Spaces:
Running
Running
Download index.html from YOUSEF2434/Computer-Vision-Lab: direct link, hf CLI and curl.
- Browser
- Download file 30.2 kB
-
https://huggingface.co/spaces/YOUSEF2434/Computer-Vision-Lab/resolve/main/index.html
- Command line
-
hf download hf://spaces/YOUSEF2434/Computer-Vision-Lab/index.html
-
curl -L -o index.html https://huggingface.co/spaces/YOUSEF2434/Computer-Vision-Lab/resolve/main/index.html
30.2 kB
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>AI STEM Lab</title> | |
| <style> | |
| :root { | |
| /* Dark Mode Variables */ | |
| --bg-color: #121212; | |
| --card-bg: #1e1e1e; | |
| --accent-color: #0a84ff; /* Apple-style vibrant blue */ | |
| --accent-hover: #409cff; | |
| --text-main: #f5f5f7; | |
| --text-secondary: #a1a1a6; | |
| /* Window Colors */ | |
| --mac-window-bg: #2c2c2e; | |
| --mac-header-bg: #3a3a3c; | |
| --mac-border: rgba(0, 0, 0, 0.5); | |
| } | |
| body { | |
| font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; | |
| background-color: var(--bg-color); | |
| color: var(--text-main); | |
| margin: 0; | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| justify-content: center; | |
| min-height: 100vh; | |
| padding: 20px; | |
| } | |
| /* Playground Header */ | |
| header { | |
| margin-bottom: 50px; | |
| text-align: center; | |
| max-width: 800px; | |
| } | |
| h1 { | |
| color: var(--text-main); | |
| font-weight: 800; | |
| font-size: 3rem; | |
| margin: 0 0 15px 0; | |
| letter-spacing: -0.03em; | |
| background: linear-gradient(90deg, #fff, #a1a1a6); | |
| -webkit-background-clip: text; | |
| -webkit-text-fill-color: transparent; | |
| } | |
| p.subtitle { | |
| color: var(--text-secondary); | |
| font-size: 1.3rem; | |
| line-height: 1.5; | |
| } | |
| /* Card Container */ | |
| .playground-grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(360px, 1fr)); | |
| gap: 30px; | |
| width: 95%; | |
| max-width: 1400px; | |
| } | |
| /* Lab Cards */ | |
| .card { | |
| background: var(--card-bg); | |
| border-radius: 24px; | |
| padding: 40px; | |
| box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3); | |
| transition: transform 0.3s cubic-bezier(0.25, 0.8, 0.25, 1), box-shadow 0.3s ease; | |
| display: flex; | |
| flex-direction: column; | |
| align-items: flex-start; | |
| border: 1px solid rgba(255,255,255,0.08); | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .card:hover { | |
| transform: translateY(-8px); | |
| box-shadow: 0 20px 40px rgba(0, 0, 0, 0.5); | |
| border-color: rgba(255,255,255,0.2); | |
| } | |
| .card::before { | |
| content: ''; | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 6px; | |
| background: linear-gradient(90deg, var(--accent-color), #bc52ff); | |
| opacity: 0.7; | |
| } | |
| .icon-box { | |
| width: 64px; | |
| height: 64px; | |
| background: rgba(255, 255, 255, 0.1); | |
| border-radius: 16px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: 32px; | |
| margin-bottom: 25px; | |
| } | |
| .card h2 { | |
| margin: 0 0 15px 0; | |
| font-size: 1.8rem; | |
| font-weight: 700; | |
| color: var(--text-main); | |
| } | |
| .card p { | |
| margin: 0 0 30px 0; | |
| color: var(--text-secondary); | |
| line-height: 1.6; | |
| font-size: 1.1rem; | |
| flex-grow: 1; | |
| } | |
| .card strong { | |
| color: #fff; | |
| font-weight: 600; | |
| } | |
| .launch-btn { | |
| background-color: var(--accent-color); | |
| color: white; | |
| border: none; | |
| padding: 14px 28px; | |
| border-radius: 30px; | |
| font-weight: 600; | |
| font-size: 1.1rem; | |
| cursor: pointer; | |
| transition: all 0.2s ease; | |
| width: 100%; | |
| text-align: center; | |
| } | |
| .launch-btn:hover { | |
| background-color: var(--accent-hover); | |
| transform: scale(1.02); | |
| } | |
| /* Modal Overlay */ | |
| .modal-overlay { | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| background: rgba(0, 0, 0, 0.75); | |
| backdrop-filter: blur(8px); | |
| z-index: 1000; | |
| display: none; /* Changed from visibility hidden to display none for stricter reset */ | |
| align-items: center; | |
| justify-content: center; | |
| opacity: 0; | |
| transition: opacity 0.3s ease; | |
| } | |
| .modal-overlay.active { | |
| display: flex; | |
| opacity: 1; | |
| } | |
| /* macOS Window Styling */ | |
| .mac-window { | |
| width: 85%; | |
| max-width: 1000px; | |
| height: 85vh; | |
| background: var(--mac-window-bg); | |
| border-radius: 12px; | |
| box-shadow: 0 50px 100px rgba(0, 0, 0, 0.6); | |
| display: flex; | |
| flex-direction: column; | |
| overflow: hidden; | |
| border: 1px solid rgba(255,255,255,0.1); | |
| transform: scale(0.95); | |
| transition: transform 0.3s cubic-bezier(0.19, 1, 0.22, 1); | |
| position: relative; | |
| } | |
| .modal-overlay.active .mac-window { | |
| transform: scale(1); | |
| } | |
| /* Window Header */ | |
| .window-header { | |
| height: 44px; | |
| background: var(--mac-header-bg); | |
| border-bottom: 1px solid #1c1c1e; | |
| display: flex; | |
| align-items: center; | |
| padding-left: 16px; | |
| cursor: default; | |
| } | |
| /* The Red Button */ | |
| .traffic-light { | |
| width: 14px; | |
| height: 14px; | |
| border-radius: 50%; | |
| background-color: #ff453a; | |
| border: none; | |
| cursor: pointer; | |
| position: relative; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| box-shadow: inset 0 1px 2px rgba(0,0,0,0.2); | |
| } | |
| .traffic-light:hover::after { | |
| content: "Γ"; | |
| color: #3b0000; | |
| font-size: 11px; | |
| font-weight: 900; | |
| margin-top: -1px; | |
| } | |
| .window-title { | |
| position: absolute; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| font-size: 14px; | |
| color: #cfcfcf; | |
| font-weight: 500; | |
| } | |
| /* Window Content */ | |
| .window-content { | |
| flex: 1; | |
| background: #000; | |
| position: relative; | |
| } | |
| iframe { | |
| width: 100%; | |
| height: 100%; | |
| border: none; | |
| background: #121212; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <header> | |
| <h1>AI Model Laboratory</h1> | |
| <p class="subtitle">Welcome to the hands-on section! Based on the slideshow we just watched, choose an experiment below to test how computers "see" the world.</p> | |
| </header> | |
| <div class="playground-grid"> | |
| <!-- Option 1: Pose Estimation --> | |
| <div class="card"> | |
| <div class="icon-box">π§</div> | |
| <h2>Pose Estimation</h2> | |
| <p> | |
| <strong>Remember the slide about skeletons?</strong><br><br> | |
| In this experiment, the AI will try to find your joints (like elbows, knees, and shoulders) and connect them with lines. | |
| <br><br> | |
| <em>Try this: Try to do some movements with yout hands and face. Does the AI follow your movement?</em> | |
| </p> | |
| <button class="launch-btn" onclick="openWindow('Pose Estimation', 'pose.html')">Launch Experiment</button> | |
| </div> | |
| <!-- Option 2: Object Recognition --> | |
| <div class="card"> | |
| <div class="icon-box">π</div> | |
| <h2>Object Recognition</h2> | |
| <p> | |
| <strong>How does a self-driving car see?</strong><br><br> | |
| This model is trained to recognize thousands of everyday items. It draws a box around what it sees and gives it a label. | |
| <br><br> | |
| <em>Try this: Hold up a pen, a water bottle, or your shoe. Can it guess them all correctly?</em> | |
| </p> | |
| <center> | |
| <button id="dev-trigger-btn">Wondering what objects this model can detect? Click here to find out!</button> | |
| </center> | |
| <br> | |
| <button class="launch-btn" onclick="openWindow('Object Recognition', 'Object-Detection.html')">Launch Experiment</button> | |
| </div> | |
| <!-- Option 3: Face Expression --> | |
| <div class="card"> | |
| <div class="icon-box">π</div> | |
| <h2>Face Expression</h2> | |
| <p> | |
| <strong>Can computers understand feelings?</strong><br><br> | |
| This AI looks at the geometry of your faceβhow much your mouth curves or your eyebrows liftβto guess your emotion. | |
| <br><br> | |
| <em>Try this: Make a super happy face, then a sad face. See if the "Confidence Score" changes!</em> | |
| </p> | |
| <button class="launch-btn" onclick="openWindow('Face Expression', 'Face-Expresion.html')">Launch Experiment</button> | |
| </div> | |
| </div> | |
| <h1 style="text-align:center; margin:60px 0 30px;"> | |
| Here are some extra ones that you might like.... | |
| </h1> | |
| <div class="playground-grid"> | |
| <!-- Extra Option 1 --> | |
| <div class="card"> | |
| <div class="icon-box">π</div> | |
| <h2>JS WebCam Motion Detection</h2> | |
| <p> | |
| <strong>Can a computer actually βseeβ movement?</strong><br><br> | |
| This project watches your webcam and compares each frame to the one before it. | |
| When something movesβeven a tiny bitβthe computer highlights the change so you can | |
| spot motion glowing on the screen.<br><br> | |
| <em>Try this: Wave your hand slowly, then quickly. Notice how the motion pattern changes!</em> | |
| </p> | |
| <button class="launch-btn" onclick="openWindow('Movement Detection', 'movement-detection.html')">Launch Experiment</button> | |
| </div> | |
| <!-- Extra Option 2 --> | |
| <div class="card"> | |
| <div class="icon-box">ποΈ</div> | |
| <h2>Object Detection with TensorFlow.js</h2> | |
| <p> | |
| <strong>How can a computer tell what's in a picture?</strong><br><br> | |
| This project uses a preβtrained AI model that can look at an imageβor even your | |
| webcamβand point out objects it recognizes. It doesnβt just guess the object, | |
| it also shows *where* it is in the picture by drawing a box around it.<br><br> | |
| <em>Try this: Hold up different objects (like a pencil, cup, or book) and see | |
| which ones the AI can detect!</em> | |
| </p> | |
| <button class="launch-btn" onclick="openWindow('Object Detection with TensorFlow.js', 'live-feed-object-detection.html')">Launch Experiment</button> | |
| </div> | |
| <!-- Extra Option 2 --> | |
| <div class="card"> | |
| <div class="icon-box">π»</div> | |
| <h2>Want to make your own model?</h2> | |
| <p> | |
| <strong>How about making your own AI model that detects the objects <em>you</em> care about?</strong><br><br> | |
| You can try this experiment to build your own custom model using TensorFlow.js and the Teachable Machine Algorithm.<br><br> | |
| <br> | |
| <em>Tip:</em> Try choosing 2 objects around you (like a water bottle, pencil, pair of headphones, or even yourself) and gather at least 30 images of each from different angles. The more variety you include, the smarter your model becomes.<br><br> | |
| </p> | |
| </p> | |
| <button class="launch-btn" onclick="openWindow('build your own custom model using TensorFlow.js and the Teachable Machine Algorithm', 'make-model.html')">Launch Experiment</button> | |
| </div> | |
| </div> | |
| <!-- Modal Overlay --> | |
| <div class="modal-overlay" id="modalOverlay"> | |
| <div class="mac-window" id="macWindow"> | |
| <div class="window-header"> | |
| <div class="traffic-light" id="closeBtn"></div> | |
| <div class="window-title" id="windowTitle">Terminal</div> | |
| </div> | |
| <div class="window-content"> | |
| <iframe id="labFrame" src=""></iframe> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Wait for DOM to load to prevent "not defined" errors | |
| document.addEventListener('DOMContentLoaded', function() { | |
| const overlay = document.getElementById('modalOverlay'); | |
| const macWindow = document.getElementById('macWindow'); | |
| const labFrame = document.getElementById('labFrame'); | |
| const windowTitle = document.getElementById('windowTitle'); | |
| const closeBtn = document.getElementById('closeBtn'); | |
| // Global function to be called by buttons | |
| window.openWindow = function(title, fileName) { | |
| if (windowTitle) windowTitle.textContent = "Running: " + title; | |
| if (overlay) overlay.classList.add('active'); | |
| // Set the iframe SRC to the actual file link | |
| if (labFrame) labFrame.src = fileName; | |
| }; | |
| function closeWindow() { | |
| if (overlay) overlay.classList.remove('active'); | |
| // Clear iframe src to stop the page from running in background | |
| setTimeout(() => { | |
| if (labFrame) labFrame.src = ""; | |
| }, 300); | |
| } | |
| // Close button listener | |
| if (closeBtn) { | |
| closeBtn.addEventListener('click', closeWindow); | |
| } | |
| // Click outside to close Logic | |
| if (overlay) { | |
| overlay.addEventListener('click', function(event) { | |
| if (event.target === overlay) { | |
| closeWindow(); | |
| } | |
| }); | |
| } | |
| // Prevent clicks inside the window from closing it | |
| if (macWindow) { | |
| macWindow.addEventListener('click', function(event) { | |
| event.stopPropagation(); | |
| }); | |
| } | |
| }); | |
| </script> | |
| </body> | |
| </html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <style> | |
| /* The Trigger Button */ | |
| #dev-trigger-btn { | |
| background-color: #007AFF; | |
| color: white; | |
| border: none; | |
| padding: 12px 24px; | |
| font-size: 16px; | |
| font-weight: 600; | |
| border-radius: 8px; | |
| cursor: pointer; | |
| box-shadow: 0 4px 6px rgba(0,0,0,0.1); | |
| transition: transform 0.1s ease; | |
| } | |
| #dev-trigger-btn:active { | |
| transform: scale(0.96); | |
| } | |
| /* Modal Overlay (Background) */ | |
| #modal-overlay { | |
| display: none; /* Hidden by default */ | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| background: rgba(0, 0, 0, 0.4); | |
| backdrop-filter: blur(5px); | |
| z-index: 1000; | |
| justify-content: center; | |
| align-items: center; | |
| opacity: 0; | |
| transition: opacity 0.3s ease; | |
| } | |
| /* The Dark MacOS Window */ | |
| #macos-window { | |
| width: 80%; | |
| max-width: 900px; | |
| height: 70%; | |
| background-color: #1e1e1e; /* Dark Mode Background */ | |
| border-radius: 12px; | |
| box-shadow: 0 20px 50px rgba(0,0,0,0.5), 0 0 0 1px rgba(255,255,255,0.1); | |
| display: flex; | |
| flex-direction: column; | |
| overflow: hidden; | |
| transform: scale(0.95); | |
| transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1); | |
| } | |
| /* Window Title Bar */ | |
| .window-header { | |
| height: 38px; | |
| background: linear-gradient(to bottom, #3a3a3a, #2b2b2b); | |
| border-bottom: 1px solid #000; | |
| display: flex; | |
| align-items: center; | |
| padding: 0 16px; | |
| flex-shrink: 0; | |
| } | |
| /* Traffic Light Buttons */ | |
| .window-controls { | |
| display: flex; | |
| gap: 8px; | |
| } | |
| .control-dot { | |
| width: 12px; | |
| height: 12px; | |
| border-radius: 50%; | |
| border: 1px solid rgba(0,0,0,0.2); | |
| } | |
| .close-dot { background-color: #ff5f56; cursor: pointer; } | |
| .close-dot:hover { background-color: #ff3b30; } /* Brightens on hover */ | |
| .minimize-dot { background-color: #ffbd2e; } | |
| .expand-dot { background-color: #27c93f; } | |
| .window-title { | |
| color: #d1d1d1; | |
| font-size: 13px; | |
| font-weight: 500; | |
| margin-left: 20px; | |
| flex-grow: 1; | |
| text-align: center; | |
| padding-right: 60px; /* Balance the title */ | |
| } | |
| /* Content Area */ | |
| .window-content { | |
| padding: 20px; | |
| overflow-y: auto; | |
| color: #fff; | |
| } | |
| /* Grid for Tiles */ | |
| .tiles-grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); | |
| gap: 16px; | |
| } | |
| /* Individual Tile Style */ | |
| .tile { | |
| background-color: #2c2c2e; | |
| border: 1px solid #3a3a3c; | |
| border-radius: 8px; | |
| padding: 16px; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 8px; | |
| transition: background-color 0.2s; | |
| } | |
| .tile:hover { | |
| background-color: #3a3a3c; | |
| } | |
| .tile-icon { | |
| font-size: 32px; | |
| } | |
| .tile-name { | |
| font-size: 16px; | |
| font-weight: 700; | |
| color: #fff; | |
| text-transform: capitalize; | |
| } | |
| .tile-desc { | |
| font-size: 13px; | |
| line-height: 1.4; | |
| color: #a1a1a6; | |
| } | |
| /* Scrollbar Styling */ | |
| .window-content::-webkit-scrollbar { | |
| width: 8px; | |
| } | |
| .window-content::-webkit-scrollbar-track { | |
| background: #1e1e1e; | |
| } | |
| .window-content::-webkit-scrollbar-thumb { | |
| background: #48484a; | |
| border-radius: 4px; | |
| } | |
| /* Animation States */ | |
| #modal-overlay.active { | |
| display: flex; | |
| opacity: 1; | |
| } | |
| #modal-overlay.active #macos-window { | |
| transform: scale(1); | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <!-- 1. The Trigger Button --> | |
| <!-- 2. The Modal Structure --> | |
| <div id="modal-overlay"> | |
| <div id="macos-window"> | |
| <!-- Header with Red Button --> | |
| <div class="window-header"> | |
| <div class="window-controls"> | |
| <div class="control-dot close-dot" id="close-btn" title="Close"></div> | |
| </div> | |
| <div class="window-title">COCO Dataset Classes (80 Objects)</div> | |
| </div> | |
| <!-- Content --> | |
| <div class="window-content"> | |
| <div style="margin-bottom: 20px; color: #a1a1a6; font-size: 14px;"> | |
| This AI model is trained to see the world like you do. Below are the 80 different things it can instantly recognize in a photo. | |
| </div> | |
| <div class="tiles-grid" id="tiles-container"> | |
| <!-- Tiles injected via JS --> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Data: 80 COCO Classes with Emojis and Kid-Friendly Explanations | |
| const cocoData = [ | |
| { name: "person", emoji: "π€", desc: "A human being, like you, your friends, or your teacher." }, | |
| { name: "bicycle", emoji: "π²", desc: "A two-wheeled vehicle that you pedal to ride." }, | |
| { name: "car", emoji: "π", desc: "A vehicle with four wheels used to drive on roads." }, | |
| { name: "motorcycle", emoji: "ποΈ", desc: "Like a bicycle, but with a fast engine and heavier wheels." }, | |
| { name: "airplane", emoji: "βοΈ", desc: "A flying machine with wings that carries passengers across the sky." }, | |
| { name: "bus", emoji: "π", desc: "A large vehicle that carries many people along a set route." }, | |
| { name: "train", emoji: "π", desc: "A series of connected cars that run on a metal track." }, | |
| { name: "truck", emoji: "π", desc: "A large, heavy vehicle used for carrying cargo or big loads." }, | |
| { name: "boat", emoji: "β΅", desc: "A vehicle designed to float and travel on water." }, | |
| { name: "traffic light", emoji: "π¦", desc: "A signal with red, yellow, and green lights to control cars." }, | |
| { name: "fire hydrant", emoji: "π", desc: "A pipe on the street that firefighters use to get water." }, | |
| { name: "stop sign", emoji: "π", desc: "A red octagon sign that tells drivers to stop moving." }, | |
| { name: "parking meter", emoji: "π ΏοΈ", desc: "A machine where you pay money to park your car on the street." }, | |
| { name: "bench", emoji: "πͺ", desc: "A long seat for several people, usually found in parks." }, | |
| { name: "bird", emoji: "π¦", desc: "An animal with feathers and wings that can usually fly." }, | |
| { name: "cat", emoji: "π", desc: "A small, furry pet that purrs and catches mice." }, | |
| { name: "dog", emoji: "π", desc: "A loyal pet with four legs that barks and loves to play." }, | |
| { name: "horse", emoji: "π", desc: "A large, strong animal that people can ride." }, | |
| { name: "sheep", emoji: "π", desc: "A fluffy farm animal that gives us wool for clothes." }, | |
| { name: "cow", emoji: "π", desc: "A large farm animal that gives us milk." }, | |
| { name: "elephant", emoji: "π", desc: "A huge animal with big ears and a long trunk." }, | |
| { name: "bear", emoji: "π»", desc: "A large, strong wild animal with thick fur." }, | |
| { name: "zebra", emoji: "π¦", desc: "A wild horse-like animal with black and white stripes." }, | |
| { name: "giraffe", emoji: "π¦", desc: "The tallest animal, with a very long neck to eat tree leaves." }, | |
| { name: "backpack", emoji: "π", desc: "A bag you carry on your back to hold books and supplies." }, | |
| { name: "umbrella", emoji: "βοΈ", desc: "A tool you hold over your head to stay dry in the rain." }, | |
| { name: "handbag", emoji: "π", desc: "A small bag used to carry personal items like a wallet." }, | |
| { name: "tie", emoji: "π", desc: "A long piece of cloth worn around the neck with a suit." }, | |
| { name: "suitcase", emoji: "π§³", desc: "A large bag used for packing clothes when traveling." }, | |
| { name: "frisbee", emoji: "π₯", desc: "A plastic disc you throw to a friend or dog." }, | |
| { name: "skis", emoji: "β·οΈ", desc: "Long, flat runners you attach to boots to glide on snow." }, | |
| { name: "snowboard", emoji: "π", desc: "A single wide board you stand on to surf down snowy hills." }, | |
| { name: "sports ball", emoji: "β½", desc: "Any round object used in games like soccer, basketball, or tennis." }, | |
| { name: "kite", emoji: "πͺ", desc: "A light frame with paper or cloth that flies in the wind." }, | |
| { name: "baseball bat", emoji: "βΎ", desc: "A smooth wooden or metal stick used to hit a baseball." }, | |
| { name: "baseball glove", emoji: "π§€", desc: "A leather mitt worn to catch a baseball safely." }, | |
| { name: "skateboard", emoji: "πΉ", desc: "A short board with wheels that you stand on and ride." }, | |
| { name: "surfboard", emoji: "π", desc: "A long board used to ride ocean waves." }, | |
| { name: "tennis racket", emoji: "πΎ", desc: "A bat with a net mesh used to hit a tennis ball." }, | |
| { name: "bottle", emoji: "πΎ", desc: "A container with a narrow neck for holding liquids." }, | |
| { name: "wine glass", emoji: "π·", desc: "A fancy glass with a stem, used for special drinks." }, | |
| { name: "cup", emoji: "β", desc: "A small open container for drinking tea or coffee." }, | |
| { name: "fork", emoji: "π΄", desc: "A tool with prongs used to pick up food." }, | |
| { name: "knife", emoji: "πͺ", desc: "A tool with a sharp edge used for cutting food." }, | |
| { name: "spoon", emoji: "π₯", desc: "A tool with a small scoop for eating soup or cereal." }, | |
| { name: "bowl", emoji: "π₯£", desc: "A round, deep dish used for soup or cereal." }, | |
| { name: "banana", emoji: "π", desc: "A long, curved yellow fruit that you peel to eat." }, | |
| { name: "apple", emoji: "π", desc: "A round red or green fruit that is crunchy and sweet." }, | |
| { name: "sandwich", emoji: "π₯ͺ", desc: "Two slices of bread with meat, cheese, or veggies inside." }, | |
| { name: "orange", emoji: "π", desc: "A round citrus fruit with a thick skin and juicy inside." }, | |
| { name: "broccoli", emoji: "π₯¦", desc: "A green vegetable that looks like a little tree." }, | |
| { name: "carrot", emoji: "π₯", desc: "A crunchy orange vegetable that grows underground." }, | |
| { name: "hot dog", emoji: "π", desc: "A cooked sausage served in a long, soft bun." }, | |
| { name: "pizza", emoji: "π", desc: "A round dough base topped with tomato sauce and cheese." }, | |
| { name: "donut", emoji: "π©", desc: "A sweet, fried ring of dough, often with frosting." }, | |
| { name: "cake", emoji: "π", desc: "A sweet baked dessert often eaten at birthday parties." }, | |
| { name: "chair", emoji: "πͺ", desc: "A piece of furniture designed for one person to sit on." }, | |
| { name: "couch", emoji: "ποΈ", desc: "A soft, long seat where multiple people can relax." }, | |
| { name: "potted plant", emoji: "πͺ΄", desc: "A plant grown inside a container for decoration." }, | |
| { name: "bed", emoji: "ποΈ", desc: "A piece of furniture with a mattress for sleeping." }, | |
| { name: "dining table", emoji: "π½οΈ", desc: "A large table where families sit to eat meals." }, | |
| { name: "toilet", emoji: "π½", desc: "A bathroom fixture used for getting rid of waste." }, | |
| { name: "tv", emoji: "πΊ", desc: "An electronic screen for watching shows and movies." }, | |
| { name: "laptop", emoji: "π»", desc: "A portable computer that you can use on your lap." }, | |
| { name: "mouse", emoji: "π±οΈ", desc: "A handheld device used to move the cursor on a computer." }, | |
| { name: "remote", emoji: "π‘", desc: "A controller used to change channels on a TV from afar." }, | |
| { name: "keyboard", emoji: "β¨οΈ", desc: "A board with buttons for typing letters into a computer." }, | |
| { name: "cell phone", emoji: "π±", desc: "A small phone you can carry in your pocket." }, | |
| { name: "microwave", emoji: "βββββββ²οΈ", desc: "An oven that heats food very quickly." }, | |
| { name: "oven", emoji: "π₯", desc: "A kitchen appliance used for baking and roasting food." }, | |
| { name: "toaster", emoji: "π", desc: "A machine that browns bread slices." }, | |
| { name: "sink", emoji: "π°", desc: "A basin with a faucet for washing hands or dishes." }, | |
| { name: "refrigerator", emoji: "βοΈ", desc: "A cold closet that keeps food fresh." }, | |
| { name: "book", emoji: "π", desc: "A set of pages with writing or pictures to read." }, | |
| { name: "clock", emoji: "β°", desc: "A device that tells you what time it is." }, | |
| { name: "vase", emoji: "πΊ", desc: "A decorative container used for holding flowers." }, | |
| { name: "scissors", emoji: "βοΈ", desc: "A tool with two blades used for cutting paper." }, | |
| { name: "teddy bear", emoji: "π§Έ", desc: "A soft toy bear that is cuddly and cute." }, | |
| { name: "hair drier", emoji: "π¨", desc: "A machine that blows hot air to dry wet hair." }, | |
| { name: "toothbrush", emoji: "πͺ₯", desc: "A small brush used to clean your teeth." } | |
| ]; | |
| // DOM Elements | |
| const triggerBtn = document.getElementById('dev-trigger-btn'); | |
| const modal = document.getElementById('modal-overlay'); | |
| const closeBtn = document.getElementById('close-btn'); | |
| const tilesContainer = document.getElementById('tiles-container'); | |
| const macosWindow = document.getElementById('macos-window'); | |
| // 1. Populate the Grid | |
| function renderTiles() { | |
| tilesContainer.innerHTML = cocoData.map(item => ` | |
| <div class="tile"> | |
| <div class="tile-icon">${item.emoji}</div> | |
| <div class="tile-name">${item.name}</div> | |
| <div class="tile-desc">${item.desc}</div> | |
| </div> | |
| `).join(''); | |
| } | |
| // 2. Open Modal Function | |
| triggerBtn.addEventListener('click', () => { | |
| renderTiles(); // Render content on open | |
| modal.classList.add('active'); // Show modal | |
| }); | |
| // 3. Close Modal Function | |
| function closeModal() { | |
| modal.classList.remove('active'); | |
| } | |
| // Event: Click the Red Dot | |
| closeBtn.addEventListener('click', closeModal); | |
| // Event: Click Outside the Window | |
| modal.addEventListener('click', (e) => { | |
| // If the user clicks the dark background (modal), close it. | |
| // If they click INSIDE the window, do nothing. | |
| if (e.target === modal) { | |
| closeModal(); | |
| } | |
| }); | |
| </script> | |
| </body> | |
| </html> | |