ThatAIguyA world of ideas

THE CONSCIOUSNESS ATLAS
Read. Experiment. Follow the evidence.

ConsciousnessLearn · Explore · Joseph Anady

scan.html

Source identity, revision, and recovered contents.

archive memberSource text recovered

Source identity

FieldRecorded value
Source typearchive member
Original recordscan.html
DateNot specified in source
Path or archive memberarchives/libsrc-1c3f88063121/NETLIFY_AI_RECOVERY_2026-10-14_21-10-49/sites/janady13__chris-rock-lab-ai-mineral-id__b8adc02f-b334-4a9e-935d-60bbfadd3535/originals/deploy_6961ef2956ec812de977e691/scan.html
Original SHA-2563e3e1d12ac68c89c78588745400ce9dae40f8570da83f0bcb066bcc53b823cac
Reading-copy SHA-2563e3e1d12ac68c89c78588745400ce9dae40f8570da83f0bcb066bcc53b823cac
Archive source{"sourceId": "libsrc-1c3f88063121", "member": "NETLIFY_AI_RECOVERY_2026-10-14_21-10-49/sites/janady13__chris-rock-lab-ai-mineral-id__b8adc02f-b334-4a9e-935d-60bbfadd3535/originals/deploy_6961ef2956ec812de977e691/scan.html"}

Every recorded occurrence

These 2 records contain identical original source bytes. Their paths and revisions remain part of the archive.

Original recordBranch or archiveRevision / identifierOriginal location
scan.html{"sourceId": "libsrc-1c3f88063121", "member": "NETLIFY_AI_RECOVERY_2026-10-14_21-10-49/sites/janady13__chris-rock-lab-ai-mineral-id__b8adc02f-b334-4a9e-935d-60bbfadd3535/originals/deploy_6961ef2956ec812de977e691/scan.html"}libsrc-5df52d1b5e89archives/libsrc-1c3f88063121/NETLIFY_AI_RECOVERY_2026-10-14_21-10-49/sites/janady13__chris-rock-lab-ai-mineral-id__b8adc02f-b334-4a9e-935d-60bbfadd3535/originals/deploy_6961ef2956ec812de977e691/scan.html
0207845d1fa9401cdb5418ce28922d7a7f9d8c1f{"sourceId": "libsrc-1c3f88063121", "member": "NETLIFY_AI_RECOVERY_2026-10-14_21-10-49/sites/janady13__chris-rock-lab-ai-mineral-id__b8adc02f-b334-4a9e-935d-60bbfadd3535/originals/.content_store/02/0207845d1fa9401cdb5418ce28922d7a7f9d8c1f"}libsrc-4bf1aa4f7365archives/libsrc-1c3f88063121/NETLIFY_AI_RECOVERY_2026-10-14_21-10-49/sites/janady13__chris-rock-lab-ai-mineral-id__b8adc02f-b334-4a9e-935d-60bbfadd3535/originals/.content_store/02/0207845d1fa9401cdb5418ce28922d7a7f9d8c1f

Recovered source transcript

Download complete source text ↓1,193 lines · 40.1 KB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Rock Scanner | Chris's Rock Lab</title> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Cinzel:wght@400;500;600;700&family=Geologica:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet"> <style> :root { --obsidian: #0d0d0d; --slate: #1a1a1a; --granite: #2d2d2d; --sandstone: #c4a574; --amber: #ffbf00; --copper: #b87333; --quartz: #e8e4e1; --crystal: #a8d8ea; --amethyst: #9966cc; --emerald: #50c878; --ruby: #e0115f; --sapphire: #0f52ba; --gold: #ffd700; } * { margin: 0; padding: 0; box-sizing: border-box; } ::selection { background: var(--amber); color: var(--obsidian); } body { font-family: 'Geologica', sans-serif; background: var(--obsidian); color: var(--quartz); min-height: 100vh; } /* Header */ header { padding: 1.5rem 3rem; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid rgba(196, 165, 116, 0.2); background: rgba(13, 13, 13, 0.95); backdrop-filter: blur(20px); position: sticky; top: 0; z-index: 100; } .logo { display: flex; align-items: center; gap: 12px; text-decoration: none; } .logo-icon { font-size: 1.8rem; filter: drop-shadow(0 0 10px var(--amber)); } .logo-text { font-family: 'Cinzel', serif; font-size: 1.2rem; font-weight: 600; color: var(--sandstone); letter-spacing: 0.1em; } .logo-text span { color: var(--amber); } .header-nav { display: flex; gap: 1.5rem; } .header-nav a { padding: 0.7rem 1.5rem; font-size: 0.85rem; font-weight: 500; text-decoration: none; border-radius: 4px; transition: all 0.3s ease; } .nav-link { color: var(--quartz); border: 1px solid transparent; } .nav-link:hover { color: var(--amber); border-color: rgba(255, 191, 0, 0.3); } .nav-cta { background: linear-gradient(135deg, var(--amber), var(--copper)); color: var(--obsidian); } .nav-cta:hover { transform: translateY(-2px); box-shadow: 0 5px 20px rgba(255, 191, 0, 0.3); } /* Main Container */ .app-container { display: grid; grid-template-columns: 1fr 400px; min-height: calc(100vh - 80px); } /* Scanner Section */ .scanner-section { padding: 3rem; display: flex; flex-direction: column; align-items: center; justify-content: center; } .scanner-title { font-family: 'Cinzel', serif; font-size: 2rem; font-weight: 600; margin-bottom: 0.5rem; text-align: center; } .scanner-title span { color: var(--amber); } .scanner-subtitle { font-size: 0.95rem; color: rgba(232, 228, 225, 0.6); margin-bottom: 2rem; text-align: center; } /* Upload Zone */ .upload-zone { width: 100%; max-width: 500px; aspect-ratio: 4/3; border: 3px dashed rgba(196, 165, 116, 0.4); border-radius: 16px; display: flex; flex-direction: column; align-items: center; justify-content: center; background: linear-gradient(145deg, var(--slate), var(--granite)); cursor: pointer; transition: all 0.3s ease; position: relative; overflow: hidden; } .upload-zone:hover { border-color: var(--amber); background: linear-gradient(145deg, var(--granite), #3a3a3a); } .upload-zone.dragover { border-color: var(--amber); background: rgba(255, 191, 0, 0.1); } .upload-zone.has-image { border-style: solid; border-color: var(--amber); } .upload-icon { font-size: 4rem; margin-bottom: 1rem; filter: drop-shadow(0 0 20px rgba(255, 191, 0, 0.3)); } .upload-text { font-size: 1.1rem; color: var(--sandstone); margin-bottom: 0.5rem; } .upload-hint { font-size: 0.85rem; color: rgba(232, 228, 225, 0.5); } .upload-input { display: none; } .preview-image { width: 100%; height: 100%; object-fit: contain; display: none; } .upload-zone.has-image .preview-image { display: block; } .upload-zone.has-image .upload-content { display: none; } /* Scan Controls */ .scan-controls { display: flex; gap: 1rem; margin-top: 2rem; width: 100%; max-width: 500px; } .btn { flex: 1; display: flex; align-items: center; justify-content: center; gap: 10px; padding: 1rem 1.5rem; font-family: 'Geologica', sans-serif; font-weight: 600; font-size: 0.95rem; letter-spacing: 0.03em; border: none; border-radius: 8px; cursor: pointer; transition: all 0.3s ease; } .btn-primary { background: linear-gradient(135deg, var(--amber), var(--copper)); color: var(--obsidian); box-shadow: 0 4px 20px rgba(255, 191, 0, 0.3); } .btn-primary:hover:not(:disabled) { transform: translateY(-2px); box-shadow: 0 8px 30px rgba(255, 191, 0, 0.5); } .btn-primary:disabled { opacity: 0.5; cursor: not-allowed; } .btn-secondary { background: transparent; color: var(--quartz); border: 2px solid rgba(196, 165, 116, 0.4); } .btn-secondary:hover { border-color: var(--sandstone); background: rgba(196, 165, 116, 0.1); } /* Scanning Animation */ .scanning-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(13, 13, 13, 0.9); display: none; flex-direction: column; align-items: center; justify-content: center; z-index: 10; } .scanning-overlay.active { display: flex; } .scanning-animation { width: 100px; height: 100px; position: relative; margin-bottom: 1.5rem; } .scanning-ring { position: absolute; width: 100%; height: 100%; border: 3px solid transparent; border-top-color: var(--amber); border-radius: 50%; animation: scanRing 1s linear infinite; } .scanning-ring:nth-child(2) { width: 80%; height: 80%; top: 10%; left: 10%; border-top-color: var(--copper); animation-duration: 1.5s; animation-direction: reverse; } .scanning-ring:nth-child(3) { width: 60%; height: 60%; top: 20%; left: 20%; border-top-color: var(--sandstone); animation-duration: 2s; } @keyframes scanRing { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } .scanning-text { font-family: 'JetBrains Mono', monospace; font-size: 0.9rem; color: var(--amber); letter-spacing: 0.1em; } .scanning-progress { display: flex; flex-direction: column; gap: 0.5rem; margin-top: 1rem; font-size: 0.8rem; color: rgba(232, 228, 225, 0.6); } .progress-step { display: flex; align-items: center; gap: 8px; opacity: 0.4; transition: opacity 0.3s ease; } .progress-step.active { opacity: 1; color: var(--amber); } .progress-step.complete { opacity: 1; color: var(--emerald); } /* Results Panel */ .results-panel { background: linear-gradient(180deg, var(--slate), var(--obsidian)); border-left: 1px solid rgba(196, 165, 116, 0.2); padding: 2rem; overflow-y: auto; } .results-header { margin-bottom: 2rem; } .results-title { font-family: 'Cinzel', serif; font-size: 1.4rem; font-weight: 600; color: var(--sandstone); margin-bottom: 0.5rem; } .results-status { font-size: 0.85rem; color: rgba(232, 228, 225, 0.5); } /* Empty State */ .empty-state { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 400px; text-align: center; } .empty-icon { font-size: 4rem; opacity: 0.3; margin-bottom: 1rem; } .empty-text { font-size: 1rem; color: rgba(232, 228, 225, 0.4); } /* Rock Result Card */ .rock-result { display: none; animation: fadeIn 0.5s ease; } .rock-result.active { display: block; } @keyframes fadeIn { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } .result-image { width: 100%; height: 200px; object-fit: cover; border-radius: 12px; margin-bottom: 1.5rem; border: 2px solid rgba(196, 165, 116, 0.3); } .result-name { font-family: 'Cinzel', serif; font-size: 1.8rem; font-weight: 700; color: var(--amber); margin-bottom: 0.5rem; } .result-type { display: inline-block; padding: 0.4rem 1rem; font-size: 0.75rem; font-weight: 600; letter-spacing: 0.1em; background: rgba(255, 191, 0, 0.15); color: var(--amber); border-radius: 20px; margin-bottom: 1.5rem; } .confidence-bar { margin-bottom: 1.5rem; } .confidence-label { display: flex; justify-content: space-between; font-size: 0.8rem; color: rgba(232, 228, 225, 0.6); margin-bottom: 0.5rem; } .confidence-value { color: var(--emerald); font-weight: 600; } .confidence-track { width: 100%; height: 8px; background: var(--granite); border-radius: 4px; overflow: hidden; } .confidence-fill { height: 100%; background: linear-gradient(90deg, var(--emerald), var(--amber)); border-radius: 4px; transition: width 1s ease; } .result-description { font-size: 0.95rem; line-height: 1.7; color: rgba(232, 228, 225, 0.8); margin-bottom: 2rem; padding-bottom: 1.5rem; border-bottom: 1px solid rgba(196, 165, 116, 0.15); } /* Properties */ .properties-section { margin-bottom: 2rem; } .properties-title { font-family: 'JetBrains Mono', monospace; font-size: 0.75rem; color: var(--amber); letter-spacing: 0.15em; margin-bottom: 1rem; } .property-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; } .property-item { background: var(--granite); padding: 1rem; border-radius: 8px; border: 1px solid rgba(196, 165, 116, 0.1); } .property-label { font-size: 0.7rem; color: rgba(232, 228, 225, 0.5); letter-spacing: 0.1em; margin-bottom: 0.3rem; } .property-value { font-size: 0.95rem; font-weight: 600; color: var(--sandstone); } /* Value Estimate */ .value-section { background: linear-gradient(145deg, rgba(255, 191, 0, 0.1), rgba(184, 115, 51, 0.1)); padding: 1.5rem; border-radius: 12px; border: 1px solid rgba(255, 191, 0, 0.2); margin-bottom: 2rem; } .value-label { font-size: 0.75rem; color: var(--amber); letter-spacing: 0.1em; margin-bottom: 0.5rem; } .value-amount { font-family: 'Cinzel', serif; font-size: 2rem; font-weight: 700; color: var(--gold); } .value-note { font-size: 0.75rem; color: rgba(232, 228, 225, 0.5); margin-top: 0.5rem; } /* Action Buttons */ .result-actions { display: flex; flex-direction: column; gap: 0.8rem; } .action-btn { width: 100%; padding: 1rem; display: flex; align-items: center; justify-content: center; gap: 10px; font-family: 'Geologica', sans-serif; font-weight: 600; font-size: 0.9rem; border: none; border-radius: 8px; cursor: pointer; transition: all 0.3s ease; } .action-btn-save { background: linear-gradient(135deg, var(--amber), var(--copper)); color: var(--obsidian); } .action-btn-save:hover { transform: translateY(-2px); box-shadow: 0 5px 20px rgba(255, 191, 0, 0.3); } .action-btn-share { background: transparent; border: 2px solid rgba(196, 165, 116, 0.4); color: var(--quartz); } .action-btn-share:hover { border-color: var(--sandstone); background: rgba(196, 165, 116, 0.1); } /* Tips Panel */ .tips-panel { margin-top: 2rem; padding-top: 2rem; border-top: 1px solid rgba(196, 165, 116, 0.15); } .tips-title { font-family: 'JetBrains Mono', monospace; font-size: 0.75rem; color: var(--amber); letter-spacing: 0.15em; margin-bottom: 1rem; } .tip-item { display: flex; gap: 10px; margin-bottom: 0.8rem; font-size: 0.85rem; color: rgba(232, 228, 225, 0.6); } .tip-icon { color: var(--sandstone); } /* Saved Toast */ .toast { position: fixed; bottom: 2rem; left: 50%; transform: translateX(-50%) translateY(100px); background: var(--emerald); color: var(--obsidian); padding: 1rem 2rem; border-radius: 8px; font-weight: 600; display: flex; align-items: center; gap: 10px; opacity: 0; transition: all 0.3s ease; z-index: 1000; } .toast.show { transform: translateX(-50%) translateY(0); opacity: 1; } /* Responsive */ @media (max-width: 1024px) { .app-container { grid-template-columns: 1fr; } .results-panel { border-left: none; border-top: 1px solid rgba(196, 165, 116, 0.2); } } @media (max-width: 768px) { header { padding: 1rem 1.5rem; } .header-nav .nav-link { display: none; } .scanner-section { padding: 1.5rem; } .scanner-title { font-size: 1.5rem; } .upload-zone { aspect-ratio: 1; } .scan-controls { flex-direction: column; } .property-grid { grid-template-columns: 1fr; } } </style> </head> <body> <!-- Header --> <header> <a href="index.html" class="logo"> <span class="logo-icon">🪨</span> <span class="logo-text">CHRIS'S <span>ROCK LAB</span></span> </a> <nav class="header-nav"> <a href="index.html" class="nav-link">Home</a> <a href="collection.html" class="nav-cta">My Collection</a> </nav> </header> <!-- Main App --> <main class="app-container"> <!-- Scanner Section --> <section class="scanner-section"> <h1 class="scanner-title">Scan Your <span>Rock</span></h1> <p class="scanner-subtitle">Upload a photo to identify your specimen</p> <div class="upload-zone" id="uploadZone"> <div class="upload-content"> <div class="upload-icon">📷</div> <div class="upload-text">Drop your rock photo here</div> <div class="upload-hint">or click to browse files</div> </div> <img class="preview-image" id="previewImage" alt="Rock preview"> <input type="file" class="upload-input" id="fileInput" accept="image/*"> <!-- Scanning Overlay --> <div class="scanning-overlay" id="scanningOverlay"> <div class="scanning-animation"> <div class="scanning-ring"></div> <div class="scanning-ring"></div> <div class="scanning-ring"></div> </div> <div class="scanning-text">ANALYZING SPECIMEN</div> <div class="scanning-progress"> <div class="progress-step" id="step1">◆ Detecting color patterns</div> <div class="progress-step" id="step2">◆ Analyzing texture</div> <div class="progress-step" id="step3">◆ Identifying crystal structure</div> <div class="progress-step" id="step4">◆ Matching database</div> </div> </div> </div> <div class="scan-controls"> <button class="btn btn-secondary" id="cameraBtn">📱 Use Camera</button> <button class="btn btn-primary" id="scanBtn" disabled>🔬 Identify Rock</button> </div> </section> <!-- Results Panel --> <aside class="results-panel"> <div class="results-header"> <h2 class="results-title">Identification Results</h2> <p class="results-status" id="resultsStatus">Upload a rock to get started</p> </div> <!-- Empty State --> <div class="empty-state" id="emptyState"> <div class="empty-icon">🔍</div> <div class="empty-text">Your rock analysis will appear here</div> </div> <!-- Rock Result --> <div class="rock-result" id="rockResult"> <img class="result-image" id="resultImage" alt="Identified rock"> <h3 class="result-name" id="resultName">Loading...</h3> <span class="result-type" id="resultType">TYPE</span> <div class="confidence-bar"> <div class="confidence-label"> <span>Confidence</span> <span class="confidence-value" id="confidenceValue">0%</span> </div> <div class="confidence-track"> <div class="confidence-fill" id="confidenceFill" style="width: 0%"></div> </div> </div> <p class="result-description" id="resultDescription"></p> <div class="properties-section"> <h4 class="properties-title">// PROPERTIES</h4> <div class="property-grid"> <div class="property-item"> <div class="property-label">HARDNESS</div> <div class="property-value" id="propHardness">-</div> </div> <div class="property-item"> <div class="property-label">COMPOSITION</div> <div class="property-value" id="propComposition">-</div> </div> <div class="property-item"> <div class="property-label">CRYSTAL SYSTEM</div> <div class="property-value" id="propCrystal">-</div> </div> <div class="property-item"> <div class="property-label">LUSTER</div> <div class="property-value" id="propLuster">-</div> </div> <div class="property-item"> <div class="property-label">SPECIFIC GRAVITY</div> <div class="property-value" id="propGravity">-</div> </div> <div class="property-item"> <div class="property-label">COMMON LOCATION</div> <div class="property-value" id="propLocation">-</div> </div> </div> </div> <div class="value-section"> <div class="value-label">💰 ESTIMATED VALUE</div> <div class="value-amount" id="resultValue">$0</div> <div class="value-note">Based on size, quality, and market conditions</div> </div> <div class="result-actions"> <button class="action-btn action-btn-save" id="saveBtn">💾 Save to Collection</button> <button class="action-btn action-btn-share" id="shareBtn">📤 Share Result</button> </div> </div> <!-- Tips --> <div class="tips-panel"> <h4 class="tips-title">// PHOTO TIPS</h4> <div class="tip-item"> <span class="tip-icon">💡</span> <span>Use natural daylight for best results</span> </div> <div class="tip-item"> <span class="tip-icon">📐</span> <span>Capture multiple angles if unsure</span> </div> <div class="tip-item"> <span class="tip-icon">🎯</span> <span>Focus on unique features and textures</span> </div> <div class="tip-item"> <span class="tip-icon">📏</span> <span>Include a coin for scale reference</span> </div> </div> </aside> </main> <!-- Toast Notification --> <div class="toast" id="toast">✅ Saved to collection!</div> <script> // Rock Database const ROCK_DATABASE = { granite: { name: "Granite", type: "IGNEOUS ROCK", description: "Granite is a coarse-grained igneous rock composed mainly of quartz, feldspar, and mica. It forms from the slow crystallization of magma deep beneath the Earth's surface. Granite is one of the most common rocks in the Earth's continental crust and is widely used in construction and monuments.", hardness: "6-7 Mohs", composition: "Quartz, Feldspar, Mica", crystal: "N/A (Aggregate)", luster: "Vitreous to Pearly", gravity: "2.65-2.75", location: "Worldwide", value: "$50-200" }, quartz: { name: "Quartz", type: "MINERAL", description: "Quartz is one of the most abundant minerals on Earth, composed of silicon and oxygen atoms. It comes in many varieties including clear (rock crystal), purple (amethyst), pink (rose quartz), and smoky. Quartz has piezoelectric properties and is used in electronics and jewelry.", hardness: "7 Mohs", composition: "SiO₂ (Silicon Dioxide)", crystal: "Hexagonal", luster: "Vitreous", gravity: "2.65", location: "Worldwide", value: "$5-500" }, amethyst: { name: "Amethyst", type: "CRYSTAL", description: "Amethyst is a purple variety of quartz, colored by iron impurities and irradiation. It has been prized as a gemstone since ancient times and was once considered as valuable as diamonds. The purple color ranges from light lilac to deep violet.", hardness: "7 Mohs", composition: "SiO₂ with Fe impurities", crystal: "Hexagonal", luster: "Vitreous", gravity: "2.65", location: "Brazil, Uruguay, Zambia", value: "$20-1000+" }, obsidian: { name: "Obsidian", type: "IGNEOUS ROCK", description: "Obsidian is a naturally occurring volcanic glass formed when lava cools rapidly with minimal crystal growth. It's typically jet-black in color but can also be brown, green, or have a rainbow sheen. Ancient peoples used obsidian to make sharp cutting tools.", hardness: "5-5.5 Mohs", composition: "Volcanic Glass (SiO₂ rich)", crystal: "Amorphous", luster: "Vitreous", gravity: "2.35-2.60", location: "Mexico, USA, Japan", value: "$10-100" }, pyrite: { name: "Pyrite", type: "MINERAL", description: "Pyrite, known as 'Fool's Gold' due to its metallic yellow color, is an iron sulfide mineral. It's the most common sulfide mineral and often forms perfect cubic crystals. Despite its nickname, pyrite has been used in jewelry and as a source of sulfur.", hardness: "6-6.5 Mohs", composition: "FeS₂ (Iron Sulfide)", crystal: "Cubic", luster: "Metallic", gravity: "5.0", location: "Spain, Peru, USA", value: "$15-200" }, marble: { name: "Marble", type: "METAMORPHIC ROCK", description: "Marble is a metamorphic rock that forms when limestone is subjected to heat and pressure. It's composed mainly of recrystallized calcite and is famous for its use in sculpture and architecture throughout history, from ancient Greece to modern buildings.", hardness: "3-4 Mohs", composition: "CaCO₃ (Calcite)", crystal: "N/A (Recrystallized)", luster: "Waxy to Pearly", gravity: "2.7", location: "Italy, Greece, Turkey", value: "$30-500" }, limestone: { name: "Limestone", type: "SEDIMENTARY ROCK", description: "Limestone is a sedimentary rock composed primarily of calcium carbonate, often containing fossils of marine organisms. It forms in warm, shallow marine environments and is a major building material. Many famous structures, including the Egyptian pyramids, are made of limestone.", hardness: "3-4 Mohs", composition: "CaCO₃ (Calcium Carbonate)", crystal: "N/A (Sedimentary)", luster: "Earthy to Dull", gravity: "2.5-2.7", location: "Worldwide", value: "$20-100" }, malachite: { name: "Malachite", type: "MINERAL", description: "Malachite is a copper carbonate mineral with distinctive green banded patterns. It forms in copper deposits and has been used as a gemstone and ornamental stone for thousands of years. The unique concentric banding makes each piece one-of-a-kind.", hardness: "3.5-4 Mohs", composition: "Cu₂CO₃(OH)₂", crystal: "Monoclinic", luster: "Silky to Adamantine", gravity: "3.6-4.0", location: "Congo, Russia, Australia", value: "$25-500+" }, sandstone: { name: "Sandstone", type: "SEDIMENTARY ROCK", description: "Sandstone is a clastic sedimentary rock composed mainly of sand-sized mineral or rock grains cemented together. It forms from the accumulation and lithification of sand in environments like beaches, deserts, and river beds. Colors range from white to red to brown.", hardness: "6-7 Mohs", composition: "Quartz, Feldspar grains", crystal: "N/A (Clastic)", luster: "Dull to Earthy", gravity: "2.2-2.8", location: "Worldwide", value: "$10-80" }, basalt: { name: "Basalt", type: "IGNEOUS ROCK", description: "Basalt is a fine-grained volcanic rock formed from the rapid cooling of lava at the Earth's surface. It's the most common rock type in the Earth's oceanic crust and makes up most of the sea floor. Basalt is typically dark gray to black in color.", hardness: "6 Mohs", composition: "Pyroxene, Plagioclase", crystal: "Fine-grained", luster: "Dull to Glassy", gravity: "2.8-3.0", location: "Hawaii, Iceland, India", value: "$15-60" }, agate: { name: "Agate", type: "MINERAL", description: "Agate is a variety of chalcedony (cryptocrystalline quartz) characterized by its colorful, banded patterns. It forms in volcanic and metamorphic rocks and comes in a wide variety of colors and patterns. Agate has been prized for jewelry and decorative objects since ancient times.", hardness: "6.5-7 Mohs", composition: "SiO₂ (Chalcedony)", crystal: "Cryptocrystalline", luster: "Waxy to Vitreous", gravity: "2.58-2.64", location: "Brazil, USA, Madagascar", value: "$20-300" }, turquoise: { name: "Turquoise", type: "MINERAL", description: "Turquoise is a blue-to-green mineral that has been prized as a gemstone for millennia. It forms in arid regions where copper-rich groundwater reacts with aluminum and phosphorus. The most valued turquoise has a pure blue color without any green.", hardness: "5-6 Mohs", composition: "CuAl₆(PO₄)₄(OH)₈·4H₂O", crystal: "Triclinic", luster: "Waxy to Subvitreous", gravity: "2.6-2.8", location: "Iran, USA, Egypt", value: "$50-1000+" } }; // DOM Elements const uploadZone = document.getElementById('uploadZone'); const fileInput = document.getElementById('fileInput'); const previewImage = document.getElementById('previewImage'); const scanBtn = document.getElementById('scanBtn'); const cameraBtn = document.getElementById('cameraBtn'); const scanningOverlay = document.getElementById('scanningOverlay'); const emptyState = document.getElementById('emptyState'); const rockResult = document.getElementById('rockResult'); const resultsStatus = document.getElementById('resultsStatus'); const toast = document.getElementById('toast'); let currentImage = null; let currentResult = null; // Event Listeners uploadZone.addEventListener('click', () => fileInput.click()); uploadZone.addEventListener('dragover', (e) => { e.preventDefault(); uploadZone.classList.add('dragover'); }); uploadZone.addEventListener('dragleave', () => { uploadZone.classList.remove('dragover'); }); uploadZone.addEventListener('drop', (e) => { e.preventDefault(); uploadZone.classList.remove('dragover'); const file = e.dataTransfer.files[0]; if (file && file.type.startsWith('image/')) { handleFile(file); } }); fileInput.addEventListener('change', (e) => { const file = e.target.files[0]; if (file) { handleFile(file); } }); cameraBtn.addEventListener('click', () => { fileInput.setAttribute('capture', 'environment'); fileInput.click(); setTimeout(() => fileInput.removeAttribute('capture'), 100); }); scanBtn.addEventListener('click', startScan); document.getElementById('saveBtn').addEventListener('click', saveToCollection); document.getElementById('shareBtn').addEventListener('click', shareResult); // Handle File Upload function handleFile(file) { const reader = new FileReader(); reader.onload = (e) => { currentImage = e.target.result; previewImage.src = currentImage; uploadZone.classList.add('has-image'); scanBtn.disabled = false; resultsStatus.textContent = 'Ready to scan'; }; reader.readAsDataURL(file); } // Start Scanning async function startScan() { if (!currentImage) return; scanningOverlay.classList.add('active'); scanBtn.disabled = true; resultsStatus.textContent = 'Analyzing specimen...'; const steps = ['step1', 'step2', 'step3', 'step4']; for (let i = 0; i < steps.length; i++) { await delay(800); document.getElementById(steps[i]).classList.add('active'); if (i > 0) { document.getElementById(steps[i-1]).classList.remove('active'); document.getElementById(steps[i-1]).classList.add('complete'); } } await delay(600); document.getElementById('step4').classList.remove('active'); document.getElementById('step4').classList.add('complete'); // Simulate AI identification (randomly select a rock) const rockKeys = Object.keys(ROCK_DATABASE); const randomKey = rockKeys[Math.floor(Math.random() * rockKeys.length)]; currentResult = ROCK_DATABASE[randomKey]; // Add some variation to confidence const confidence = 85 + Math.floor(Math.random() * 13); await delay(400); displayResult(currentResult, confidence); scanningOverlay.classList.remove('active'); steps.forEach(s => { document.getElementById(s).classList.remove('active', 'complete'); }); scanBtn.disabled = false; resultsStatus.textContent = 'Identification complete'; } // Display Result function displayResult(rock, confidence) { emptyState.style.display = 'none'; rockResult.classList.add('active'); document.getElementById('resultImage').src = currentImage; document.getElementById('resultName').textContent = rock.name; document.getElementById('resultType').textContent = rock.type; document.getElementById('resultDescription').textContent = rock.description; document.getElementById('confidenceValue').textContent = confidence + '%'; document.getElementById('confidenceFill').style.width = confidence + '%'; document.getElementById('propHardness').textContent = rock.hardness; document.getElementById('propComposition').textContent = rock.composition; document.getElementById('propCrystal').textContent = rock.crystal; document.getElementById('propLuster').textContent = rock.luster; document.getElementById('propGravity').textContent = rock.gravity; document.getElementById('propLocation').textContent = rock.location; document.getElementById('resultValue').textContent = rock.value; } // Save to Collection function saveToCollection() { if (!currentResult) return; const collection = JSON.parse(localStorage.getItem('rockCollection') || '[]'); const newRock = { id: Date.now(), name: currentResult.name, type: currentResult.type, image: currentImage, date: new Date().toISOString(), properties: { hardness: currentResult.hardness, composition: currentResult.composition, value: currentResult.value } }; collection.push(newRock); localStorage.setItem('rockCollection', JSON.stringify(collection)); showToast('Saved to collection!'); } // Share Result function shareResult() { if (!currentResult) return; const shareText = `🪨 I just identified a ${currentResult.name}!\n\nType: ${currentResult.type}\nHardness: ${currentResult.hardness}\nValue: ${currentResult.value}\n\nIdentified with Chris's Rock Lab`; if (navigator.share) { navigator.share({ title: `Rock Identification: ${currentResult.name}`, text: shareText }); } else { navigator.clipboard.writeText(shareText); showToast('Copied to clipboard!'); } } // Show Toast function showToast(message) { toast.textContent = '✅ ' + message; toast.classList.add('show'); setTimeout(() => toast.classList.remove('show'), 3000); } // Utility function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } </script> </body> </html>

Search equations, builds, manuscript text, and recovered sources.