Design & motion system · v1
Mission control
on paper.
Every color, size and motion on the site comes from src/design/tokens.ts and src/design/motion.ts. Feature code may not hard-code values. npm run lint:tokens enforces it at build.
Color
Semantic roles, two themes. Contrast is computed live against paper; AA needs 4.5 for body text, 3 for large type and graphics.
--c-paper
Page background
#F3EEE4 · 1.00:1
--c-paper-raised
Cards, panels
#E9E2D3 · 1.12:1
--c-paper-sunk
Wells, code, inputs
#E2DACA · 1.20:1
--c-ink
Primary text and strokes
#1A1712 · 15.45:1
--c-ink-muted
Secondary text, labels (AA on paper)
#5C554A · 6.36:1
--c-ink-faint
Decorative only — never body text
#8F877A · 3.07:1
--c-signal
Accent for large type, lines, dots, focus
#D9481A · 3.71:1
--c-signal-ink
Accent for small text, primary button fill
#B23A12 · 5.18:1
--c-on-signal
Text on signal-ink fills
#F3EEE4 · 1.00:1
--c-teal
Secondary data series, live states
#1F5F5B · 6.38:1
--c-rule
Hairlines and borders
rgba(26, 23, 18, 0.14)
--c-grid
Drafting grid, minor
rgba(26, 23, 18, 0.055)
--c-grid-major
Drafting grid, major
rgba(26, 23, 18, 0.09)
--c-vellum
Translucent panels (chat, nav)
rgba(243, 238, 228, 0.94)
--c-scrim
Overlay behind dialogs
rgba(26, 23, 18, 0.35)
--c-glow
Dark-mode bloom on emphasis
rgba(217, 72, 26, 0.0)
--c-focus
Focus ring
#D9481A · 3.71:1
--c-term-bg
Terminal surface (always dark)
#0E0C0A · 16.88:1
--c-term-ink
Terminal text
#EFE8DA · 1.05:1
--c-term-accent
Terminal prompt and input echo
#FF6B3D · 2.45:1
Typography
Bricolage Grotesque (display), Instrument Sans (text), JetBrains Mono (data). Fluid scale: ratio 1.2 → 1.333 between 360 and 1440px.
Aa
display · 800 · -0.035em
Aa
text · 400–700
Aa
mono · 0.02em
Space, radius, elevation, blur, z-index, breakpoints
none
xs
sm
md
lg
xl
pill
z: base 0 · raised 10 · sticky 40 · nav 50 · orb 60 · overlay 70 · modal 80 · cursor 90 · boot 100
breakpoints: sm 480px · md 768px · lg 1024px · xl 1280px · 2xl 1536px
Motion tokens
Durations and easings. Click a curve to replay it. Meanings: entrance = ease.out, exit = ease.in, transition = ease.inOut, drawing = ease.plot.
Springs
Physics for feedback and panels. Pick a token, then tune it to feel the difference.
stagger: char 20ms · word 40ms · item 80ms · card 140ms — distance: entrance 24 · emphasisScale 1.04 · pressScale 0.96 · parallax 80 · tilt 8 · magnetic 0.35
<Reveal>
Entrance: rise + fade when scrolled into view. Reduced motion → 150ms crossfade.
<Reveal y={24} duration="slow" delay={i * stagger.item}>
<SplitText>
Units rise out of clipped lines. Screen readers get the intact string; animated spans are aria-hidden.
Kinetic type, accessible.
<Magnetic>
Pulls toward the pointer. Mouse only; inert on touch and under reduced motion.
<Parallax>
Layers drift against page scroll. Scroll the page to see the three layers separate.
<CountUp>
Counts when visible. Assistive tech reads only the final value.
<ScrollScene>
Pins a section with position: sticky and exposes 0→1 scroll progress as a MotionValue (works with Lenis, native and touch scrolling). The hero uses it to collapse the constellation; below, the same progress drives the SVG fallback while you scroll.
<ScrollScene length={1.3}>{(progress) => <Constellation progress={progress} />}</ScrollScene>
<Marquee>
Infinite ribbon; pauses on hover/focus; static when reduced.
<TiltCard>
Tilts toward the pointer with a moving glare. Flat on touch and reduced motion.
QUERY-87
Text-to-SQL Copilot
87%
<GlowCursor>
A reticle that reacts to content: data-cursor="link" grows it, data-cursor-label adds a word. Inputs keep the native caret. Mouse + full motion only.
<PageTransition>
Client navigations feed a new sheet: an ink wipe clears upward while content settles. Never runs on the first load (protects LCP).
<Skeleton>
Loading placeholder for the 3D scene and chat. Shimmer stops under reduced motion.
Controls
Buttons carry spring press feedback (scale 0.96) and cursor labels. Toggles use Radix semantics.