Spaces:
Running
Running
jasondo OpenAI Codex commited on
Commit ·
92853cc
1
Parent(s): c5339c8
Add hackathon presentation deck
Browse filesCo-authored-by: OpenAI Codex <codex@openai.com>
- AGENTS.md +15 -2
- PRESENTATION_PROMPT.md +181 -0
- README.md +9 -5
- presentation/assets/.gitkeep +1 -0
- presentation/deck.html +938 -0
AGENTS.md
CHANGED
|
@@ -399,6 +399,17 @@ technical cutaway animation.
|
|
| 399 |
assembly` at `0.65` confidence with an emitted motion axis of
|
| 400 |
`[1.0, 0.0, 0.0]`, and `/generate_scene` returned `renderer: three`,
|
| 401 |
`render_mode: three`, and no HTML field.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 402 |
|
| 403 |
## Next Work
|
| 404 |
|
|
@@ -406,8 +417,10 @@ technical cutaway animation.
|
|
| 406 |
tune token/context/timeout values down if valid JSON remains reliable with
|
| 407 |
lower latency. The synthetic Modal check now succeeds with the current
|
| 408 |
`4096` output token, `8192` context, `300s` timeout settings.
|
| 409 |
-
-
|
| 410 |
-
|
|
|
|
|
|
|
| 411 |
- Keep the README opening hook intact: "You find a small metal cylinder at a
|
| 412 |
flea market. What is it? How does it work inside?" Maintain the judge-facing
|
| 413 |
YAML tags and public pitch if future README updates are needed.
|
|
|
|
| 399 |
assembly` at `0.65` confidence with an emitted motion axis of
|
| 400 |
`[1.0, 0.0, 0.0]`, and `/generate_scene` returned `renderer: three`,
|
| 401 |
`render_mode: three`, and no HTML field.
|
| 402 |
+
- User made Hugging Face Space `jasondo111/Snap2Sim` public on June 15, 2026.
|
| 403 |
+
Verification confirmed Hub metadata `private=false`, the public Space page
|
| 404 |
+
returned `200`, and the public app host
|
| 405 |
+
`https://jasondo111-snap2sim.hf.space` returned the trusted shell with the
|
| 406 |
+
confidence slider present. The Space has not been transferred to
|
| 407 |
+
`build-small-hackathon/Snap2Sim`; that target repo did not exist at the time
|
| 408 |
+
of verification.
|
| 409 |
+
- Public endpoint smoke verification on June 15, 2026 passed: `/generate_scene`
|
| 410 |
+
returned `renderer: three` with no HTML field for `EXAMPLE_ANALYSIS`, and
|
| 411 |
+
`/analyze_image` returned a real Modal analysis for a synthetic target-like
|
| 412 |
+
image as `rotary indexer` at `0.6` confidence with 3 parts.
|
| 413 |
|
| 414 |
## Next Work
|
| 415 |
|
|
|
|
| 417 |
tune token/context/timeout values down if valid JSON remains reliable with
|
| 418 |
lower latency. The synthetic Modal check now succeeds with the current
|
| 419 |
`4096` output token, `8192` context, `300s` timeout settings.
|
| 420 |
+
- The Hugging Face Space is now public under `jasondo111/Snap2Sim`. If the
|
| 421 |
+
submission requires org ownership, transfer it to
|
| 422 |
+
`build-small-hackathon/Snap2Sim`, then update README, presentation links, and
|
| 423 |
+
`.github/workflows/sync_to_hf.yml`.
|
| 424 |
- Keep the README opening hook intact: "You find a small metal cylinder at a
|
| 425 |
flea market. What is it? How does it work inside?" Maintain the judge-facing
|
| 426 |
YAML tags and public pitch if future README updates are needed.
|
PRESENTATION_PROMPT.md
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# PRESENTATION_PROMPT.md
|
| 2 |
+
|
| 3 |
+
> Build instructions for Codex. Goal: produce a **self-contained HTML slide deck**
|
| 4 |
+
> that markets Snap2Sim — "Inside the Machine" to **Build Small Hackathon judges**.
|
| 5 |
+
> Tone: interesting, intuitive, fun, concise, beautifully formatted. This file is
|
| 6 |
+
> a spec, not the deck. Follow the deliverable + slide plan below.
|
| 7 |
+
|
| 8 |
+
---
|
| 9 |
+
|
| 10 |
+
## 1. Deliverable
|
| 11 |
+
|
| 12 |
+
Create `presentation/deck.html` — a single, **self-contained** reveal.js deck.
|
| 13 |
+
|
| 14 |
+
- Use the [reveal.js](https://revealjs.com/) CDN (`<script src="https://cdn.jsdelivr.net/npm/reveal.js@5/dist/reveal.js">` + matching CSS), so there is **no build step**. Opens in any browser.
|
| 15 |
+
- Put any standalone assets (exported screenshots, fonts you self-host if needed) in `presentation/assets/`. Prefer inline SVG over external images so the deck stays portable.
|
| 16 |
+
- The architecture diagram must be **inline SVG (or Mermaid rendered to inline SVG)** so the deck has no broken-image risk during a live demo.
|
| 17 |
+
- Keyboard nav, speaker notes (`data-notes` / the reveal notes plugin), and a PDF export path (`?print-pdf`) should all work.
|
| 18 |
+
- No external API calls, no tracking, no network dependency beyond the reveal.js + font CDNs.
|
| 19 |
+
|
| 20 |
+
### Match the product's visual identity (this is a "technical field-manual / cutaway" aesthetic)
|
| 21 |
+
|
| 22 |
+
Pull the theme straight from `index.html` so the deck feels like the same product:
|
| 23 |
+
|
| 24 |
+
```
|
| 25 |
+
--bg: #0F1318 (near-black blue)
|
| 26 |
+
--bg-panel: #161B22
|
| 27 |
+
--bg-lift: #1E2530
|
| 28 |
+
--amber: #E8A33D (primary accent — headings, key numbers)
|
| 29 |
+
--cyan: #5FD4D0 (secondary accent — labels, links, diagram lines)
|
| 30 |
+
--text: #C8C0AC (warm off-white body)
|
| 31 |
+
--text-muted:#9CA3AF
|
| 32 |
+
--danger: #F07F5A
|
| 33 |
+
--grid: rgba(255,255,255,0.04)
|
| 34 |
+
```
|
| 35 |
+
|
| 36 |
+
- Fonts: **"Chakra Petch"** for headings/UI and **"Fira Code"** (monospace) for data, labels, code, and stat callouts. Load from Google Fonts.
|
| 37 |
+
- Texture cues to carry over from the app: faint blueprint **grid background**, thin **cyan scan-line / divider rules**, amber section kickers, a subtle vignette. Keep it tasteful — readability first, one or two motion flourishes max.
|
| 38 |
+
- Every slide: small monospace **kicker label** top-left (e.g. `01 · THE PROBLEM`) and a faint `SNAP2SIM // INSIDE THE MACHINE` watermark. This mirrors the in-app component watermark + reticle styling.
|
| 39 |
+
|
| 40 |
+
---
|
| 41 |
+
|
| 42 |
+
## 2. Slide plan (in order)
|
| 43 |
+
|
| 44 |
+
The user explicitly required slides 1–3 in this order. Build the full deck below.
|
| 45 |
+
|
| 46 |
+
### Slide 1 — The Problem (REQUIRED, first)
|
| 47 |
+
Lead with the product's own hook, verbatim, as the emotional opening:
|
| 48 |
+
|
| 49 |
+
> "You find a small metal cylinder at a flea market. What is it? How does it work inside?"
|
| 50 |
+
|
| 51 |
+
Then frame the problem crisply:
|
| 52 |
+
- Curious makers, repair hobbyists, thrift scavengers, and robotics students constantly hold **mystery hardware** and can't see what's happening inside.
|
| 53 |
+
- Existing image AI **stops at a label** ("this is a valve") — it never answers the real question: *what moves, and why?*
|
| 54 |
+
- Teardowns, manuals, and exploded diagrams are scattered, intimidating, or don't exist for that exact part.
|
| 55 |
+
|
| 56 |
+
Keep it to 3 tight bullets + the hook. Don't over-explain.
|
| 57 |
+
|
| 58 |
+
### Slide 2 — The Solution (REQUIRED, second)
|
| 59 |
+
One-line positioning statement (make it pop in amber):
|
| 60 |
+
|
| 61 |
+
> **Snap a photo. Watch the mechanism come alive.**
|
| 62 |
+
|
| 63 |
+
Then: Snap2Sim turns a single photo of a hardware component into a **narrated, animated 3D mechanical cutaway** — it names the internal parts and shows the hidden motion: the plunger sliding, the spring loading, the rotor spinning, the pawl catching, the port opening.
|
| 64 |
+
|
| 65 |
+
Three short "what you get" pillars (use icon-ish monospace chips):
|
| 66 |
+
1. **Identify** — the likely mechanism + confidence, not just a class name.
|
| 67 |
+
2. **Explain** — internal parts, the trigger, and the motion sequence in plain language.
|
| 68 |
+
3. **Animate** — a moving Three.js field-manual cutaway you can orbit, zoom, and reset.
|
| 69 |
+
|
| 70 |
+
Add the honesty angle as a one-liner: when a confident 3D reconstruction isn't justified, it **falls back to annotated callouts on the original photo instead of pretending.** (Judges love that it doesn't hallucinate geometry.)
|
| 71 |
+
|
| 72 |
+
### Slide 3 — How It Works / Architecture Diagram (REQUIRED, third)
|
| 73 |
+
An **inline SVG** flow diagram of the real pipeline. Nodes and flow (left → right), styled with cyan connectors and amber node borders on dark panels:
|
| 74 |
+
|
| 75 |
+
```
|
| 76 |
+
[ Photo upload ]
|
| 77 |
+
│ same-origin POST /analyze_image
|
| 78 |
+
▼
|
| 79 |
+
[ Hugging Face Space (gradio.Server, cpu-basic) ]
|
| 80 |
+
│ bearer-token, server-side secret
|
| 81 |
+
▼
|
| 82 |
+
[ Modal GPU endpoint ]
|
| 83 |
+
│ llama.cpp + llama-mtmd-cli
|
| 84 |
+
▼
|
| 85 |
+
[ NVIDIA Nemotron 3 Nano Omni 30B-A3B GGUF (UD-Q4_K_M + mmproj-F16) ]
|
| 86 |
+
│ returns structured mechanism JSON
|
| 87 |
+
▼
|
| 88 |
+
[ /generate_scene → JSON schema validation → render-mode select ]
|
| 89 |
+
│
|
| 90 |
+
▼
|
| 91 |
+
[ Browser renders DETERMINISTIC Three.js cutaway ] ──(low confidence)──▶ [ Annotated-photo fallback ]
|
| 92 |
+
```
|
| 93 |
+
|
| 94 |
+
Caption the key architectural decision under the diagram:
|
| 95 |
+
> **The model describes the mechanism. The browser owns the rendering.** No model-authored HTML/JS ever touches the page — that keeps the demo reliable and safe.
|
| 96 |
+
|
| 97 |
+
If you use Mermaid, render it to inline SVG at build time or load Mermaid from CDN and let it render on slide-ready; either way it must display with zero external image files.
|
| 98 |
+
|
| 99 |
+
### Slide 4 — Live Demo / "The Moment"
|
| 100 |
+
- Frame the demo: photo in → cutaway out, in seconds.
|
| 101 |
+
- Use the in-theme demo mockup currently in the deck, or replace it later with intentionally captured product screenshots in `presentation/assets/`.
|
| 102 |
+
- Callout the interactivity: orbit / zoom / reset, play-pause, confidence slider.
|
| 103 |
+
- Speaker note: "Drop in a valve, lock, pump, gear train, fan, or latch."
|
| 104 |
+
|
| 105 |
+
### Slide 5 — What Makes It Different
|
| 106 |
+
Tight comparison. Most image demos stop at a label; Snap2Sim answers *"what would I see if I cut this open?"*
|
| 107 |
+
- Mechanism explanation, not a class name.
|
| 108 |
+
- Maps internal parts into a moving technical cutaway.
|
| 109 |
+
- Honest uncertainty: confidence threshold + photo-annotation fallback.
|
| 110 |
+
- Custom branded maker tool, not a default chat/form UI.
|
| 111 |
+
- Secrets + GPU endpoints stay server-side; client calls only same-origin APIs.
|
| 112 |
+
|
| 113 |
+
### Slide 6 — Tech Stack & Hackathon Fit (the judge-credibility slide)
|
| 114 |
+
Two columns.
|
| 115 |
+
|
| 116 |
+
**Stack** (monospace list):
|
| 117 |
+
- Frontend: plain `index.html` + CSS + JS served by `gradio.Server`.
|
| 118 |
+
- Rendering: deterministic Three.js primitives (box, cylinder, cone, capsule, sphere, rod, gear, torus, spring), OrbitControls, camera fitting, annotated-photo fallback.
|
| 119 |
+
- Model: NVIDIA Nemotron 3 Nano Omni 30B-A3B GGUF (~30B total / ~3B active per MoE token — **under the 32B budget**) via llama.cpp.
|
| 120 |
+
- GPU: Modal, weights cached in a Modal Volume, bearer-token protected.
|
| 121 |
+
- Contract: JSON schema validation before anything renders.
|
| 122 |
+
|
| 123 |
+
**Badges we're claiming** (render as themed chips — confirmed ones in amber, pending in muted):
|
| 124 |
+
| Badge | Status |
|
| 125 |
+
|---|---|
|
| 126 |
+
| Backyard AI (track) | core fit |
|
| 127 |
+
| Llama Champion | confirmed |
|
| 128 |
+
| NVIDIA Nemotron Quest | confirmed |
|
| 129 |
+
| Modal Award | confirmed |
|
| 130 |
+
| Off-Brand | confirmed |
|
| 131 |
+
| OpenAI Codex | confirmed |
|
| 132 |
+
| Best Demo / Sharing is Caring | pending demo video + social post |
|
| 133 |
+
| Off the Grid | not claimed (inference runs on Modal) |
|
| 134 |
+
|
| 135 |
+
### Slide 7 — Closing / Call to Action
|
| 136 |
+
- Restate the one-liner: **Snap a photo. See inside the machine.**
|
| 137 |
+
- Links: GitHub source of truth `https://github.com/Bigstonks1/Snap2Sim`; Hugging Face Space `https://huggingface.co/spaces/jasondo111/Snap2Sim` (public submission Space; transfer to `build-small-hackathon/Snap2Sim` is pending if required).
|
| 138 |
+
- Credit line: "Built by Jason Do with implementation assistance from OpenAI Codex."
|
| 139 |
+
- End on the hook image/line for symmetry with slide 1.
|
| 140 |
+
|
| 141 |
+
---
|
| 142 |
+
|
| 143 |
+
## 3. Findings from the codebase review (source material — all verified in-repo)
|
| 144 |
+
|
| 145 |
+
Use these as the factual backbone. Do **not** invent metrics or claims beyond these.
|
| 146 |
+
|
| 147 |
+
- **Product**: Snap2Sim / "Inside the Machine" — photo of a hardware component → identified mechanism → animated 3D technical cutaway with named internal parts, trigger, and motion sequence. (`README.md`, `AGENTS.md`)
|
| 148 |
+
- **The hook** (keep verbatim, per AGENTS.md "Next Work" — do not alter): *"You find a small metal cylinder at a flea market. What is it? How does it work inside?"*
|
| 149 |
+
- **Audience**: garage tinkerers, repair hobbyists, thrift-store scavengers, robotics students — "people who learn by taking things apart." (`README.md` Hackathon Fit)
|
| 150 |
+
- **Pipeline** (`README.md` How It Works): browser → same-origin `/analyze_image` on the HF Space → secured Modal endpoint → Nemotron via llama.cpp/`llama-mtmd-cli` → structured mechanism JSON → `/generate_scene` validates + picks render mode → browser renders deterministic Three.js, or annotated-photo fallback.
|
| 151 |
+
- **Key safety/architecture decision**: "The model describes the mechanism. The browser owns the rendering." No model-authored HTML/JS injection. Schema validation in `snap2sim/schema.py` gates rendering. (`README.md`, `AGENTS.md`)
|
| 152 |
+
- **Renderer vocabulary** (`snap2sim/prompts.py`, `snap2sim/schema.py`): shapes = box, cylinder, cone, capsule, sphere, rod, gear, torus, spring; motions = static, rotate, oscillate, translate, screw, orbit, pulse; 2–6 parts per scene.
|
| 153 |
+
- **Honesty features**: confidence threshold slider (default 0.5), render-mode selection (`three` / `annotate` / `unavailable`), annotated-photo fallback with numbered markers + leader lines. (`docs/features/`)
|
| 154 |
+
- **Model**: `unsloth/NVIDIA-Nemotron-3-Nano-Omni-30B-A3B-Reasoning-GGUF`, quant `UD-Q4_K_M` + `mmproj-F16.gguf`. ~30B total / ~3B active per MoE token → under the hackathon's 32B budget. (`README.md` Tech Stack)
|
| 155 |
+
- **Infra**: HF Space on `cpu-basic`; GPU inference on Modal with Modal Volume asset caching; bearer-token auth between Space and Modal (secret `snap2sim-api-auth` / `SNAP2SIM_API_TOKEN`); unauthenticated requests return `401`. Space is public for submission. (`AGENTS.md`, `SECURITY.md`)
|
| 156 |
+
- **Security posture** (`docs/reviews/security-hardening.md`): rate limiting on both endpoints, upload-size caps, PIL decompression-bomb handling, temp-file cleanup, no model-authored scene HTML.
|
| 157 |
+
- **Badges** confirmed per AGENTS.md: Llama Champion, NVIDIA Nemotron Quest, Modal Award, Off-Brand, OpenAI Codex. Off the Grid is explicitly **not** claimed (Modal inference). Best Demo / Sharing is Caring pending public demo video + social post.
|
| 158 |
+
- **Visual identity tokens**: see Section 1 (sourced from `index.html`).
|
| 159 |
+
- **Credit**: Built by Jason Do with implementation assistance from OpenAI Codex. Commit trailer convention: `Co-authored-by: OpenAI Codex <codex@openai.com>`.
|
| 160 |
+
|
| 161 |
+
### Marketing angles worth leaning into (for tone)
|
| 162 |
+
- The emotional payoff: "the moment a curious maker gets to **see the hidden motion**." (Pulled from README — this is the strongest line in the repo.)
|
| 163 |
+
- "Most image demos stop at a label. Snap2Sim answers the next question: *what would I see if I cut this open?*"
|
| 164 |
+
- The honesty differentiator: it shows uncertainty instead of hallucinating geometry. Judges reward this.
|
| 165 |
+
|
| 166 |
+
---
|
| 167 |
+
|
| 168 |
+
## 4. Next steps for Codex (in build order)
|
| 169 |
+
|
| 170 |
+
1. Scaffold `presentation/deck.html` with reveal.js CDN, the theme tokens from Section 1, Chakra Petch + Fira Code fonts, grid/scan-line/vignette texture, and the per-slide kicker + watermark chrome.
|
| 171 |
+
2. Build slides 1–3 exactly as specified (Problem → Solution → inline-SVG architecture diagram). These are the required core.
|
| 172 |
+
3. Build the inline-SVG (or CDN-Mermaid-to-SVG) pipeline diagram for slide 3 from the flow in Section 2.
|
| 173 |
+
4. Add slides 4–7.
|
| 174 |
+
5. Keep the in-theme demo mockup on slide 4 unless real product screenshots are intentionally captured and added later.
|
| 175 |
+
6. Verify: open in a browser, arrow through all slides, confirm the diagram renders inline with no broken images, confirm `?print-pdf` exports cleanly, confirm no horizontal overflow at 1280×720 and 1920×1080.
|
| 176 |
+
7. Keep all private endpoint URLs and tokens **out** of the deck — only the public GitHub + HF Space links from Section 3.
|
| 177 |
+
8. Do not claim Off the Grid. Do not mark Best Demo / Sharing is Caring as confirmed.
|
| 178 |
+
|
| 179 |
+
### Open items / placeholders to flag in the deck
|
| 180 |
+
- Public demo video + social post link (needed before Best Demo / Sharing is Caring can be claimed).
|
| 181 |
+
- Space is public under `jasondo111/Snap2Sim`; org transfer remains pending if the submission process requires it.
|
README.md
CHANGED
|
@@ -45,9 +45,9 @@ the pawl catching, the port opening.
|
|
| 45 |
- App host: https://jasondo111-snap2sim.hf.space
|
| 46 |
- Source of truth: https://github.com/Bigstonks1/Snap2Sim
|
| 47 |
|
| 48 |
-
The Space is
|
| 49 |
-
|
| 50 |
-
|
| 51 |
|
| 52 |
## Hackathon Fit
|
| 53 |
|
|
@@ -122,11 +122,14 @@ question: "what would I see if I cut this open?"
|
|
| 122 |
|
| 123 |
Recent local and deployed checks confirmed:
|
| 124 |
|
| 125 |
-
- The
|
| 126 |
- `/analyze_image` returns validated mechanism payloads through the secured
|
| 127 |
Modal bearer-token flow.
|
|
|
|
|
|
|
|
|
|
| 128 |
- `/generate_scene` returns a deterministic Three.js scene descriptor, not raw
|
| 129 |
-
HTML.
|
| 130 |
- The renderer handles six-part scenes, axial orientation from geometry sizes,
|
| 131 |
geometry-aware motion-axis fallback, fitted camera framing, orbit controls,
|
| 132 |
reset view, mobile layout, and annotated-photo fallbacks.
|
|
@@ -178,6 +181,7 @@ $env:PYTHONIOENCODING="utf-8"; python -m modal run modal_app.py::run_runtime_pre
|
|
| 178 |
- `app.py` - Gradio Server app, same-origin APIs, image validation, rate limits.
|
| 179 |
- `index.html` - upload flow, analysis panel, Three.js renderer, fallback UI.
|
| 180 |
- `modal_app.py` - Modal deployment, llama.cpp runtime, diagnostics.
|
|
|
|
| 181 |
- `docs/` - implementation notes, review passes, and representative fixtures.
|
| 182 |
- `snap2sim/backend.py` - backend selection and authenticated Modal client.
|
| 183 |
- `snap2sim/prompts.py` - vision prompt contract.
|
|
|
|
| 45 |
- App host: https://jasondo111-snap2sim.hf.space
|
| 46 |
- Source of truth: https://github.com/Bigstonks1/Snap2Sim
|
| 47 |
|
| 48 |
+
The Space is public for submission. The app is built as a Gradio Space with a
|
| 49 |
+
custom `gradio.Server` shell; GitHub remains the source of truth for code
|
| 50 |
+
changes.
|
| 51 |
|
| 52 |
## Hackathon Fit
|
| 53 |
|
|
|
|
| 122 |
|
| 123 |
Recent local and deployed checks confirmed:
|
| 124 |
|
| 125 |
+
- The public Space serves the trusted `index.html` shell.
|
| 126 |
- `/analyze_image` returns validated mechanism payloads through the secured
|
| 127 |
Modal bearer-token flow.
|
| 128 |
+
- A public smoke test on June 15, 2026 returned a real Modal analysis for a
|
| 129 |
+
synthetic target-like image as `rotary indexer` at `0.6` confidence with 3
|
| 130 |
+
parts.
|
| 131 |
- `/generate_scene` returns a deterministic Three.js scene descriptor, not raw
|
| 132 |
+
HTML; a public smoke test returned `renderer: three`.
|
| 133 |
- The renderer handles six-part scenes, axial orientation from geometry sizes,
|
| 134 |
geometry-aware motion-axis fallback, fitted camera framing, orbit controls,
|
| 135 |
reset view, mobile layout, and annotated-photo fallbacks.
|
|
|
|
| 181 |
- `app.py` - Gradio Server app, same-origin APIs, image validation, rate limits.
|
| 182 |
- `index.html` - upload flow, analysis panel, Three.js renderer, fallback UI.
|
| 183 |
- `modal_app.py` - Modal deployment, llama.cpp runtime, diagnostics.
|
| 184 |
+
- `presentation/deck.html` - reveal.js judging deck for the hackathon pitch.
|
| 185 |
- `docs/` - implementation notes, review passes, and representative fixtures.
|
| 186 |
- `snap2sim/backend.py` - backend selection and authenticated Modal client.
|
| 187 |
- `snap2sim/prompts.py` - vision prompt contract.
|
presentation/assets/.gitkeep
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
|
presentation/deck.html
ADDED
|
@@ -0,0 +1,938 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!doctype html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="utf-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
| 6 |
+
<title>Snap2Sim // Inside the Machine</title>
|
| 7 |
+
<link rel="icon" href="data:,">
|
| 8 |
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
| 9 |
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
| 10 |
+
<link href="https://fonts.googleapis.com/css2?family=Chakra+Petch:wght@400;500;600;700&family=Fira+Code:wght@400;500;600&display=swap" rel="stylesheet">
|
| 11 |
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reveal.js@5/dist/reset.css">
|
| 12 |
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reveal.js@5/dist/reveal.css">
|
| 13 |
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reveal.js@5/dist/theme/black.css" id="theme">
|
| 14 |
+
<style>
|
| 15 |
+
:root {
|
| 16 |
+
--bg: #0F1318;
|
| 17 |
+
--bg-panel: #161B22;
|
| 18 |
+
--bg-lift: #1E2530;
|
| 19 |
+
--amber: #E8A33D;
|
| 20 |
+
--cyan: #5FD4D0;
|
| 21 |
+
--text: #C8C0AC;
|
| 22 |
+
--text-muted: #9CA3AF;
|
| 23 |
+
--danger: #F07F5A;
|
| 24 |
+
--grid: rgba(255,255,255,0.04);
|
| 25 |
+
--line: rgba(95,212,208,0.34);
|
| 26 |
+
--amber-line: rgba(232,163,61,0.45);
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
html,
|
| 30 |
+
body {
|
| 31 |
+
background: var(--bg);
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
body::before,
|
| 35 |
+
body::after {
|
| 36 |
+
content: "";
|
| 37 |
+
position: fixed;
|
| 38 |
+
inset: 0;
|
| 39 |
+
pointer-events: none;
|
| 40 |
+
z-index: 1;
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
body::before {
|
| 44 |
+
background:
|
| 45 |
+
linear-gradient(var(--grid) 1px, transparent 1px),
|
| 46 |
+
linear-gradient(90deg, var(--grid) 1px, transparent 1px);
|
| 47 |
+
background-size: 32px 32px;
|
| 48 |
+
opacity: 0.9;
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
body::after {
|
| 52 |
+
background:
|
| 53 |
+
radial-gradient(circle at 50% 42%, transparent 48%, rgba(0,0,0,0.52)),
|
| 54 |
+
linear-gradient(90deg, rgba(0,0,0,0.2), transparent 22%, transparent 78%, rgba(0,0,0,0.24));
|
| 55 |
+
mix-blend-mode: multiply;
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
.reveal {
|
| 59 |
+
color: var(--text);
|
| 60 |
+
font-family: "Chakra Petch", "Aptos", sans-serif;
|
| 61 |
+
letter-spacing: 0;
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
.reveal .slides {
|
| 65 |
+
text-align: left;
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
.reveal .slides > section {
|
| 69 |
+
height: 100%;
|
| 70 |
+
max-height: 100%;
|
| 71 |
+
overflow: hidden;
|
| 72 |
+
min-height: 100%;
|
| 73 |
+
padding: 50px 56px 46px;
|
| 74 |
+
box-sizing: border-box;
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
.slide-grid {
|
| 78 |
+
display: grid;
|
| 79 |
+
gap: 24px;
|
| 80 |
+
height: 100%;
|
| 81 |
+
min-height: 0;
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
.two-col {
|
| 85 |
+
display: grid;
|
| 86 |
+
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
|
| 87 |
+
gap: 30px;
|
| 88 |
+
align-items: stretch;
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
.kicker {
|
| 92 |
+
position: absolute;
|
| 93 |
+
top: 26px;
|
| 94 |
+
left: 36px;
|
| 95 |
+
color: var(--amber);
|
| 96 |
+
font-family: "Fira Code", monospace;
|
| 97 |
+
font-size: 13px;
|
| 98 |
+
font-weight: 600;
|
| 99 |
+
letter-spacing: 0;
|
| 100 |
+
text-transform: uppercase;
|
| 101 |
+
}
|
| 102 |
+
|
| 103 |
+
.watermark {
|
| 104 |
+
position: absolute;
|
| 105 |
+
right: 34px;
|
| 106 |
+
bottom: 24px;
|
| 107 |
+
color: rgba(200,192,172,0.13);
|
| 108 |
+
font-family: "Fira Code", monospace;
|
| 109 |
+
font-size: 12px;
|
| 110 |
+
letter-spacing: 0;
|
| 111 |
+
text-transform: uppercase;
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
.section-rule {
|
| 115 |
+
height: 2px;
|
| 116 |
+
background: linear-gradient(90deg, transparent, var(--cyan), transparent);
|
| 117 |
+
box-shadow: 0 0 20px rgba(95,212,208,0.42);
|
| 118 |
+
}
|
| 119 |
+
|
| 120 |
+
h1,
|
| 121 |
+
h2,
|
| 122 |
+
h3 {
|
| 123 |
+
margin: 0;
|
| 124 |
+
color: var(--text);
|
| 125 |
+
font-family: "Chakra Petch", "Aptos Display", sans-serif;
|
| 126 |
+
font-weight: 700;
|
| 127 |
+
letter-spacing: 0;
|
| 128 |
+
text-transform: uppercase;
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
h1 {
|
| 132 |
+
max-width: 920px;
|
| 133 |
+
font-size: 54px;
|
| 134 |
+
line-height: 0.96;
|
| 135 |
+
}
|
| 136 |
+
|
| 137 |
+
h2 {
|
| 138 |
+
font-size: 38px;
|
| 139 |
+
line-height: 1.04;
|
| 140 |
+
}
|
| 141 |
+
|
| 142 |
+
h3 {
|
| 143 |
+
color: var(--cyan);
|
| 144 |
+
font-size: 22px;
|
| 145 |
+
line-height: 1.12;
|
| 146 |
+
}
|
| 147 |
+
|
| 148 |
+
.hook {
|
| 149 |
+
max-width: 960px;
|
| 150 |
+
color: var(--amber);
|
| 151 |
+
font-size: 52px;
|
| 152 |
+
font-weight: 700;
|
| 153 |
+
line-height: 1.02;
|
| 154 |
+
text-transform: none;
|
| 155 |
+
}
|
| 156 |
+
|
| 157 |
+
.positioning {
|
| 158 |
+
color: var(--amber);
|
| 159 |
+
font-size: 46px;
|
| 160 |
+
font-weight: 700;
|
| 161 |
+
line-height: 1;
|
| 162 |
+
text-transform: uppercase;
|
| 163 |
+
}
|
| 164 |
+
|
| 165 |
+
p {
|
| 166 |
+
margin: 0;
|
| 167 |
+
color: var(--text);
|
| 168 |
+
font-size: 20px;
|
| 169 |
+
line-height: 1.38;
|
| 170 |
+
}
|
| 171 |
+
|
| 172 |
+
strong {
|
| 173 |
+
color: var(--amber);
|
| 174 |
+
font-weight: 700;
|
| 175 |
+
}
|
| 176 |
+
|
| 177 |
+
em {
|
| 178 |
+
color: var(--cyan);
|
| 179 |
+
font-style: normal;
|
| 180 |
+
}
|
| 181 |
+
|
| 182 |
+
ul {
|
| 183 |
+
margin: 0;
|
| 184 |
+
padding: 0;
|
| 185 |
+
list-style: none;
|
| 186 |
+
}
|
| 187 |
+
|
| 188 |
+
li {
|
| 189 |
+
position: relative;
|
| 190 |
+
margin: 0 0 11px;
|
| 191 |
+
padding-left: 22px;
|
| 192 |
+
color: var(--text);
|
| 193 |
+
font-size: 19px;
|
| 194 |
+
line-height: 1.34;
|
| 195 |
+
}
|
| 196 |
+
|
| 197 |
+
li::before {
|
| 198 |
+
content: "";
|
| 199 |
+
position: absolute;
|
| 200 |
+
left: 0;
|
| 201 |
+
top: 0.58em;
|
| 202 |
+
width: 8px;
|
| 203 |
+
height: 8px;
|
| 204 |
+
border: 1px solid var(--cyan);
|
| 205 |
+
transform: rotate(45deg);
|
| 206 |
+
background: rgba(95,212,208,0.12);
|
| 207 |
+
}
|
| 208 |
+
|
| 209 |
+
.panel,
|
| 210 |
+
.card,
|
| 211 |
+
.chip,
|
| 212 |
+
.screen {
|
| 213 |
+
border: 1px solid var(--amber-line);
|
| 214 |
+
background: linear-gradient(180deg, rgba(30,37,48,0.92), rgba(22,27,34,0.96));
|
| 215 |
+
box-shadow: inset 0 1px 0 rgba(255,255,255,0.04), 0 18px 60px rgba(0,0,0,0.22);
|
| 216 |
+
}
|
| 217 |
+
|
| 218 |
+
.panel {
|
| 219 |
+
padding: 22px;
|
| 220 |
+
}
|
| 221 |
+
|
| 222 |
+
.card {
|
| 223 |
+
padding: 18px;
|
| 224 |
+
}
|
| 225 |
+
|
| 226 |
+
.chip {
|
| 227 |
+
display: inline-grid;
|
| 228 |
+
place-items: center;
|
| 229 |
+
min-height: 34px;
|
| 230 |
+
padding: 0 12px;
|
| 231 |
+
color: var(--cyan);
|
| 232 |
+
font-family: "Fira Code", monospace;
|
| 233 |
+
font-size: 15px;
|
| 234 |
+
font-weight: 600;
|
| 235 |
+
text-transform: uppercase;
|
| 236 |
+
white-space: nowrap;
|
| 237 |
+
}
|
| 238 |
+
|
| 239 |
+
.chip.confirmed {
|
| 240 |
+
color: var(--amber);
|
| 241 |
+
border-color: var(--amber);
|
| 242 |
+
background: rgba(232,163,61,0.12);
|
| 243 |
+
}
|
| 244 |
+
|
| 245 |
+
.chip.pending {
|
| 246 |
+
color: var(--text-muted);
|
| 247 |
+
border-color: rgba(156,163,175,0.36);
|
| 248 |
+
background: rgba(156,163,175,0.08);
|
| 249 |
+
}
|
| 250 |
+
|
| 251 |
+
.pillars {
|
| 252 |
+
display: grid;
|
| 253 |
+
grid-template-columns: repeat(3, 1fr);
|
| 254 |
+
gap: 18px;
|
| 255 |
+
}
|
| 256 |
+
|
| 257 |
+
.pillar {
|
| 258 |
+
display: grid;
|
| 259 |
+
gap: 12px;
|
| 260 |
+
min-height: 138px;
|
| 261 |
+
}
|
| 262 |
+
|
| 263 |
+
.pillar p {
|
| 264 |
+
color: var(--text-muted);
|
| 265 |
+
font-size: 18px;
|
| 266 |
+
}
|
| 267 |
+
|
| 268 |
+
.mono {
|
| 269 |
+
font-family: "Fira Code", monospace;
|
| 270 |
+
}
|
| 271 |
+
|
| 272 |
+
.stat {
|
| 273 |
+
color: var(--amber);
|
| 274 |
+
font-family: "Fira Code", monospace;
|
| 275 |
+
font-size: 54px;
|
| 276 |
+
font-weight: 600;
|
| 277 |
+
line-height: 1;
|
| 278 |
+
}
|
| 279 |
+
|
| 280 |
+
.subtle {
|
| 281 |
+
color: var(--text-muted);
|
| 282 |
+
}
|
| 283 |
+
|
| 284 |
+
.caption {
|
| 285 |
+
color: var(--text-muted);
|
| 286 |
+
font-family: "Fira Code", monospace;
|
| 287 |
+
font-size: 13px;
|
| 288 |
+
line-height: 1.45;
|
| 289 |
+
}
|
| 290 |
+
|
| 291 |
+
.diagram-wrap {
|
| 292 |
+
display: grid;
|
| 293 |
+
grid-template-rows: minmax(0, 1fr) auto;
|
| 294 |
+
gap: 16px;
|
| 295 |
+
height: 100%;
|
| 296 |
+
min-height: 0;
|
| 297 |
+
}
|
| 298 |
+
|
| 299 |
+
.architecture {
|
| 300 |
+
width: 100%;
|
| 301 |
+
height: 100%;
|
| 302 |
+
min-height: 420px;
|
| 303 |
+
display: block;
|
| 304 |
+
}
|
| 305 |
+
|
| 306 |
+
.demo-grid {
|
| 307 |
+
display: grid;
|
| 308 |
+
grid-template-columns: 1.42fr 0.9fr;
|
| 309 |
+
gap: 22px;
|
| 310 |
+
align-items: stretch;
|
| 311 |
+
min-height: 0;
|
| 312 |
+
}
|
| 313 |
+
|
| 314 |
+
.screen {
|
| 315 |
+
position: relative;
|
| 316 |
+
overflow: hidden;
|
| 317 |
+
min-height: 0;
|
| 318 |
+
padding: 22px;
|
| 319 |
+
}
|
| 320 |
+
|
| 321 |
+
.screen::before {
|
| 322 |
+
content: "";
|
| 323 |
+
position: absolute;
|
| 324 |
+
inset: 0;
|
| 325 |
+
background:
|
| 326 |
+
linear-gradient(rgba(255,255,255,0.035) 1px, transparent 1px),
|
| 327 |
+
linear-gradient(90deg, rgba(255,255,255,0.035) 1px, transparent 1px);
|
| 328 |
+
background-size: 24px 24px;
|
| 329 |
+
pointer-events: none;
|
| 330 |
+
}
|
| 331 |
+
|
| 332 |
+
.mock-shell {
|
| 333 |
+
position: relative;
|
| 334 |
+
z-index: 1;
|
| 335 |
+
display: grid;
|
| 336 |
+
grid-template-columns: 1.5fr 0.82fr;
|
| 337 |
+
gap: 16px;
|
| 338 |
+
height: 100%;
|
| 339 |
+
}
|
| 340 |
+
|
| 341 |
+
.mock-viewport,
|
| 342 |
+
.mock-panel {
|
| 343 |
+
border: 1px solid rgba(95,212,208,0.28);
|
| 344 |
+
background: rgba(15,19,24,0.72);
|
| 345 |
+
}
|
| 346 |
+
|
| 347 |
+
.mock-viewport {
|
| 348 |
+
position: relative;
|
| 349 |
+
min-height: 0;
|
| 350 |
+
overflow: hidden;
|
| 351 |
+
}
|
| 352 |
+
|
| 353 |
+
.mock-viewport svg {
|
| 354 |
+
position: absolute;
|
| 355 |
+
inset: 18px;
|
| 356 |
+
width: calc(100% - 36px);
|
| 357 |
+
height: calc(100% - 36px);
|
| 358 |
+
}
|
| 359 |
+
|
| 360 |
+
.mock-panel {
|
| 361 |
+
display: grid;
|
| 362 |
+
grid-template-rows: auto auto 1fr;
|
| 363 |
+
gap: 12px;
|
| 364 |
+
padding: 16px;
|
| 365 |
+
}
|
| 366 |
+
|
| 367 |
+
.mock-title {
|
| 368 |
+
color: var(--cyan);
|
| 369 |
+
font-size: 22px;
|
| 370 |
+
font-weight: 700;
|
| 371 |
+
line-height: 1;
|
| 372 |
+
text-transform: uppercase;
|
| 373 |
+
}
|
| 374 |
+
|
| 375 |
+
.mock-line {
|
| 376 |
+
height: 9px;
|
| 377 |
+
background: rgba(200,192,172,0.2);
|
| 378 |
+
}
|
| 379 |
+
|
| 380 |
+
.compare {
|
| 381 |
+
display: grid;
|
| 382 |
+
gap: 14px;
|
| 383 |
+
}
|
| 384 |
+
|
| 385 |
+
.compare-row {
|
| 386 |
+
display: grid;
|
| 387 |
+
grid-template-columns: 0.86fr 1.14fr;
|
| 388 |
+
gap: 16px;
|
| 389 |
+
align-items: stretch;
|
| 390 |
+
}
|
| 391 |
+
|
| 392 |
+
.compare-row > div {
|
| 393 |
+
border: 1px solid rgba(95,212,208,0.22);
|
| 394 |
+
padding: 15px;
|
| 395 |
+
background: rgba(15,19,24,0.52);
|
| 396 |
+
}
|
| 397 |
+
|
| 398 |
+
.compare-row b {
|
| 399 |
+
display: block;
|
| 400 |
+
margin-bottom: 6px;
|
| 401 |
+
color: var(--amber);
|
| 402 |
+
font-size: 17px;
|
| 403 |
+
text-transform: uppercase;
|
| 404 |
+
}
|
| 405 |
+
|
| 406 |
+
.compare-row span {
|
| 407 |
+
color: var(--text);
|
| 408 |
+
font-size: 18px;
|
| 409 |
+
line-height: 1.25;
|
| 410 |
+
}
|
| 411 |
+
|
| 412 |
+
.stack-list {
|
| 413 |
+
display: grid;
|
| 414 |
+
gap: 11px;
|
| 415 |
+
}
|
| 416 |
+
|
| 417 |
+
.stack-list li {
|
| 418 |
+
margin: 0;
|
| 419 |
+
color: var(--text-muted);
|
| 420 |
+
font-family: "Fira Code", monospace;
|
| 421 |
+
font-size: 15px;
|
| 422 |
+
line-height: 1.35;
|
| 423 |
+
}
|
| 424 |
+
|
| 425 |
+
.badge-grid {
|
| 426 |
+
display: flex;
|
| 427 |
+
flex-wrap: wrap;
|
| 428 |
+
gap: 10px;
|
| 429 |
+
align-content: start;
|
| 430 |
+
}
|
| 431 |
+
|
| 432 |
+
.closing-links {
|
| 433 |
+
display: grid;
|
| 434 |
+
gap: 16px;
|
| 435 |
+
margin-top: 8px;
|
| 436 |
+
}
|
| 437 |
+
|
| 438 |
+
.link-row {
|
| 439 |
+
display: grid;
|
| 440 |
+
grid-template-columns: 160px minmax(0, 1fr);
|
| 441 |
+
gap: 16px;
|
| 442 |
+
align-items: baseline;
|
| 443 |
+
border-bottom: 1px solid rgba(95,212,208,0.2);
|
| 444 |
+
padding-bottom: 10px;
|
| 445 |
+
}
|
| 446 |
+
|
| 447 |
+
.link-row span {
|
| 448 |
+
color: var(--amber);
|
| 449 |
+
font-family: "Fira Code", monospace;
|
| 450 |
+
font-size: 14px;
|
| 451 |
+
text-transform: uppercase;
|
| 452 |
+
}
|
| 453 |
+
|
| 454 |
+
.link-row a,
|
| 455 |
+
.link-row p {
|
| 456 |
+
color: var(--cyan);
|
| 457 |
+
font-family: "Fira Code", monospace;
|
| 458 |
+
font-size: 16px;
|
| 459 |
+
line-height: 1.35;
|
| 460 |
+
text-decoration: none;
|
| 461 |
+
overflow-wrap: anywhere;
|
| 462 |
+
}
|
| 463 |
+
|
| 464 |
+
.reticle {
|
| 465 |
+
position: absolute;
|
| 466 |
+
right: 72px;
|
| 467 |
+
top: 92px;
|
| 468 |
+
width: 170px;
|
| 469 |
+
height: 170px;
|
| 470 |
+
border: 1px solid rgba(95,212,208,0.36);
|
| 471 |
+
border-radius: 50%;
|
| 472 |
+
opacity: 0.55;
|
| 473 |
+
}
|
| 474 |
+
|
| 475 |
+
.reticle::before,
|
| 476 |
+
.reticle::after {
|
| 477 |
+
content: "";
|
| 478 |
+
position: absolute;
|
| 479 |
+
background: rgba(95,212,208,0.42);
|
| 480 |
+
}
|
| 481 |
+
|
| 482 |
+
.reticle::before {
|
| 483 |
+
left: 50%;
|
| 484 |
+
top: -18px;
|
| 485 |
+
width: 1px;
|
| 486 |
+
height: calc(100% + 36px);
|
| 487 |
+
}
|
| 488 |
+
|
| 489 |
+
.reticle::after {
|
| 490 |
+
top: 50%;
|
| 491 |
+
left: -18px;
|
| 492 |
+
height: 1px;
|
| 493 |
+
width: calc(100% + 36px);
|
| 494 |
+
}
|
| 495 |
+
|
| 496 |
+
.scanline {
|
| 497 |
+
position: absolute;
|
| 498 |
+
left: 0;
|
| 499 |
+
right: 0;
|
| 500 |
+
top: 0;
|
| 501 |
+
height: 2px;
|
| 502 |
+
background: linear-gradient(90deg, transparent, var(--cyan), transparent);
|
| 503 |
+
opacity: 0.8;
|
| 504 |
+
animation: scan 7s ease-in-out infinite;
|
| 505 |
+
box-shadow: 0 0 18px rgba(95,212,208,0.72);
|
| 506 |
+
}
|
| 507 |
+
|
| 508 |
+
.reveal h1,
|
| 509 |
+
.reveal h2,
|
| 510 |
+
.reveal h3 {
|
| 511 |
+
margin: 0;
|
| 512 |
+
color: var(--text);
|
| 513 |
+
font-family: "Chakra Petch", "Aptos Display", sans-serif;
|
| 514 |
+
font-weight: 700;
|
| 515 |
+
letter-spacing: 0;
|
| 516 |
+
text-transform: uppercase;
|
| 517 |
+
text-shadow: none;
|
| 518 |
+
}
|
| 519 |
+
|
| 520 |
+
.reveal h1 {
|
| 521 |
+
max-width: 920px;
|
| 522 |
+
font-size: 54px;
|
| 523 |
+
line-height: 0.96;
|
| 524 |
+
}
|
| 525 |
+
|
| 526 |
+
.reveal h2 {
|
| 527 |
+
font-size: 38px;
|
| 528 |
+
line-height: 1.04;
|
| 529 |
+
}
|
| 530 |
+
|
| 531 |
+
.reveal h3 {
|
| 532 |
+
color: var(--cyan);
|
| 533 |
+
font-size: 22px;
|
| 534 |
+
line-height: 1.12;
|
| 535 |
+
}
|
| 536 |
+
|
| 537 |
+
.reveal p {
|
| 538 |
+
margin: 0;
|
| 539 |
+
color: var(--text);
|
| 540 |
+
font-size: 20px;
|
| 541 |
+
line-height: 1.38;
|
| 542 |
+
}
|
| 543 |
+
|
| 544 |
+
.reveal ul {
|
| 545 |
+
margin: 0;
|
| 546 |
+
padding: 0;
|
| 547 |
+
list-style: none;
|
| 548 |
+
}
|
| 549 |
+
|
| 550 |
+
.reveal li {
|
| 551 |
+
margin: 0 0 11px;
|
| 552 |
+
color: var(--text);
|
| 553 |
+
font-size: 19px;
|
| 554 |
+
line-height: 1.34;
|
| 555 |
+
}
|
| 556 |
+
|
| 557 |
+
.reveal .hook {
|
| 558 |
+
color: var(--amber);
|
| 559 |
+
font-size: 52px;
|
| 560 |
+
line-height: 1.02;
|
| 561 |
+
text-transform: none;
|
| 562 |
+
}
|
| 563 |
+
|
| 564 |
+
.reveal .positioning {
|
| 565 |
+
color: var(--amber);
|
| 566 |
+
font-size: 46px;
|
| 567 |
+
line-height: 1;
|
| 568 |
+
text-transform: uppercase;
|
| 569 |
+
}
|
| 570 |
+
|
| 571 |
+
@keyframes scan {
|
| 572 |
+
0%, 22% { transform: translateY(0); opacity: 0; }
|
| 573 |
+
28%, 58% { opacity: 1; }
|
| 574 |
+
70%, 100% { transform: translateY(100vh); opacity: 0; }
|
| 575 |
+
}
|
| 576 |
+
|
| 577 |
+
@media (max-width: 900px) {
|
| 578 |
+
.reveal .slides > section {
|
| 579 |
+
padding: 48px 34px 48px;
|
| 580 |
+
}
|
| 581 |
+
|
| 582 |
+
.hook,
|
| 583 |
+
.positioning {
|
| 584 |
+
font-size: 40px;
|
| 585 |
+
}
|
| 586 |
+
|
| 587 |
+
h1 {
|
| 588 |
+
font-size: 42px;
|
| 589 |
+
}
|
| 590 |
+
|
| 591 |
+
h2 {
|
| 592 |
+
font-size: 34px;
|
| 593 |
+
}
|
| 594 |
+
|
| 595 |
+
p,
|
| 596 |
+
li {
|
| 597 |
+
font-size: 18px;
|
| 598 |
+
}
|
| 599 |
+
|
| 600 |
+
.two-col,
|
| 601 |
+
.demo-grid,
|
| 602 |
+
.mock-shell,
|
| 603 |
+
.compare-row {
|
| 604 |
+
grid-template-columns: 1fr;
|
| 605 |
+
}
|
| 606 |
+
|
| 607 |
+
.pillars {
|
| 608 |
+
grid-template-columns: 1fr;
|
| 609 |
+
}
|
| 610 |
+
}
|
| 611 |
+
|
| 612 |
+
@media print {
|
| 613 |
+
body::before,
|
| 614 |
+
body::after,
|
| 615 |
+
.scanline {
|
| 616 |
+
display: none;
|
| 617 |
+
}
|
| 618 |
+
|
| 619 |
+
.reveal .slides > section {
|
| 620 |
+
background: var(--bg) !important;
|
| 621 |
+
}
|
| 622 |
+
}
|
| 623 |
+
</style>
|
| 624 |
+
</head>
|
| 625 |
+
<body>
|
| 626 |
+
<div class="reveal">
|
| 627 |
+
<div class="slides">
|
| 628 |
+
<section data-transition="fade">
|
| 629 |
+
<div class="scanline" aria-hidden="true"></div>
|
| 630 |
+
<div class="reticle" aria-hidden="true"></div>
|
| 631 |
+
<div class="kicker">01 / THE PROBLEM</div>
|
| 632 |
+
<div class="watermark">SNAP2SIM // INSIDE THE MACHINE</div>
|
| 633 |
+
<div class="slide-grid" style="grid-template-rows: auto auto 1fr;">
|
| 634 |
+
<div class="hook">"You find a small metal cylinder at a flea market. What is it? How does it work inside?"</div>
|
| 635 |
+
<div class="section-rule"></div>
|
| 636 |
+
<ul>
|
| 637 |
+
<li>Curious makers, repair hobbyists, thrift scavengers, and robotics students constantly hold <strong>mystery hardware</strong> and cannot see what is happening inside.</li>
|
| 638 |
+
<li>Existing image AI <strong>stops at a label</strong> - "this is a valve" - instead of answering the real question: <em>what moves, and why?</em></li>
|
| 639 |
+
<li>Teardowns, manuals, and exploded diagrams are scattered, intimidating, or do not exist for that exact part.</li>
|
| 640 |
+
</ul>
|
| 641 |
+
</div>
|
| 642 |
+
<aside class="notes">
|
| 643 |
+
Open with the flea-market object. The point is not recognition; it is curiosity about hidden motion.
|
| 644 |
+
</aside>
|
| 645 |
+
</section>
|
| 646 |
+
|
| 647 |
+
<section data-transition="fade">
|
| 648 |
+
<div class="scanline" aria-hidden="true"></div>
|
| 649 |
+
<div class="kicker">02 / THE SOLUTION</div>
|
| 650 |
+
<div class="watermark">SNAP2SIM // INSIDE THE MACHINE</div>
|
| 651 |
+
<div class="slide-grid" style="grid-template-rows: auto auto auto 1fr;">
|
| 652 |
+
<div class="positioning">Snap a photo. Watch the mechanism come alive.</div>
|
| 653 |
+
<p>Snap2Sim turns a single photo of a hardware component into a <strong>narrated, animated 3D mechanical cutaway</strong> - naming internal parts and showing hidden motion.</p>
|
| 654 |
+
<div class="pillars">
|
| 655 |
+
<div class="card pillar">
|
| 656 |
+
<span class="chip">[ identify ]</span>
|
| 657 |
+
<h3>Likely mechanism</h3>
|
| 658 |
+
<p>Confidence and mechanism type, not just a class name.</p>
|
| 659 |
+
</div>
|
| 660 |
+
<div class="card pillar">
|
| 661 |
+
<span class="chip">[ explain ]</span>
|
| 662 |
+
<h3>Plain-language motion</h3>
|
| 663 |
+
<p>Internal parts, trigger, and sequence: plunger, spring, rotor, pawl, port.</p>
|
| 664 |
+
</div>
|
| 665 |
+
<div class="card pillar">
|
| 666 |
+
<span class="chip">[ animate ]</span>
|
| 667 |
+
<h3>Orbit the cutaway</h3>
|
| 668 |
+
<p>Three.js field-manual view with orbit, zoom, reset, and play/pause.</p>
|
| 669 |
+
</div>
|
| 670 |
+
</div>
|
| 671 |
+
<p class="caption">Honesty is part of the product: when confident 3D reconstruction is not justified, Snap2Sim falls back to annotated callouts on the original photo instead of pretending.</p>
|
| 672 |
+
</div>
|
| 673 |
+
<aside class="notes">
|
| 674 |
+
Stress that the fallback is a feature, not a failure. The demo has a confidence threshold so uncertainty is visible and controllable.
|
| 675 |
+
</aside>
|
| 676 |
+
</section>
|
| 677 |
+
|
| 678 |
+
<section data-transition="fade">
|
| 679 |
+
<div class="kicker">03 / HOW IT WORKS</div>
|
| 680 |
+
<div class="watermark">SNAP2SIM // INSIDE THE MACHINE</div>
|
| 681 |
+
<div class="diagram-wrap">
|
| 682 |
+
<svg class="architecture" viewBox="0 0 1110 550" role="img" aria-labelledby="archTitle archDesc">
|
| 683 |
+
<title id="archTitle">Snap2Sim architecture flow</title>
|
| 684 |
+
<desc id="archDesc">Photo upload flows through the Hugging Face Space, Modal GPU endpoint, NVIDIA Nemotron with llama.cpp, JSON validation, and deterministic browser rendering, with low confidence going to an annotated-photo fallback.</desc>
|
| 685 |
+
<defs>
|
| 686 |
+
<filter id="glow" x="-30%" y="-30%" width="160%" height="160%">
|
| 687 |
+
<feGaussianBlur stdDeviation="3" result="coloredBlur"/>
|
| 688 |
+
<feMerge>
|
| 689 |
+
<feMergeNode in="coloredBlur"/>
|
| 690 |
+
<feMergeNode in="SourceGraphic"/>
|
| 691 |
+
</feMerge>
|
| 692 |
+
</filter>
|
| 693 |
+
<marker id="arrow" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
| 694 |
+
<path d="M 0 0 L 10 5 L 0 10 z" fill="#5FD4D0"/>
|
| 695 |
+
</marker>
|
| 696 |
+
</defs>
|
| 697 |
+
<rect x="6" y="6" width="1098" height="538" fill="rgba(15,19,24,0.58)" stroke="rgba(95,212,208,0.22)"/>
|
| 698 |
+
<g font-family="Fira Code, monospace" font-size="14" fill="#C8C0AC">
|
| 699 |
+
<g transform="translate(45 45)">
|
| 700 |
+
<rect width="210" height="78" rx="0" fill="#161B22" stroke="#E8A33D" stroke-width="2"/>
|
| 701 |
+
<text x="105" y="34" text-anchor="middle" fill="#E8A33D" font-weight="600">Photo upload</text>
|
| 702 |
+
<text x="105" y="56" text-anchor="middle" fill="#9CA3AF">component image</text>
|
| 703 |
+
</g>
|
| 704 |
+
<path d="M 255 84 C 302 84 302 84 346 84" stroke="#5FD4D0" stroke-width="2.4" fill="none" marker-end="url(#arrow)" filter="url(#glow)"/>
|
| 705 |
+
<text x="300" y="68" text-anchor="middle" fill="#5FD4D0" font-size="12">POST /analyze_image</text>
|
| 706 |
+
|
| 707 |
+
<g transform="translate(346 45)">
|
| 708 |
+
<rect width="250" height="78" fill="#161B22" stroke="#E8A33D" stroke-width="2"/>
|
| 709 |
+
<text x="125" y="30" text-anchor="middle" fill="#E8A33D" font-weight="600">Hugging Face Space</text>
|
| 710 |
+
<text x="125" y="52" text-anchor="middle" fill="#9CA3AF">gradio.Server / cpu-basic</text>
|
| 711 |
+
</g>
|
| 712 |
+
<path d="M 596 84 C 642 84 642 84 686 84" stroke="#5FD4D0" stroke-width="2.4" fill="none" marker-end="url(#arrow)" filter="url(#glow)"/>
|
| 713 |
+
<text x="640" y="68" text-anchor="middle" fill="#5FD4D0" font-size="12">bearer-token secret</text>
|
| 714 |
+
|
| 715 |
+
<g transform="translate(686 45)">
|
| 716 |
+
<rect width="210" height="78" fill="#161B22" stroke="#E8A33D" stroke-width="2"/>
|
| 717 |
+
<text x="105" y="30" text-anchor="middle" fill="#E8A33D" font-weight="600">Modal GPU endpoint</text>
|
| 718 |
+
<text x="105" y="52" text-anchor="middle" fill="#9CA3AF">llama.cpp + mtmd</text>
|
| 719 |
+
</g>
|
| 720 |
+
|
| 721 |
+
<path d="M 791 123 L 791 166" stroke="#5FD4D0" stroke-width="2.4" fill="none" marker-end="url(#arrow)" filter="url(#glow)"/>
|
| 722 |
+
<g transform="translate(626 166)">
|
| 723 |
+
<rect width="330" height="86" fill="#161B22" stroke="#E8A33D" stroke-width="2"/>
|
| 724 |
+
<text x="165" y="30" text-anchor="middle" fill="#E8A33D" font-weight="600">NVIDIA Nemotron 3 Nano Omni</text>
|
| 725 |
+
<text x="165" y="52" text-anchor="middle" fill="#9CA3AF">30B-A3B GGUF / UD-Q4_K_M</text>
|
| 726 |
+
<text x="165" y="72" text-anchor="middle" fill="#9CA3AF">mmproj-F16 returns JSON</text>
|
| 727 |
+
</g>
|
| 728 |
+
|
| 729 |
+
<path d="M 626 209 C 560 209 560 209 506 209" stroke="#5FD4D0" stroke-width="2.4" fill="none" marker-end="url(#arrow)" filter="url(#glow)"/>
|
| 730 |
+
<g transform="translate(246 166)">
|
| 731 |
+
<rect width="260" height="86" fill="#161B22" stroke="#E8A33D" stroke-width="2"/>
|
| 732 |
+
<text x="130" y="30" text-anchor="middle" fill="#E8A33D" font-weight="600">/generate_scene</text>
|
| 733 |
+
<text x="130" y="52" text-anchor="middle" fill="#9CA3AF">schema validation</text>
|
| 734 |
+
<text x="130" y="72" text-anchor="middle" fill="#9CA3AF">render-mode select</text>
|
| 735 |
+
</g>
|
| 736 |
+
|
| 737 |
+
<path d="M 376 252 L 376 314" stroke="#5FD4D0" stroke-width="2.4" fill="none" marker-end="url(#arrow)" filter="url(#glow)"/>
|
| 738 |
+
<g transform="translate(190 314)">
|
| 739 |
+
<rect width="372" height="92" fill="#161B22" stroke="#E8A33D" stroke-width="2"/>
|
| 740 |
+
<text x="186" y="34" text-anchor="middle" fill="#E8A33D" font-weight="600">Browser renders deterministic</text>
|
| 741 |
+
<text x="186" y="58" text-anchor="middle" fill="#9CA3AF">Three.js cutaway</text>
|
| 742 |
+
<text x="186" y="78" text-anchor="middle" fill="#9CA3AF">orbit / zoom / reset / play</text>
|
| 743 |
+
</g>
|
| 744 |
+
|
| 745 |
+
<path d="M 562 360 C 640 360 672 360 744 360" stroke="#5FD4D0" stroke-width="2.4" fill="none" marker-end="url(#arrow)" stroke-dasharray="8 8"/>
|
| 746 |
+
<text x="652" y="342" text-anchor="middle" fill="#5FD4D0" font-size="12">low confidence</text>
|
| 747 |
+
<g transform="translate(744 314)">
|
| 748 |
+
<rect width="250" height="92" fill="#161B22" stroke="rgba(156,163,175,0.65)" stroke-width="2"/>
|
| 749 |
+
<text x="125" y="35" text-anchor="middle" fill="#9CA3AF" font-weight="600">Annotated-photo</text>
|
| 750 |
+
<text x="125" y="59" text-anchor="middle" fill="#9CA3AF">fallback</text>
|
| 751 |
+
</g>
|
| 752 |
+
|
| 753 |
+
<g transform="translate(90 456)">
|
| 754 |
+
<rect width="930" height="42" fill="rgba(95,212,208,0.08)" stroke="rgba(95,212,208,0.28)"/>
|
| 755 |
+
<text x="465" y="27" text-anchor="middle" fill="#C8C0AC" font-size="16">
|
| 756 |
+
The model describes the mechanism. The browser owns the rendering.
|
| 757 |
+
</text>
|
| 758 |
+
</g>
|
| 759 |
+
</g>
|
| 760 |
+
</svg>
|
| 761 |
+
<p class="caption"><strong>No model-authored HTML/JS touches the page.</strong> The renderer consumes validated mechanism JSON, which keeps the live demo reliable and safe.</p>
|
| 762 |
+
</div>
|
| 763 |
+
<aside class="notes">
|
| 764 |
+
The important architectural decision is separation of concerns: Modal and Nemotron infer the mechanism, while trusted browser code renders it deterministically.
|
| 765 |
+
</aside>
|
| 766 |
+
</section>
|
| 767 |
+
|
| 768 |
+
<section data-transition="fade">
|
| 769 |
+
<div class="kicker">04 / LIVE DEMO</div>
|
| 770 |
+
<div class="watermark">SNAP2SIM // INSIDE THE MACHINE</div>
|
| 771 |
+
<div class="slide-grid" style="grid-template-rows: auto 1fr;">
|
| 772 |
+
<h2>The moment: photo in, cutaway out.</h2>
|
| 773 |
+
<div class="demo-grid">
|
| 774 |
+
<div class="screen" aria-label="In-theme product demo mockup">
|
| 775 |
+
<div class="mock-shell">
|
| 776 |
+
<div class="mock-viewport">
|
| 777 |
+
<svg viewBox="0 0 440 300" aria-hidden="true">
|
| 778 |
+
<rect x="0" y="0" width="440" height="300" fill="rgba(15,19,24,0.35)"/>
|
| 779 |
+
<g stroke="#5FD4D0" stroke-width="2" fill="none" opacity="0.7">
|
| 780 |
+
<circle cx="218" cy="150" r="88"/>
|
| 781 |
+
<line x1="218" y1="32" x2="218" y2="268"/>
|
| 782 |
+
<line x1="100" y1="150" x2="336" y2="150"/>
|
| 783 |
+
</g>
|
| 784 |
+
<g transform="translate(112 76)">
|
| 785 |
+
<rect x="38" y="54" width="166" height="52" fill="#1E2530" stroke="#E8A33D" stroke-width="3"/>
|
| 786 |
+
<circle cx="77" cy="80" r="30" fill="rgba(95,212,208,0.22)" stroke="#5FD4D0" stroke-width="4"/>
|
| 787 |
+
<rect x="160" y="36" width="26" height="88" fill="rgba(232,163,61,0.24)" stroke="#E8A33D" stroke-width="3"/>
|
| 788 |
+
<path d="M 184 80 C 218 52 236 108 270 80" stroke="#F07F5A" stroke-width="5"/>
|
| 789 |
+
</g>
|
| 790 |
+
<text x="34" y="270" fill="#9CA3AF" font-family="Fira Code" font-size="12">Drag to orbit / scroll to zoom</text>
|
| 791 |
+
<text x="270" y="88" fill="#5FD4D0" font-family="Fira Code" font-size="13">spring preload</text>
|
| 792 |
+
<text x="246" y="210" fill="#5FD4D0" font-family="Fira Code" font-size="13">sliding plunger</text>
|
| 793 |
+
</svg>
|
| 794 |
+
</div>
|
| 795 |
+
<div class="mock-panel">
|
| 796 |
+
<div class="chip confirmed">CUTAWAY READY</div>
|
| 797 |
+
<div class="mock-title">Piston Mechanism</div>
|
| 798 |
+
<div class="mono subtle">confidence 85%</div>
|
| 799 |
+
<div class="mock-line" style="width: 92%;"></div>
|
| 800 |
+
<div class="mock-line" style="width: 74%;"></div>
|
| 801 |
+
<div class="mock-line" style="width: 86%;"></div>
|
| 802 |
+
<div class="mock-line" style="width: 62%; background: rgba(95,212,208,0.28);"></div>
|
| 803 |
+
</div>
|
| 804 |
+
</div>
|
| 805 |
+
</div>
|
| 806 |
+
<div class="panel">
|
| 807 |
+
<h3>Judges should feel the handoff.</h3>
|
| 808 |
+
<ul>
|
| 809 |
+
<li>Upload a mystery part photo.</li>
|
| 810 |
+
<li>Watch analysis become named parts and motion.</li>
|
| 811 |
+
<li>Orbit, zoom, reset, and play/pause the deterministic scene.</li>
|
| 812 |
+
<li>Move the confidence slider and see fallback behavior stay honest.</li>
|
| 813 |
+
</ul>
|
| 814 |
+
</div>
|
| 815 |
+
</div>
|
| 816 |
+
</div>
|
| 817 |
+
<aside class="notes">
|
| 818 |
+
Drop in a valve, lock, pump, gear train, fan, or latch.
|
| 819 |
+
</aside>
|
| 820 |
+
</section>
|
| 821 |
+
|
| 822 |
+
<section data-transition="fade">
|
| 823 |
+
<div class="kicker">05 / DIFFERENTIATION</div>
|
| 824 |
+
<div class="watermark">SNAP2SIM // INSIDE THE MACHINE</div>
|
| 825 |
+
<div class="slide-grid" style="grid-template-rows: auto auto 1fr;">
|
| 826 |
+
<h2>Most image demos stop at a label.</h2>
|
| 827 |
+
<p>Snap2Sim answers the maker's next question: <em>what would I see if I cut this open?</em></p>
|
| 828 |
+
<div class="compare">
|
| 829 |
+
<div class="compare-row">
|
| 830 |
+
<div><b>Typical image demo</b><span>"This is a valve."</span></div>
|
| 831 |
+
<div><b>Snap2Sim</b><span>Likely mechanism, internal parts, trigger, and motion sequence.</span></div>
|
| 832 |
+
</div>
|
| 833 |
+
<div class="compare-row">
|
| 834 |
+
<div><b>Static output</b><span>Caption, chat answer, or generic class label.</span></div>
|
| 835 |
+
<div><b>Moving cutaway</b><span>Maps parts into a technical field-manual scene with animation.</span></div>
|
| 836 |
+
</div>
|
| 837 |
+
<div class="compare-row">
|
| 838 |
+
<div><b>Overconfident</b><span>Looks plausible even when geometry is unsupported.</span></div>
|
| 839 |
+
<div><b>Honest uncertainty</b><span>Confidence threshold plus annotated-photo fallback.</span></div>
|
| 840 |
+
</div>
|
| 841 |
+
<div class="compare-row">
|
| 842 |
+
<div><b>Default app shell</b><span>Generic chat or form UI.</span></div>
|
| 843 |
+
<div><b>Branded maker tool</b><span>Cutaway aesthetic, same-origin client calls, server-side secrets.</span></div>
|
| 844 |
+
</div>
|
| 845 |
+
</div>
|
| 846 |
+
</div>
|
| 847 |
+
<aside class="notes">
|
| 848 |
+
This is the Off-Brand angle: it feels like a purpose-built instrument, not a wrapper around a model response.
|
| 849 |
+
</aside>
|
| 850 |
+
</section>
|
| 851 |
+
|
| 852 |
+
<section data-transition="fade">
|
| 853 |
+
<div class="kicker">06 / TECH STACK + HACKATHON FIT</div>
|
| 854 |
+
<div class="watermark">SNAP2SIM // INSIDE THE MACHINE</div>
|
| 855 |
+
<div class="two-col" style="height: 100%;">
|
| 856 |
+
<div class="panel">
|
| 857 |
+
<h3>Stack</h3>
|
| 858 |
+
<ul class="stack-list">
|
| 859 |
+
<li>Frontend: plain index.html + CSS + JS served by gradio.Server.</li>
|
| 860 |
+
<li>Rendering: deterministic Three.js primitives: box, cylinder, cone, capsule, sphere, rod, gear, torus, spring.</li>
|
| 861 |
+
<li>Controls: OrbitControls, camera fitting, reset view, confidence threshold, annotated-photo fallback.</li>
|
| 862 |
+
<li>Model: NVIDIA Nemotron 3 Nano Omni 30B-A3B GGUF, UD-Q4_K_M + mmproj-F16.</li>
|
| 863 |
+
<li>Budget: ~30B total / ~3B active per MoE token, under the 32B single-model budget.</li>
|
| 864 |
+
<li>GPU: Modal with weights cached in a Modal Volume and bearer-token protection.</li>
|
| 865 |
+
<li>Contract: JSON schema validation before anything renders.</li>
|
| 866 |
+
</ul>
|
| 867 |
+
</div>
|
| 868 |
+
<div class="panel">
|
| 869 |
+
<h3>Badges we are claiming</h3>
|
| 870 |
+
<div class="badge-grid" style="margin-top: 18px;">
|
| 871 |
+
<span class="chip confirmed">Backyard AI / core fit</span>
|
| 872 |
+
<span class="chip confirmed">Llama Champion</span>
|
| 873 |
+
<span class="chip confirmed">NVIDIA Nemotron Quest</span>
|
| 874 |
+
<span class="chip confirmed">Modal Award</span>
|
| 875 |
+
<span class="chip confirmed">Off-Brand</span>
|
| 876 |
+
<span class="chip confirmed">OpenAI Codex</span>
|
| 877 |
+
<span class="chip pending">Best Demo / pending video</span>
|
| 878 |
+
<span class="chip pending">Sharing is Caring / pending post</span>
|
| 879 |
+
<span class="chip pending">Off the Grid / not claimed</span>
|
| 880 |
+
</div>
|
| 881 |
+
<p class="caption" style="margin-top: 22px;">Inference currently runs on Modal, so Off the Grid is intentionally not claimed.</p>
|
| 882 |
+
</div>
|
| 883 |
+
</div>
|
| 884 |
+
<aside class="notes">
|
| 885 |
+
Keep this factual. The strongest credibility points are the real Modal/Nemotron path, schema gate, deterministic renderer, and honest fallback.
|
| 886 |
+
</aside>
|
| 887 |
+
</section>
|
| 888 |
+
|
| 889 |
+
<section data-transition="fade">
|
| 890 |
+
<div class="scanline" aria-hidden="true"></div>
|
| 891 |
+
<div class="reticle" aria-hidden="true"></div>
|
| 892 |
+
<div class="kicker">07 / CLOSE</div>
|
| 893 |
+
<div class="watermark">SNAP2SIM // INSIDE THE MACHINE</div>
|
| 894 |
+
<div class="slide-grid" style="grid-template-rows: auto auto 1fr auto;">
|
| 895 |
+
<h1>Snap a photo. See inside the machine.</h1>
|
| 896 |
+
<p class="hook" style="font-size: 38px; max-width: 880px;">"You find a small metal cylinder at a flea market. What is it? How does it work inside?"</p>
|
| 897 |
+
<div class="panel closing-links">
|
| 898 |
+
<div class="link-row">
|
| 899 |
+
<span>GitHub</span>
|
| 900 |
+
<a href="https://github.com/Bigstonks1/Snap2Sim">https://github.com/Bigstonks1/Snap2Sim</a>
|
| 901 |
+
</div>
|
| 902 |
+
<div class="link-row">
|
| 903 |
+
<span>HF Space</span>
|
| 904 |
+
<p>https://huggingface.co/spaces/jasondo111/Snap2Sim<br><span class="subtle">Public submission Space; transfer to the Build Small org is still pending if required.</span></p>
|
| 905 |
+
</div>
|
| 906 |
+
<div class="link-row">
|
| 907 |
+
<span>Credit</span>
|
| 908 |
+
<p>Built by Jason Do with implementation assistance from OpenAI Codex.</p>
|
| 909 |
+
</div>
|
| 910 |
+
</div>
|
| 911 |
+
<p class="caption">Snap2Sim // Inside the Machine // Build Small Hackathon</p>
|
| 912 |
+
</div>
|
| 913 |
+
<aside class="notes">
|
| 914 |
+
End with the same hook. The product promise is short: snap a photo, see the hidden mechanism, and learn by looking inside.
|
| 915 |
+
</aside>
|
| 916 |
+
</section>
|
| 917 |
+
</div>
|
| 918 |
+
</div>
|
| 919 |
+
|
| 920 |
+
<script src="https://cdn.jsdelivr.net/npm/reveal.js@5/dist/reveal.js"></script>
|
| 921 |
+
<script src="https://cdn.jsdelivr.net/npm/reveal.js@5/plugin/notes/notes.js"></script>
|
| 922 |
+
<script>
|
| 923 |
+
Reveal.initialize({
|
| 924 |
+
hash: true,
|
| 925 |
+
controls: true,
|
| 926 |
+
progress: true,
|
| 927 |
+
center: false,
|
| 928 |
+
slideNumber: "c/t",
|
| 929 |
+
transition: "fade",
|
| 930 |
+
backgroundTransition: "fade",
|
| 931 |
+
width: 1440,
|
| 932 |
+
height: 810,
|
| 933 |
+
margin: 0.06,
|
| 934 |
+
plugins: [RevealNotes]
|
| 935 |
+
});
|
| 936 |
+
</script>
|
| 937 |
+
</body>
|
| 938 |
+
</html>
|