Snap2Sim / presentation /deck.html
jasondo
Point deployment at Build Small Space
4755cbc
Raw
History Blame Contribute Delete
31.3 kB
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Snap2Sim // Inside the Machine</title>
<link rel="icon" href="data:,">
<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=Chakra+Petch:wght@400;500;600;700&family=Fira+Code:wght@400;500;600&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reveal.js@5/dist/reset.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reveal.js@5/dist/reveal.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reveal.js@5/dist/theme/black.css" id="theme">
<style>
:root {
--bg: #0F1318;
--bg-panel: #161B22;
--bg-lift: #1E2530;
--amber: #E8A33D;
--cyan: #5FD4D0;
--text: #C8C0AC;
--text-muted: #9CA3AF;
--danger: #F07F5A;
--grid: rgba(255,255,255,0.04);
--line: rgba(95,212,208,0.34);
--amber-line: rgba(232,163,61,0.45);
}
html,
body {
background: var(--bg);
}
body::before,
body::after {
content: "";
position: fixed;
inset: 0;
pointer-events: none;
z-index: 1;
}
body::before {
background:
linear-gradient(var(--grid) 1px, transparent 1px),
linear-gradient(90deg, var(--grid) 1px, transparent 1px);
background-size: 32px 32px;
opacity: 0.9;
}
body::after {
background:
radial-gradient(circle at 50% 42%, transparent 48%, rgba(0,0,0,0.52)),
linear-gradient(90deg, rgba(0,0,0,0.2), transparent 22%, transparent 78%, rgba(0,0,0,0.24));
mix-blend-mode: multiply;
}
.reveal {
color: var(--text);
font-family: "Chakra Petch", "Aptos", sans-serif;
letter-spacing: 0;
}
.reveal .slides {
text-align: left;
}
.reveal .slides > section {
height: 100%;
max-height: 100%;
overflow: hidden;
min-height: 100%;
padding: 50px 56px 46px;
box-sizing: border-box;
}
.slide-grid {
display: grid;
gap: 24px;
height: 100%;
min-height: 0;
}
.two-col {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
gap: 30px;
align-items: stretch;
}
.kicker {
position: absolute;
top: 26px;
left: 36px;
color: var(--amber);
font-family: "Fira Code", monospace;
font-size: 13px;
font-weight: 600;
letter-spacing: 0;
text-transform: uppercase;
}
.watermark {
position: absolute;
right: 34px;
bottom: 24px;
color: rgba(200,192,172,0.13);
font-family: "Fira Code", monospace;
font-size: 12px;
letter-spacing: 0;
text-transform: uppercase;
}
.section-rule {
height: 2px;
background: linear-gradient(90deg, transparent, var(--cyan), transparent);
box-shadow: 0 0 20px rgba(95,212,208,0.42);
}
h1,
h2,
h3 {
margin: 0;
color: var(--text);
font-family: "Chakra Petch", "Aptos Display", sans-serif;
font-weight: 700;
letter-spacing: 0;
text-transform: uppercase;
}
h1 {
max-width: 920px;
font-size: 54px;
line-height: 0.96;
}
h2 {
font-size: 38px;
line-height: 1.04;
}
h3 {
color: var(--cyan);
font-size: 22px;
line-height: 1.12;
}
.hook {
max-width: 960px;
color: var(--amber);
font-size: 52px;
font-weight: 700;
line-height: 1.02;
text-transform: none;
}
.positioning {
color: var(--amber);
font-size: 46px;
font-weight: 700;
line-height: 1;
text-transform: uppercase;
}
p {
margin: 0;
color: var(--text);
font-size: 20px;
line-height: 1.38;
}
strong {
color: var(--amber);
font-weight: 700;
}
em {
color: var(--cyan);
font-style: normal;
}
ul {
margin: 0;
padding: 0;
list-style: none;
}
li {
position: relative;
margin: 0 0 11px;
padding-left: 22px;
color: var(--text);
font-size: 19px;
line-height: 1.34;
}
li::before {
content: "";
position: absolute;
left: 0;
top: 0.58em;
width: 8px;
height: 8px;
border: 1px solid var(--cyan);
transform: rotate(45deg);
background: rgba(95,212,208,0.12);
}
.panel,
.card,
.chip,
.screen {
border: 1px solid var(--amber-line);
background: linear-gradient(180deg, rgba(30,37,48,0.92), rgba(22,27,34,0.96));
box-shadow: inset 0 1px 0 rgba(255,255,255,0.04), 0 18px 60px rgba(0,0,0,0.22);
}
.panel {
padding: 22px;
}
.card {
padding: 18px;
}
.chip {
display: inline-grid;
place-items: center;
min-height: 34px;
padding: 0 12px;
color: var(--cyan);
font-family: "Fira Code", monospace;
font-size: 15px;
font-weight: 600;
text-transform: uppercase;
white-space: nowrap;
}
.chip.confirmed {
color: var(--amber);
border-color: var(--amber);
background: rgba(232,163,61,0.12);
}
.chip.pending {
color: var(--text-muted);
border-color: rgba(156,163,175,0.36);
background: rgba(156,163,175,0.08);
}
.pillars {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 18px;
}
.pillar {
display: grid;
gap: 12px;
min-height: 138px;
}
.pillar p {
color: var(--text-muted);
font-size: 18px;
}
.mono {
font-family: "Fira Code", monospace;
}
.stat {
color: var(--amber);
font-family: "Fira Code", monospace;
font-size: 54px;
font-weight: 600;
line-height: 1;
}
.subtle {
color: var(--text-muted);
}
.caption {
color: var(--text-muted);
font-family: "Fira Code", monospace;
font-size: 13px;
line-height: 1.45;
}
.diagram-wrap {
display: grid;
grid-template-rows: minmax(0, 1fr) auto;
gap: 16px;
height: 100%;
min-height: 0;
}
.architecture {
width: 100%;
height: 100%;
min-height: 420px;
display: block;
}
.demo-grid {
display: grid;
grid-template-columns: 1.42fr 0.9fr;
gap: 22px;
align-items: stretch;
min-height: 0;
}
.screen {
position: relative;
overflow: hidden;
min-height: 0;
padding: 22px;
}
.screen::before {
content: "";
position: absolute;
inset: 0;
background:
linear-gradient(rgba(255,255,255,0.035) 1px, transparent 1px),
linear-gradient(90deg, rgba(255,255,255,0.035) 1px, transparent 1px);
background-size: 24px 24px;
pointer-events: none;
}
.mock-shell {
position: relative;
z-index: 1;
display: grid;
grid-template-columns: 1.5fr 0.82fr;
gap: 16px;
height: 100%;
}
.mock-viewport,
.mock-panel {
border: 1px solid rgba(95,212,208,0.28);
background: rgba(15,19,24,0.72);
}
.mock-viewport {
position: relative;
min-height: 0;
overflow: hidden;
}
.mock-viewport svg {
position: absolute;
inset: 18px;
width: calc(100% - 36px);
height: calc(100% - 36px);
}
.mock-panel {
display: grid;
grid-template-rows: auto auto 1fr;
gap: 12px;
padding: 16px;
}
.mock-title {
color: var(--cyan);
font-size: 22px;
font-weight: 700;
line-height: 1;
text-transform: uppercase;
}
.mock-line {
height: 9px;
background: rgba(200,192,172,0.2);
}
.compare {
display: grid;
gap: 14px;
}
.compare-row {
display: grid;
grid-template-columns: 0.86fr 1.14fr;
gap: 16px;
align-items: stretch;
}
.compare-row > div {
border: 1px solid rgba(95,212,208,0.22);
padding: 15px;
background: rgba(15,19,24,0.52);
}
.compare-row b {
display: block;
margin-bottom: 6px;
color: var(--amber);
font-size: 17px;
text-transform: uppercase;
}
.compare-row span {
color: var(--text);
font-size: 18px;
line-height: 1.25;
}
.stack-list {
display: grid;
gap: 11px;
}
.stack-list li {
margin: 0;
color: var(--text-muted);
font-family: "Fira Code", monospace;
font-size: 15px;
line-height: 1.35;
}
.badge-grid {
display: flex;
flex-wrap: wrap;
gap: 10px;
align-content: start;
}
.closing-links {
display: grid;
gap: 16px;
margin-top: 8px;
}
.link-row {
display: grid;
grid-template-columns: 160px minmax(0, 1fr);
gap: 16px;
align-items: baseline;
border-bottom: 1px solid rgba(95,212,208,0.2);
padding-bottom: 10px;
}
.link-row span {
color: var(--amber);
font-family: "Fira Code", monospace;
font-size: 14px;
text-transform: uppercase;
}
.link-row a,
.link-row p {
color: var(--cyan);
font-family: "Fira Code", monospace;
font-size: 16px;
line-height: 1.35;
text-decoration: none;
overflow-wrap: anywhere;
}
.reticle {
position: absolute;
right: 72px;
top: 92px;
width: 170px;
height: 170px;
border: 1px solid rgba(95,212,208,0.36);
border-radius: 50%;
opacity: 0.55;
}
.reticle::before,
.reticle::after {
content: "";
position: absolute;
background: rgba(95,212,208,0.42);
}
.reticle::before {
left: 50%;
top: -18px;
width: 1px;
height: calc(100% + 36px);
}
.reticle::after {
top: 50%;
left: -18px;
height: 1px;
width: calc(100% + 36px);
}
.scanline {
position: absolute;
left: 0;
right: 0;
top: 0;
height: 2px;
background: linear-gradient(90deg, transparent, var(--cyan), transparent);
opacity: 0.8;
animation: scan 7s ease-in-out infinite;
box-shadow: 0 0 18px rgba(95,212,208,0.72);
}
.reveal h1,
.reveal h2,
.reveal h3 {
margin: 0;
color: var(--text);
font-family: "Chakra Petch", "Aptos Display", sans-serif;
font-weight: 700;
letter-spacing: 0;
text-transform: uppercase;
text-shadow: none;
}
.reveal h1 {
max-width: 920px;
font-size: 54px;
line-height: 0.96;
}
.reveal h2 {
font-size: 38px;
line-height: 1.04;
}
.reveal h3 {
color: var(--cyan);
font-size: 22px;
line-height: 1.12;
}
.reveal p {
margin: 0;
color: var(--text);
font-size: 20px;
line-height: 1.38;
}
.reveal ul {
margin: 0;
padding: 0;
list-style: none;
}
.reveal li {
margin: 0 0 11px;
color: var(--text);
font-size: 19px;
line-height: 1.34;
}
.reveal .hook {
color: var(--amber);
font-size: 52px;
line-height: 1.02;
text-transform: none;
}
.reveal .positioning {
color: var(--amber);
font-size: 46px;
line-height: 1;
text-transform: uppercase;
}
@keyframes scan {
0%, 22% { transform: translateY(0); opacity: 0; }
28%, 58% { opacity: 1; }
70%, 100% { transform: translateY(100vh); opacity: 0; }
}
@media (max-width: 900px) {
.reveal .slides > section {
padding: 48px 34px 48px;
}
.hook,
.positioning {
font-size: 40px;
}
h1 {
font-size: 42px;
}
h2 {
font-size: 34px;
}
p,
li {
font-size: 18px;
}
.two-col,
.demo-grid,
.mock-shell,
.compare-row {
grid-template-columns: 1fr;
}
.pillars {
grid-template-columns: 1fr;
}
}
@media print {
body::before,
body::after,
.scanline {
display: none;
}
.reveal .slides > section {
background: var(--bg) !important;
}
}
</style>
</head>
<body>
<div class="reveal">
<div class="slides">
<section data-transition="fade">
<div class="scanline" aria-hidden="true"></div>
<div class="reticle" aria-hidden="true"></div>
<div class="kicker">01 / THE PROBLEM</div>
<div class="watermark">SNAP2SIM // INSIDE THE MACHINE</div>
<div class="slide-grid" style="grid-template-rows: auto auto 1fr;">
<div class="hook">"You find a small metal cylinder at a flea market. What is it? How does it work inside?"</div>
<div class="section-rule"></div>
<ul>
<li>Curious makers, repair hobbyists, thrift scavengers, and robotics students constantly hold <strong>mystery hardware</strong> and cannot see what is happening inside.</li>
<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>
<li>Teardowns, manuals, and exploded diagrams are scattered, intimidating, or do not exist for that exact part.</li>
</ul>
</div>
<aside class="notes">
Open with the flea-market object. The point is not recognition; it is curiosity about hidden motion.
</aside>
</section>
<section data-transition="fade">
<div class="scanline" aria-hidden="true"></div>
<div class="kicker">02 / THE SOLUTION</div>
<div class="watermark">SNAP2SIM // INSIDE THE MACHINE</div>
<div class="slide-grid" style="grid-template-rows: auto auto auto 1fr;">
<div class="positioning">Snap a photo. Watch the mechanism come alive.</div>
<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>
<div class="pillars">
<div class="card pillar">
<span class="chip">[ identify ]</span>
<h3>Likely mechanism</h3>
<p>Confidence and mechanism type, not just a class name.</p>
</div>
<div class="card pillar">
<span class="chip">[ explain ]</span>
<h3>Plain-language motion</h3>
<p>Internal parts, trigger, and sequence: plunger, spring, rotor, pawl, port.</p>
</div>
<div class="card pillar">
<span class="chip">[ animate ]</span>
<h3>Orbit the cutaway</h3>
<p>Three.js field-manual view with orbit, zoom, reset, and play/pause.</p>
</div>
</div>
<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>
</div>
<aside class="notes">
Stress that the fallback is a feature, not a failure. The demo has a confidence threshold so uncertainty is visible and controllable.
</aside>
</section>
<section data-transition="fade">
<div class="kicker">03 / HOW IT WORKS</div>
<div class="watermark">SNAP2SIM // INSIDE THE MACHINE</div>
<div class="diagram-wrap">
<svg class="architecture" viewBox="0 0 1110 550" role="img" aria-labelledby="archTitle archDesc">
<title id="archTitle">Snap2Sim architecture flow</title>
<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>
<defs>
<filter id="glow" x="-30%" y="-30%" width="160%" height="160%">
<feGaussianBlur stdDeviation="3" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
<marker id="arrow" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" fill="#5FD4D0"/>
</marker>
</defs>
<rect x="6" y="6" width="1098" height="538" fill="rgba(15,19,24,0.58)" stroke="rgba(95,212,208,0.22)"/>
<g font-family="Fira Code, monospace" font-size="14" fill="#C8C0AC">
<g transform="translate(45 45)">
<rect width="210" height="78" rx="0" fill="#161B22" stroke="#E8A33D" stroke-width="2"/>
<text x="105" y="34" text-anchor="middle" fill="#E8A33D" font-weight="600">Photo upload</text>
<text x="105" y="56" text-anchor="middle" fill="#9CA3AF">component image</text>
</g>
<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)"/>
<text x="300" y="68" text-anchor="middle" fill="#5FD4D0" font-size="12">POST /analyze_image</text>
<g transform="translate(346 45)">
<rect width="250" height="78" fill="#161B22" stroke="#E8A33D" stroke-width="2"/>
<text x="125" y="30" text-anchor="middle" fill="#E8A33D" font-weight="600">Hugging Face Space</text>
<text x="125" y="52" text-anchor="middle" fill="#9CA3AF">gradio.Server / cpu-basic</text>
</g>
<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)"/>
<text x="640" y="68" text-anchor="middle" fill="#5FD4D0" font-size="12">bearer-token secret</text>
<g transform="translate(686 45)">
<rect width="210" height="78" fill="#161B22" stroke="#E8A33D" stroke-width="2"/>
<text x="105" y="30" text-anchor="middle" fill="#E8A33D" font-weight="600">Modal GPU endpoint</text>
<text x="105" y="52" text-anchor="middle" fill="#9CA3AF">llama.cpp + mtmd</text>
</g>
<path d="M 791 123 L 791 166" stroke="#5FD4D0" stroke-width="2.4" fill="none" marker-end="url(#arrow)" filter="url(#glow)"/>
<g transform="translate(626 166)">
<rect width="330" height="86" fill="#161B22" stroke="#E8A33D" stroke-width="2"/>
<text x="165" y="30" text-anchor="middle" fill="#E8A33D" font-weight="600">NVIDIA Nemotron 3 Nano Omni</text>
<text x="165" y="52" text-anchor="middle" fill="#9CA3AF">30B-A3B GGUF / UD-Q4_K_M</text>
<text x="165" y="72" text-anchor="middle" fill="#9CA3AF">mmproj-F16 returns JSON</text>
</g>
<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)"/>
<g transform="translate(246 166)">
<rect width="260" height="86" fill="#161B22" stroke="#E8A33D" stroke-width="2"/>
<text x="130" y="30" text-anchor="middle" fill="#E8A33D" font-weight="600">/generate_scene</text>
<text x="130" y="52" text-anchor="middle" fill="#9CA3AF">schema validation</text>
<text x="130" y="72" text-anchor="middle" fill="#9CA3AF">render-mode select</text>
</g>
<path d="M 376 252 L 376 314" stroke="#5FD4D0" stroke-width="2.4" fill="none" marker-end="url(#arrow)" filter="url(#glow)"/>
<g transform="translate(190 314)">
<rect width="372" height="92" fill="#161B22" stroke="#E8A33D" stroke-width="2"/>
<text x="186" y="34" text-anchor="middle" fill="#E8A33D" font-weight="600">Browser renders deterministic</text>
<text x="186" y="58" text-anchor="middle" fill="#9CA3AF">Three.js cutaway</text>
<text x="186" y="78" text-anchor="middle" fill="#9CA3AF">orbit / zoom / reset / play</text>
</g>
<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"/>
<text x="652" y="342" text-anchor="middle" fill="#5FD4D0" font-size="12">low confidence</text>
<g transform="translate(744 314)">
<rect width="250" height="92" fill="#161B22" stroke="rgba(156,163,175,0.65)" stroke-width="2"/>
<text x="125" y="35" text-anchor="middle" fill="#9CA3AF" font-weight="600">Annotated-photo</text>
<text x="125" y="59" text-anchor="middle" fill="#9CA3AF">fallback</text>
</g>
<g transform="translate(90 456)">
<rect width="930" height="42" fill="rgba(95,212,208,0.08)" stroke="rgba(95,212,208,0.28)"/>
<text x="465" y="27" text-anchor="middle" fill="#C8C0AC" font-size="16">
The model describes the mechanism. The browser owns the rendering.
</text>
</g>
</g>
</svg>
<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>
</div>
<aside class="notes">
The important architectural decision is separation of concerns: Modal and Nemotron infer the mechanism, while trusted browser code renders it deterministically.
</aside>
</section>
<section data-transition="fade">
<div class="kicker">04 / LIVE DEMO</div>
<div class="watermark">SNAP2SIM // INSIDE THE MACHINE</div>
<div class="slide-grid" style="grid-template-rows: auto 1fr;">
<h2>The moment: photo in, cutaway out.</h2>
<div class="demo-grid">
<div class="screen" aria-label="In-theme product demo mockup">
<div class="mock-shell">
<div class="mock-viewport">
<svg viewBox="0 0 440 300" aria-hidden="true">
<rect x="0" y="0" width="440" height="300" fill="rgba(15,19,24,0.35)"/>
<g stroke="#5FD4D0" stroke-width="2" fill="none" opacity="0.7">
<circle cx="218" cy="150" r="88"/>
<line x1="218" y1="32" x2="218" y2="268"/>
<line x1="100" y1="150" x2="336" y2="150"/>
</g>
<g transform="translate(112 76)">
<rect x="38" y="54" width="166" height="52" fill="#1E2530" stroke="#E8A33D" stroke-width="3"/>
<circle cx="77" cy="80" r="30" fill="rgba(95,212,208,0.22)" stroke="#5FD4D0" stroke-width="4"/>
<rect x="160" y="36" width="26" height="88" fill="rgba(232,163,61,0.24)" stroke="#E8A33D" stroke-width="3"/>
<path d="M 184 80 C 218 52 236 108 270 80" stroke="#F07F5A" stroke-width="5"/>
</g>
<text x="34" y="270" fill="#9CA3AF" font-family="Fira Code" font-size="12">Drag to orbit / scroll to zoom</text>
<text x="270" y="88" fill="#5FD4D0" font-family="Fira Code" font-size="13">spring preload</text>
<text x="246" y="210" fill="#5FD4D0" font-family="Fira Code" font-size="13">sliding plunger</text>
</svg>
</div>
<div class="mock-panel">
<div class="chip confirmed">CUTAWAY READY</div>
<div class="mock-title">Piston Mechanism</div>
<div class="mono subtle">confidence 85%</div>
<div class="mock-line" style="width: 92%;"></div>
<div class="mock-line" style="width: 74%;"></div>
<div class="mock-line" style="width: 86%;"></div>
<div class="mock-line" style="width: 62%; background: rgba(95,212,208,0.28);"></div>
</div>
</div>
</div>
<div class="panel">
<h3>Judges should feel the handoff.</h3>
<ul>
<li>Upload a mystery part photo.</li>
<li>Watch analysis become named parts and motion.</li>
<li>Orbit, zoom, reset, and play/pause the deterministic scene.</li>
<li>Move the confidence slider and see fallback behavior stay honest.</li>
</ul>
</div>
</div>
</div>
<aside class="notes">
Drop in a valve, lock, pump, gear train, fan, or latch.
</aside>
</section>
<section data-transition="fade">
<div class="kicker">05 / DIFFERENTIATION</div>
<div class="watermark">SNAP2SIM // INSIDE THE MACHINE</div>
<div class="slide-grid" style="grid-template-rows: auto auto 1fr;">
<h2>Most image demos stop at a label.</h2>
<p>Snap2Sim answers the maker's next question: <em>what would I see if I cut this open?</em></p>
<div class="compare">
<div class="compare-row">
<div><b>Typical image demo</b><span>"This is a valve."</span></div>
<div><b>Snap2Sim</b><span>Likely mechanism, internal parts, trigger, and motion sequence.</span></div>
</div>
<div class="compare-row">
<div><b>Static output</b><span>Caption, chat answer, or generic class label.</span></div>
<div><b>Moving cutaway</b><span>Maps parts into a technical field-manual scene with animation.</span></div>
</div>
<div class="compare-row">
<div><b>Overconfident</b><span>Looks plausible even when geometry is unsupported.</span></div>
<div><b>Honest uncertainty</b><span>Confidence threshold plus annotated-photo fallback.</span></div>
</div>
<div class="compare-row">
<div><b>Default app shell</b><span>Generic chat or form UI.</span></div>
<div><b>Branded maker tool</b><span>Cutaway aesthetic, same-origin client calls, server-side secrets.</span></div>
</div>
</div>
</div>
<aside class="notes">
This is the Off-Brand angle: it feels like a purpose-built instrument, not a wrapper around a model response.
</aside>
</section>
<section data-transition="fade">
<div class="kicker">06 / TECH STACK + HACKATHON FIT</div>
<div class="watermark">SNAP2SIM // INSIDE THE MACHINE</div>
<div class="two-col" style="height: 100%;">
<div class="panel">
<h3>Stack</h3>
<ul class="stack-list">
<li>Frontend: plain index.html + CSS + JS served by gradio.Server.</li>
<li>Rendering: deterministic Three.js primitives: box, cylinder, cone, capsule, sphere, rod, gear, torus, spring.</li>
<li>Controls: OrbitControls, camera fitting, reset view, confidence threshold, annotated-photo fallback.</li>
<li>Model: NVIDIA Nemotron 3 Nano Omni 30B-A3B GGUF, UD-Q4_K_M + mmproj-F16.</li>
<li>Budget: ~30B total / ~3B active per MoE token, under the 32B single-model budget.</li>
<li>GPU: Modal with weights cached in a Modal Volume and bearer-token protection.</li>
<li>Contract: JSON schema validation before anything renders.</li>
</ul>
</div>
<div class="panel">
<h3>Badges we are claiming</h3>
<div class="badge-grid" style="margin-top: 18px;">
<span class="chip confirmed">Backyard AI / core fit</span>
<span class="chip confirmed">Llama Champion</span>
<span class="chip confirmed">NVIDIA Nemotron Quest</span>
<span class="chip confirmed">Modal Award</span>
<span class="chip confirmed">Off-Brand</span>
<span class="chip confirmed">OpenAI Codex</span>
<span class="chip pending">Best Demo / pending video</span>
<span class="chip pending">Sharing is Caring / pending post</span>
<span class="chip pending">Off the Grid / not claimed</span>
</div>
<p class="caption" style="margin-top: 22px;">Inference currently runs on Modal, so Off the Grid is intentionally not claimed.</p>
</div>
</div>
<aside class="notes">
Keep this factual. The strongest credibility points are the real Modal/Nemotron path, schema gate, deterministic renderer, and honest fallback.
</aside>
</section>
<section data-transition="fade">
<div class="scanline" aria-hidden="true"></div>
<div class="reticle" aria-hidden="true"></div>
<div class="kicker">07 / CLOSE</div>
<div class="watermark">SNAP2SIM // INSIDE THE MACHINE</div>
<div class="slide-grid" style="grid-template-rows: auto auto 1fr auto;">
<h1>Snap a photo. See inside the machine.</h1>
<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>
<div class="panel closing-links">
<div class="link-row">
<span>GitHub</span>
<a href="https://github.com/Bigstonks1/Snap2Sim">https://github.com/Bigstonks1/Snap2Sim</a>
</div>
<div class="link-row">
<span>HF Space</span>
<p>https://huggingface.co/spaces/build-small-hackathon/Snap2Sim<br><span class="subtle">Public submission Space under the Build Small Hackathon organization.</span></p>
</div>
<div class="link-row">
<span>Credit</span>
<p>Built by Jason Do with implementation assistance from OpenAI Codex.</p>
</div>
</div>
<p class="caption">Snap2Sim // Inside the Machine // Build Small Hackathon</p>
</div>
<aside class="notes">
End with the same hook. The product promise is short: snap a photo, see the hidden mechanism, and learn by looking inside.
</aside>
</section>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/reveal.js@5/dist/reveal.js"></script>
<script src="https://cdn.jsdelivr.net/npm/reveal.js@5/plugin/notes/notes.js"></script>
<script>
Reveal.initialize({
hash: true,
controls: true,
progress: true,
center: false,
slideNumber: "c/t",
transition: "fade",
backgroundTransition: "fade",
width: 1440,
height: 810,
margin: 0.06,
plugins: [RevealNotes]
});
</script>
</body>
</html>