ThatAIguyA world of ideas

THE CONSCIOUSNESS ATLAS
Read. Experiment. Follow the evidence.

ConsciousnessLearn · Explore · Joseph Anady

collection.html

Source identity, revision, and recovered contents.

archive memberSource text recovered

Source identity

FieldRecorded value
Source typearchive member
Original recordcollection.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/collection.html
Original SHA-256a8ef613087a88bd7005d9152e6e35f11861ef23e3d6f060ad649dc57bac3c4b3
Reading-copy SHA-256a8ef613087a88bd7005d9152e6e35f11861ef23e3d6f060ad649dc57bac3c4b3
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/collection.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
collection.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/collection.html"}libsrc-258e18d916ccarchives/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/collection.html
07a8d117679f056d4dde51f676a5847e163af2ad{"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/07/07a8d117679f056d4dde51f676a5847e163af2ad"}libsrc-c420035a1ce2archives/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/07/07a8d117679f056d4dde51f676a5847e163af2ad

Recovered source transcript

Download complete source text ↓1,057 lines · 33.8 KB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>My Collection | 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; --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 */ main { max-width: 1400px; margin: 0 auto; padding: 3rem; } /* Page Header */ .page-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 3rem; } .page-title-section h1 { font-family: 'Cinzel', serif; font-size: 2.5rem; font-weight: 600; margin-bottom: 0.5rem; } .page-title-section h1 span { color: var(--amber); } .page-subtitle { font-size: 1rem; color: rgba(232, 228, 225, 0.6); } /* Stats Bar */ .stats-bar { display: flex; gap: 2rem; background: linear-gradient(145deg, var(--slate), var(--granite)); padding: 1.5rem 2rem; border-radius: 12px; border: 1px solid rgba(196, 165, 116, 0.15); } .stat { text-align: center; } .stat-value { font-family: 'Cinzel', serif; font-size: 2rem; font-weight: 700; color: var(--amber); } .stat-label { font-size: 0.75rem; color: rgba(232, 228, 225, 0.5); letter-spacing: 0.1em; } /* Controls */ .controls { display: flex; gap: 1rem; margin-bottom: 2rem; flex-wrap: wrap; } .search-box { flex: 1; min-width: 200px; padding: 0.9rem 1.2rem; background: var(--granite); border: 1px solid rgba(196, 165, 116, 0.2); border-radius: 8px; color: var(--quartz); font-family: 'Geologica', sans-serif; font-size: 0.9rem; transition: all 0.3s ease; } .search-box::placeholder { color: rgba(232, 228, 225, 0.4); } .search-box:focus { outline: none; border-color: var(--amber); box-shadow: 0 0 0 3px rgba(255, 191, 0, 0.1); } .filter-btn { padding: 0.9rem 1.5rem; background: var(--granite); border: 1px solid rgba(196, 165, 116, 0.2); border-radius: 8px; color: var(--quartz); font-family: 'Geologica', sans-serif; font-size: 0.85rem; cursor: pointer; transition: all 0.3s ease; } .filter-btn:hover { border-color: var(--sandstone); background: rgba(196, 165, 116, 0.1); } .filter-btn.active { background: var(--amber); color: var(--obsidian); border-color: var(--amber); } .view-toggle { display: flex; background: var(--granite); border-radius: 8px; overflow: hidden; border: 1px solid rgba(196, 165, 116, 0.2); } .view-btn { padding: 0.9rem 1.2rem; background: transparent; border: none; color: var(--quartz); cursor: pointer; font-size: 1.1rem; transition: all 0.3s ease; } .view-btn:hover { background: rgba(196, 165, 116, 0.1); } .view-btn.active { background: var(--amber); color: var(--obsidian); } /* Empty State */ .empty-state { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 6rem 2rem; text-align: center; } .empty-icon { font-size: 5rem; opacity: 0.3; margin-bottom: 1.5rem; } .empty-title { font-family: 'Cinzel', serif; font-size: 1.5rem; color: var(--sandstone); margin-bottom: 0.5rem; } .empty-text { font-size: 1rem; color: rgba(232, 228, 225, 0.5); margin-bottom: 2rem; } .empty-btn { display: inline-flex; align-items: center; gap: 10px; padding: 1rem 2rem; background: linear-gradient(135deg, var(--amber), var(--copper)); color: var(--obsidian); font-family: 'Geologica', sans-serif; font-weight: 600; font-size: 0.95rem; text-decoration: none; border-radius: 8px; transition: all 0.3s ease; } .empty-btn:hover { transform: translateY(-3px); box-shadow: 0 8px 30px rgba(255, 191, 0, 0.4); } /* Collection Grid */ .collection-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 1.5rem; } .collection-grid.list-view { grid-template-columns: 1fr; } /* Rock Card */ .rock-card { background: linear-gradient(145deg, var(--slate), var(--granite)); border-radius: 12px; overflow: hidden; border: 1px solid rgba(196, 165, 116, 0.15); transition: all 0.3s ease; position: relative; } .rock-card:hover { transform: translateY(-5px); border-color: var(--amber); box-shadow: 0 15px 40px rgba(0, 0, 0, 0.4); } .rock-card-image { width: 100%; height: 200px; object-fit: cover; border-bottom: 1px solid rgba(196, 165, 116, 0.1); } .rock-card-content { padding: 1.5rem; } .rock-card-type { display: inline-block; padding: 0.3rem 0.8rem; font-size: 0.65rem; font-weight: 600; letter-spacing: 0.1em; background: rgba(255, 191, 0, 0.15); color: var(--amber); border-radius: 20px; margin-bottom: 0.8rem; } .rock-card-name { font-family: 'Cinzel', serif; font-size: 1.3rem; font-weight: 600; color: var(--sandstone); margin-bottom: 0.5rem; } .rock-card-date { font-size: 0.8rem; color: rgba(232, 228, 225, 0.5); margin-bottom: 1rem; } .rock-card-props { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 1rem; } .rock-prop { padding: 0.4rem 0.8rem; background: var(--obsidian); border-radius: 4px; font-size: 0.75rem; color: rgba(232, 228, 225, 0.7); } .rock-card-value { font-family: 'Cinzel', serif; font-size: 1.2rem; font-weight: 600; color: var(--gold); } .rock-card-actions { position: absolute; top: 1rem; right: 1rem; display: flex; gap: 0.5rem; opacity: 0; transition: opacity 0.3s ease; } .rock-card:hover .rock-card-actions { opacity: 1; } .card-action-btn { width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; background: rgba(13, 13, 13, 0.8); border: none; border-radius: 50%; color: var(--quartz); cursor: pointer; transition: all 0.3s ease; } .card-action-btn:hover { background: var(--ruby); color: white; } /* List View Styles */ .collection-grid.list-view .rock-card { display: grid; grid-template-columns: 150px 1fr; } .collection-grid.list-view .rock-card-image { height: 100%; min-height: 120px; } .collection-grid.list-view .rock-card-content { display: flex; align-items: center; gap: 2rem; } .collection-grid.list-view .rock-card-info { flex: 1; } .collection-grid.list-view .rock-card-props { margin-bottom: 0; } /* Modal */ .modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.9); display: none; align-items: center; justify-content: center; z-index: 1000; padding: 2rem; } .modal-overlay.active { display: flex; } .modal { background: var(--slate); border-radius: 16px; max-width: 700px; width: 100%; max-height: 90vh; overflow-y: auto; border: 1px solid rgba(196, 165, 116, 0.2); position: relative; } .modal-close { position: absolute; top: 1rem; right: 1rem; width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; background: var(--granite); border: none; border-radius: 50%; color: var(--quartz); cursor: pointer; font-size: 1.2rem; transition: all 0.3s ease; z-index: 10; } .modal-close:hover { background: var(--ruby); } .modal-image { width: 100%; height: 300px; object-fit: cover; } .modal-content { padding: 2rem; } .modal-type { display: inline-block; padding: 0.4rem 1rem; font-size: 0.7rem; font-weight: 600; letter-spacing: 0.1em; background: rgba(255, 191, 0, 0.15); color: var(--amber); border-radius: 20px; margin-bottom: 1rem; } .modal-name { font-family: 'Cinzel', serif; font-size: 2rem; font-weight: 600; color: var(--amber); margin-bottom: 1rem; } .modal-date { font-size: 0.85rem; color: rgba(232, 228, 225, 0.5); margin-bottom: 1.5rem; } .modal-props { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1rem; margin-bottom: 2rem; } .modal-prop { background: var(--granite); padding: 1rem; border-radius: 8px; } .modal-prop-label { font-size: 0.7rem; color: rgba(232, 228, 225, 0.5); letter-spacing: 0.1em; margin-bottom: 0.3rem; } .modal-prop-value { font-size: 1rem; font-weight: 600; color: var(--sandstone); } .modal-value { 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); text-align: center; margin-bottom: 1.5rem; } .modal-value-label { font-size: 0.75rem; color: var(--amber); letter-spacing: 0.1em; margin-bottom: 0.5rem; } .modal-value-amount { font-family: 'Cinzel', serif; font-size: 2.5rem; font-weight: 700; color: var(--gold); } .modal-actions { display: flex; gap: 1rem; } .modal-btn { flex: 1; padding: 1rem; display: flex; align-items: center; justify-content: center; gap: 8px; font-family: 'Geologica', sans-serif; font-weight: 600; font-size: 0.9rem; border: none; border-radius: 8px; cursor: pointer; transition: all 0.3s ease; } .modal-btn-delete { background: transparent; border: 2px solid var(--ruby); color: var(--ruby); } .modal-btn-delete:hover { background: var(--ruby); color: white; } .modal-btn-edit { background: linear-gradient(135deg, var(--amber), var(--copper)); color: var(--obsidian); } .modal-btn-edit:hover { transform: translateY(-2px); box-shadow: 0 5px 20px rgba(255, 191, 0, 0.3); } /* 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: 1001; } .toast.show { transform: translateX(-50%) translateY(0); opacity: 1; } .toast.error { background: var(--ruby); color: white; } /* Responsive */ @media (max-width: 768px) { header { padding: 1rem 1.5rem; } .header-nav .nav-link { display: none; } main { padding: 1.5rem; } .page-header { flex-direction: column; gap: 1.5rem; } .stats-bar { width: 100%; justify-content: space-around; } .page-title-section h1 { font-size: 1.8rem; } .collection-grid { grid-template-columns: 1fr; } .collection-grid.list-view .rock-card { grid-template-columns: 100px 1fr; } .modal-props { 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="scan.html" class="nav-cta">📷 Scan Rock</a> </nav> </header> <!-- Main Content --> <main> <!-- Page Header --> <div class="page-header"> <div class="page-title-section"> <h1>My <span>Collection</span></h1> <p class="page-subtitle">Your personal rock & mineral museum</p> </div> <div class="stats-bar"> <div class="stat"> <div class="stat-value" id="totalCount">0</div> <div class="stat-label">SPECIMENS</div> </div> <div class="stat"> <div class="stat-value" id="totalValue">$0</div> <div class="stat-label">EST. VALUE</div> </div> </div> </div> <!-- Controls --> <div class="controls"> <input type="text" class="search-box" id="searchBox" placeholder="🔍 Search your collection..."> <button class="filter-btn active" data-filter="all">All</button> <button class="filter-btn" data-filter="igneous">Igneous</button> <button class="filter-btn" data-filter="sedimentary">Sedimentary</button> <button class="filter-btn" data-filter="metamorphic">Metamorphic</button> <button class="filter-btn" data-filter="mineral">Mineral</button> <button class="filter-btn" data-filter="crystal">Crystal</button> <div class="view-toggle"> <button class="view-btn active" data-view="grid">⊞</button> <button class="view-btn" data-view="list">☰</button> </div> </div> <!-- Empty State --> <div class="empty-state" id="emptyState"> <div class="empty-icon">📦</div> <h2 class="empty-title">No Rocks Yet</h2> <p class="empty-text">Start building your collection by scanning your first rock!</p> <a href="scan.html" class="empty-btn">📷 Scan Your First Rock</a> </div> <!-- Collection Grid --> <div class="collection-grid" id="collectionGrid"></div> </main> <!-- Rock Detail Modal --> <div class="modal-overlay" id="modalOverlay"> <div class="modal"> <button class="modal-close" id="modalClose">✕</button> <img class="modal-image" id="modalImage" alt="Rock specimen"> <div class="modal-content"> <span class="modal-type" id="modalType">TYPE</span> <h2 class="modal-name" id="modalName">Rock Name</h2> <p class="modal-date" id="modalDate">Added on --</p> <div class="modal-props"> <div class="modal-prop"> <div class="modal-prop-label">HARDNESS</div> <div class="modal-prop-value" id="modalHardness">-</div> </div> <div class="modal-prop"> <div class="modal-prop-label">COMPOSITION</div> <div class="modal-prop-value" id="modalComposition">-</div> </div> </div> <div class="modal-value"> <div class="modal-value-label">💰 ESTIMATED VALUE</div> <div class="modal-value-amount" id="modalValue">$0</div> </div> <div class="modal-actions"> <button class="modal-btn modal-btn-delete" id="deleteBtn">🗑️ Remove</button> <button class="modal-btn modal-btn-edit" onclick="document.getElementById('modalOverlay').classList.remove('active')">✓ Done</button> </div> </div> </div> </div> <!-- Toast --> <div class="toast" id="toast">Notification</div> <script> // State let collection = []; let currentFilter = 'all'; let currentView = 'grid'; let selectedRockId = null; // DOM Elements const collectionGrid = document.getElementById('collectionGrid'); const emptyState = document.getElementById('emptyState'); const searchBox = document.getElementById('searchBox'); const modalOverlay = document.getElementById('modalOverlay'); const toast = document.getElementById('toast'); // Initialize document.addEventListener('DOMContentLoaded', () => { loadCollection(); setupEventListeners(); }); // Load collection from localStorage function loadCollection() { const stored = localStorage.getItem('rockCollection'); collection = stored ? JSON.parse(stored) : []; // Add sample rocks if collection is empty (for demo) if (collection.length === 0) { addSampleRocks(); } renderCollection(); updateStats(); } // Add sample rocks for demo function addSampleRocks() { const sampleRocks = [ { id: 1, name: 'Amethyst Cluster', type: 'CRYSTAL', image: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAwIiBoZWlnaHQ9IjMwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZGVmcz48bGluZWFyR3JhZGllbnQgaWQ9ImciIHgxPSIwJSIgeTE9IjAlIiB4Mj0iMTAwJSIgeTI9IjEwMCUiPjxzdG9wIG9mZnNldD0iMCUiIHN0b3AtY29sb3I9IiM5OTY2Y2MiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiM2NjMzOTkiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2cpIi8+PHRleHQgeD0iNTAlIiB5PSI1MCUiIGRvbWluYW50LWJhc2VsaW5lPSJtaWRkbGUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZpbGw9IndoaXRlIiBmb250LXNpemU9IjQ4Ij7wn5OEPC90ZXh0Pjwvc3ZnPg==', date: new Date(Date.now() - 86400000 * 5).toISOString(), properties: { hardness: '7 Mohs', composition: 'SiO₂ with Fe', value: '$150-400' } }, { id: 2, name: 'Pyrite Cube', type: 'MINERAL', image: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAwIiBoZWlnaHQ9IjMwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZGVmcz48bGluZWFyR3JhZGllbnQgaWQ9ImciIHgxPSIwJSIgeTE9IjAlIiB4Mj0iMTAwJSIgeTI9IjEwMCUiPjxzdG9wIG9mZnNldD0iMCUiIHN0b3AtY29sb3I9IiNmZmQ3MDAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNiODg2MGIiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2cpIi8+PHRleHQgeD0iNTAlIiB5PSI1MCUiIGRvbWluYW50LWJhc2VsaW5lPSJtaWRkbGUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZpbGw9IndoaXRlIiBmb250LXNpemU9IjQ4Ij7inKg8L3RleHQ+PC9zdmc+', date: new Date(Date.now() - 86400000 * 12).toISOString(), properties: { hardness: '6-6.5 Mohs', composition: 'FeS₂', value: '$25-80' } }, { id: 3, name: 'River Granite', type: 'IGNEOUS ROCK', image: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAwIiBoZWlnaHQ9IjMwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZGVmcz48bGluZWFyR3JhZGllbnQgaWQ9ImciIHgxPSIwJSIgeTE9IjAlIiB4Mj0iMTAwJSIgeTI9IjEwMCUiPjxzdG9wIG9mZnNldD0iMCUiIHN0b3AtY29sb3I9IiM2NjY2NjYiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMzMzMzMzMiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2cpIi8+PHRleHQgeD0iNTAlIiB5PSI1MCUiIGRvbWluYW50LWJhc2VsaW5lPSJtaWRkbGUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZpbGw9IndoaXRlIiBmb250LXNpemU9IjQ4Ij7wn6qdPC90ZXh0Pjwvc3ZnPg==', date: new Date(Date.now() - 86400000 * 20).toISOString(), properties: { hardness: '6-7 Mohs', composition: 'Quartz, Feldspar', value: '$15-50' } }, { id: 4, name: 'Malachite Slab', type: 'MINERAL', image: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAwIiBoZWlnaHQ9IjMwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZGVmcz48bGluZWFyR3JhZGllbnQgaWQ9ImciIHgxPSIwJSIgeTE9IjAlIiB4Mj0iMTAwJSIgeTI9IjEwMCUiPjxzdG9wIG9mZnNldD0iMCUiIHN0b3AtY29sb3I9IiM1MGM4NzgiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMyZThhNTciLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2cpIi8+PHRleHQgeD0iNTAlIiB5PSI1MCUiIGRvbWluYW50LWJhc2VsaW5lPSJtaWRkbGUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZpbGw9IndoaXRlIiBmb250LXNpemU9IjQ4Ij7wn5KaPC90ZXh0Pjwvc3ZnPg==', date: new Date(Date.now() - 86400000 * 30).toISOString(), properties: { hardness: '3.5-4 Mohs', composition: 'Cu₂CO₃(OH)₂', value: '$75-250' } } ]; collection = sampleRocks; localStorage.setItem('rockCollection', JSON.stringify(collection)); } // Setup event listeners function setupEventListeners() { // Search searchBox.addEventListener('input', (e) => { renderCollection(e.target.value); }); // Filter buttons document.querySelectorAll('.filter-btn').forEach(btn => { btn.addEventListener('click', () => { document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active')); btn.classList.add('active'); currentFilter = btn.dataset.filter; renderCollection(); }); }); // View toggle document.querySelectorAll('.view-btn').forEach(btn => { btn.addEventListener('click', () => { document.querySelectorAll('.view-btn').forEach(b => b.classList.remove('active')); btn.classList.add('active'); currentView = btn.dataset.view; collectionGrid.classList.toggle('list-view', currentView === 'list'); }); }); // Modal close document.getElementById('modalClose').addEventListener('click', () => { modalOverlay.classList.remove('active'); }); modalOverlay.addEventListener('click', (e) => { if (e.target === modalOverlay) { modalOverlay.classList.remove('active'); } }); // Delete button document.getElementById('deleteBtn').addEventListener('click', () => { if (selectedRockId) { deleteRock(selectedRockId); } }); } // Render collection function renderCollection(searchTerm = '') { let filtered = collection; // Apply filter if (currentFilter !== 'all') { filtered = filtered.filter(rock => rock.type.toLowerCase().includes(currentFilter.toLowerCase()) ); } // Apply search if (searchTerm) { filtered = filtered.filter(rock => rock.name.toLowerCase().includes(searchTerm.toLowerCase()) || rock.type.toLowerCase().includes(searchTerm.toLowerCase()) ); } // Show empty state or grid if (filtered.length === 0 && collection.length === 0) { emptyState.style.display = 'flex'; collectionGrid.style.display = 'none'; } else { emptyState.style.display = 'none'; collectionGrid.style.display = 'grid'; } // Render cards collectionGrid.innerHTML = filtered.map(rock => ` <div class="rock-card" onclick="openRockModal(${rock.id})"> <div class="rock-card-actions"> <button class="card-action-btn" onclick="event.stopPropagation(); deleteRock(${rock.id})">🗑️</button> </div> <img class="rock-card-image" src="${rock.image}" alt="${rock.name}"> <div class="rock-card-content"> <div class="rock-card-info"> <span class="rock-card-type">${rock.type}</span> <h3 class="rock-card-name">${rock.name}</h3> <p class="rock-card-date">Added ${formatDate(rock.date)}</p> <div class="rock-card-props"> <span class="rock-prop">${rock.properties.hardness}</span> </div> </div> <div class="rock-card-value">${rock.properties.value}</div> </div> </div> `).join(''); } // Update stats function updateStats() { document.getElementById('totalCount').textContent = collection.length; // Calculate total value (rough estimate from ranges) let totalMin = 0; let totalMax = 0; collection.forEach(rock => { const valueStr = rock.properties.value; const matches = valueStr.match(/\$(\d+)(?:-(\d+))?/); if (matches) { totalMin += parseInt(matches[1]); totalMax += parseInt(matches[2] || matches[1]); } }); const avgValue = Math.round((totalMin + totalMax) / 2); document.getElementById('totalValue').textContent = '$' + avgValue.toLocaleString(); } // Open rock modal function openRockModal(id) { const rock = collection.find(r => r.id === id); if (!rock) return; selectedRockId = id; document.getElementById('modalImage').src = rock.image; document.getElementById('modalType').textContent = rock.type; document.getElementById('modalName').textContent = rock.name; document.getElementById('modalDate').textContent = 'Added ' + formatDate(rock.date); document.getElementById('modalHardness').textContent = rock.properties.hardness; document.getElementById('modalComposition').textContent = rock.properties.composition; document.getElementById('modalValue').textContent = rock.properties.value; modalOverlay.classList.add('active'); } // Delete rock function deleteRock(id) { collection = collection.filter(r => r.id !== id); localStorage.setItem('rockCollection', JSON.stringify(collection)); renderCollection(); updateStats(); modalOverlay.classList.remove('active'); showToast('Rock removed from collection', 'error'); } // Format date function formatDate(dateStr) { const date = new Date(dateStr); const now = new Date(); const diffDays = Math.floor((now - date) / (1000 * 60 * 60 * 24)); if (diffDays === 0) return 'today'; if (diffDays === 1) return 'yesterday'; if (diffDays < 7) return `${diffDays} days ago`; if (diffDays < 30) return `${Math.floor(diffDays / 7)} weeks ago`; return date.toLocaleDateString(); } // Show toast function showToast(message, type = 'success') { toast.textContent = (type === 'success' ? '✅ ' : '🗑️ ') + message; toast.className = 'toast' + (type === 'error' ? ' error' : ''); toast.classList.add('show'); setTimeout(() => toast.classList.remove('show'), 3000); } </script> </body> </html>

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