// App — orchestrates the pipeline. // State: prompt (string), generated tokens (appended), current "step" (which stage is active), // progress within that stage (0..1). On step=5 completion, append sampled token and loop. const STAGE_DURATIONS = [1.4, 1.8, 3.2, 2.6, 2.2]; // seconds at 1× — attention + mlp are the "heavy" ones function App() { const [prompt, setPrompt] = React.useState('The machine dreams in'); const [generated, setGenerated] = React.useState([]); // array of {text, id} const [stage, setStage] = React.useState(0); // 0..4 const [progress, setProgress] = React.useState(0); // 0..1 const [playing, setPlaying] = React.useState(true); const [speed, setSpeed] = React.useState(1.0); const [temperature, setTemperature] = React.useState(0.9); const [helpOpen, setHelpOpen] = React.useState(false); const [helpStage, setHelpStage] = React.useState(0); const [autoScroll, setAutoScroll] = React.useState(() => { // Default ON. Respect explicit off-preference if the user has toggled it. try { const v = localStorage.getItem('tlv-autoscroll'); return v === null ? true : v === '1'; } catch { return true; } }); React.useEffect(() => { try { localStorage.setItem('tlv-autoscroll', autoScroll ? '1' : '0'); } catch {} }, [autoScroll]); const scrollContainerRef = React.useRef(null); const wasPlayingBeforeHelpRef = React.useRef(false); // Auto-pause while help is open; restore on close React.useEffect(() => { if (helpOpen) { wasPlayingBeforeHelpRef.current = playingRef.current; setPlaying(false); } else if (wasPlayingBeforeHelpRef.current) { setPlaying(true); wasPlayingBeforeHelpRef.current = false; } // eslint-disable-next-line react-hooks/exhaustive-deps }, [helpOpen]); // Tokenize prompt + generated const promptTokens = React.useMemo(() => toyTokenize(prompt), [prompt]); const allTokens = React.useMemo(() => [...promptTokens, ...generated], [promptTokens, generated]); const activeIdx = allTokens.length - 1; // we're always generating after the last token // Animation loop const lastTimeRef = React.useRef(performance.now()); const stageRef = React.useRef(stage); const progressRef = React.useRef(progress); const speedRef = React.useRef(speed); const playingRef = React.useRef(playing); const pendingTokenRef = React.useRef(null); stageRef.current = stage; progressRef.current = progress; speedRef.current = speed; playingRef.current = playing; React.useEffect(() => { let raf; const tick = (now) => { const dt = Math.min(0.1, (now - lastTimeRef.current) / 1000); lastTimeRef.current = now; if (playingRef.current) { const s = stageRef.current; const dur = STAGE_DURATIONS[s] || 1; let p = progressRef.current + (dt * speedRef.current) / dur; if (p >= 1) { // advance if (s < 4) { setStage(s + 1); setProgress(0); } else { // Completed full cycle — commit sampled token if (pendingTokenRef.current) { const tok = pendingTokenRef.current; pendingTokenRef.current = null; let h = 2166136261; for (let i = 0; i < tok.length; i++) { h ^= tok.charCodeAt(i); h = Math.imul(h, 16777619); } const id = Math.abs(h) % 50000; setGenerated((g) => { const next = [...g, { text: tok, id }]; return next.length > 24 ? next.slice(-24) : next; }); } setStage(0); setProgress(0); } } else { setProgress(p); } } else { // keep lastTime fresh while paused so unpause doesn't jump // (already updated above) } raf = requestAnimationFrame(tick); }; lastTimeRef.current = performance.now(); raf = requestAnimationFrame(tick); return () => cancelAnimationFrame(raf); }, []); const handleSample = React.useCallback((tok) => { pendingTokenRef.current = tok; }, []); const handleStep = () => { setPlaying(false); setProgress(1 - 0.001); setTimeout(() => { setProgress(0); setStage((s) => (s + 1) % 5); }, 50); }; const handleReset = () => { setGenerated([]); setStage(0); setProgress(0); setPlaying(true); }; // Page-level keyboard shortcuts — disabled when help overlay is open (it owns keys then) // and when user is typing in an input. React.useEffect(() => { if (helpOpen) return; // tour has the keys const onKey = (e) => { const t = e.target; if (t && (t.tagName === 'INPUT' || t.tagName === 'TEXTAREA' || t.isContentEditable)) return; // Ignore when any modifier is down — we don't want to hijack browser shortcuts if (e.metaKey || e.ctrlKey || e.altKey) return; if (e.key === ' ') { e.preventDefault(); setPlaying((p) => !p); } else if (e.key === 'ArrowRight' || e.key === '.') { e.preventDefault(); // step forward one stage setPlaying(false); setProgress(1 - 0.001); setTimeout(() => { setProgress(0); setStage((s) => (s + 1) % 5); }, 50); } else if (e.key === 'ArrowLeft' || e.key === ',') { e.preventDefault(); // step back one stage setPlaying(false); setStage((s) => (s - 1 + 5) % 5); setProgress(0); } else if (e.key === 'r' || e.key === 'R') { e.preventDefault(); handleReset(); } else if (e.key === 'f' || e.key === 'F') { e.preventDefault(); setAutoScroll((v) => !v); } else if (e.key === '?' || (e.shiftKey && e.key === '/')) { e.preventDefault(); setHelpStage(-1); setHelpOpen(true); } else if (e.key >= '1' && e.key <= '5') { e.preventDefault(); const idx = parseInt(e.key, 10) - 1; setStage(idx); setProgress(0); } }; window.addEventListener('keydown', onKey); return () => window.removeEventListener('keydown', onKey); }, [helpOpen]); const explainStage = React.useCallback((i) => { // Pipeline stages 0..4 → STAGE_INFO indices (residual-stream at idx 3 is an interstitial, so shift mlp/logits) const MAP = [0, 1, 2, 4, 5]; setHelpStage(MAP[i] ?? i); setHelpOpen(true); }, []); // Auto-scroll to active stage when enabled React.useEffect(() => { if (!autoScroll) return; const container = scrollContainerRef.current; if (!container) return; const key = ['stage-tokenize','stage-embed','stage-attention','stage-mlp','stage-logits'][stage]; const el = container.querySelector(`[data-help-target="${key}"]`); if (!el) return; const cr = container.getBoundingClientRect(); const er = el.getBoundingClientRect(); const target = container.scrollTop + (er.top - cr.top) - 12; container.scrollTo({ top: target, behavior: 'smooth' }); }, [stage, autoScroll]); // Layout return (
{ setPrompt(v); setGenerated([]); setStage(0); setProgress(0); }} playing={playing} onPlayToggle={() => setPlaying(p => !p)} onStep={handleStep} onReset={handleReset} speed={speed} onSpeedChange={setSpeed} temperature={temperature} onTempChange={setTemperature} tokenCount={allTokens.length} stepIdx={stage} progress={progress} onJumpStage={(i) => { setStage(i); setProgress(0); }} onHelp={() => { setHelpStage(-1); setHelpOpen(true); setPlaying(false); }} autoScroll={autoScroll} onAutoScrollToggle={() => setAutoScroll((v) => !v)} />
{/* left: pipeline stack */}
0 ? 1 : 0)} active={stage === 0} onExplain={() => explainStage(0)} />
1 ? 1 : 0)} active={stage === 1} onExplain={() => explainStage(1)} />
2 ? 1 : 0)} active={stage === 2} nHeads={8} onExplain={() => explainStage(2)} />
3 ? 1 : 0)} active={stage === 3} nLayers={32} onExplain={() => explainStage(3)} />
explainStage(4)} />
{/* right: narration + matrix rain backdrop */}
{ setHelpStage(3); setHelpOpen(true); }} />
setHelpOpen(false)} stageIdx={helpStage} setStageIdx={setHelpStage} />
); } // Subtle number-rain canvas — NOT recreating branded imagery; // just streaming decimals in our phosphor green aesthetic. Supports // two states: the default 160px corner, and an "expanded" state that // fills the viewport below the header (Esc closes). function RainBackdrop({ stage, progress, onExplain, tokens, stageRef, progressRef }) { const canvasRef = React.useRef(null); const containerRef = React.useRef(null); const colsRef = React.useRef([]); const [expanded, setExpanded] = React.useState(false); const [headerOffset, setHeaderOffset] = React.useState(64); // Measure the header (first grid row) so the expanded overlay leaves it // visible. Re-measure on window resize. React.useLayoutEffect(() => { const measure = () => { const header = document.querySelector('[data-app-header]'); if (header) setHeaderOffset(header.getBoundingClientRect().height); }; measure(); window.addEventListener('resize', measure); return () => window.removeEventListener('resize', measure); }, []); // Esc closes when expanded. Scope-aware so we don't hijack the tour or // inputs. Matches the pattern used elsewhere in app.jsx. React.useEffect(() => { if (!expanded) return; const onKey = (e) => { const t = e.target; if (t && (t.tagName === 'INPUT' || t.tagName === 'TEXTAREA' || t.isContentEditable)) return; if (e.key === 'Escape') { e.preventDefault(); setExpanded(false); } }; window.addEventListener('keydown', onKey); return () => window.removeEventListener('keydown', onKey); }, [expanded]); // Canvas rendering loop. ResizeObserver re-initializes on container size // change. Per-frame work scales down for larger canvases (fewer columns, // shorter trail, 30fps cap) so expanded mode doesn't feel sluggish. React.useEffect(() => { const canvas = canvasRef.current; if (!canvas) return; const ctx = canvas.getContext('2d'); const dpr = Math.min(2, window.devicePixelRatio || 1); let w = 0, h = 0; let fs = 11; let trail = 10; let frameIntervalMs = 0; // 0 = uncapped (60fps); non-zero = cap const COL_SPACING = 0.7; const init = () => { w = canvas.clientWidth; h = canvas.clientHeight; if (w === 0 || h === 0) return; // Heuristic: corner panel (≤ ~400px wide) runs dense + full-trail at // 60fps. Once expanded (viewport-width), we're drawing ~5x the pixels // so dial back: larger glyphs → fewer columns, shorter trail, 30fps cap. const isLarge = w > 500; fs = isLarge ? 14 : 11; trail = isLarge ? 6 : 10; frameIntervalMs = isLarge ? 33 : 0; // 30fps when expanded, 60fps when corner canvas.width = w * dpr; canvas.height = h * dpr; ctx.setTransform(1, 0, 0, 1, 0, 0); ctx.scale(dpr, dpr); const colCount = Math.floor(w / (fs * COL_SPACING)); colsRef.current = Array.from({ length: colCount }, () => ({ y: Math.random() * h, speed: 30 + Math.random() * 80, seed: Math.random() * 9999, })); }; init(); let raf, last = performance.now(); const draw = (now) => { const elapsed = now - last; // Frame cap: skip draws until we've accumulated enough real time. if (frameIntervalMs > 0 && elapsed < frameIntervalMs) { raf = requestAnimationFrame(draw); return; } const dt = elapsed / 1000; last = now; ctx.fillStyle = 'rgba(10,13,10,0.22)'; ctx.fillRect(0, 0, w, h); ctx.font = `${fs}px JetBrains Mono, monospace`; const cols = colsRef.current; // Pre-compute the per-trail alpha strings so we don't re-concatenate // inside the hot loop. for (let i = 0; i < cols.length; i++) { const c = cols[i]; c.y += c.speed * dt; if (c.y > h + 100) { c.y = -Math.random() * h; } const x = i * (fs * COL_SPACING) + 2; const ch = (Math.random() > 0.5 ? '+' : '-') + (Math.random() * 9.9).toFixed(1); ctx.fillStyle = 'rgba(170, 255, 190, 0.9)'; ctx.fillText(ch, x, c.y); for (let t = 1; t < trail; t++) { ctx.fillStyle = `rgba(120, 220, 150, ${0.14 - t * 0.012})`; const tch = (Math.random() > 0.5 ? '+' : '-') + (Math.random() * 9.9).toFixed(1); ctx.fillText(tch, x, c.y - t * fs); } } raf = requestAnimationFrame(draw); }; raf = requestAnimationFrame(draw); const ro = new ResizeObserver(() => init()); ro.observe(canvas); return () => { cancelAnimationFrame(raf); ro.disconnect(); }; }, []); const stageLabel = ['TOKENIZE','EMBED','ATTEND','MLP','SAMPLE'][stage]; const pct = (progress * 100).toFixed(0).padStart(2, '0'); // Reusable UI (same markup for both states — only container geometry changes) const chrome = ( <>
{onExplain && { e.stopPropagation(); onExplain(); }} />}
RESIDUAL·STREAM {stageLabel} · {pct}%
); // Two layers: an always-160px placeholder keeps the grid row stable, // and a position-aware inner container (same DOM element in both states // so the canvas stays mounted and ResizeObserver handles the dimension // change without re-initializing). const [hover, setHover] = React.useState(false); const hoverCue = hover && !expanded; const innerStyle = expanded ? { position: 'fixed', top: headerOffset, left: 0, right: 0, bottom: 0, background: 'rgba(10,13,10,0.98)', borderTop: '1px solid var(--line-strong)', overflow: 'hidden', zIndex: 80, // below help overlay (typically 999) cursor: 'zoom-out', animation: 'rain-expand-in 180ms ease-out', } : { position: 'absolute', inset: 0, border: `1px solid ${hoverCue ? 'color-mix(in oklch, var(--ink) 50%, transparent)' : 'var(--line)'}`, borderRadius: 8, overflow: 'hidden', background: 'rgba(0,0,0,0.5)', cursor: 'zoom-in', transition: 'border-color 180ms', boxShadow: hoverCue ? '0 0 0 1px color-mix(in oklch, var(--ink) 25%, transparent), 0 0 18px color-mix(in oklch, var(--ink) 15%, transparent)' : 'none', }; return (
{expanded && (
EXPANDED · ESC OR CLICK TO RETURN
)}
setExpanded(v => !v)} onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)} > {chrome} {/* 3D scene disabled for now; 2D rain canvas fills the expanded view. Flip this flag to bring it back. Code lives in src/scene-3d.jsx. */} {false && expanded && typeof window !== 'undefined' && window.ResidualScene ? : null} {hoverCue && (
↗ CLICK TO EXPAND
)}
); } // Small "?" chip matching the EXPLAIN buttons on each stage panel header. function ExplainChip({ onClick }) { const [hover, setHover] = React.useState(false); return ( ); } const root = ReactDOM.createRoot(document.getElementById('root')); root.render();