Platform
Built like it looks
The engineering under the brand: one source of truth, generated artifacts, budgets held.
How it's built
Source to shipped artifact, twice over
Two pipelines, once for design tokens flowing into the website, once for the identity mark flowing into generated assets. Both converge on website/public/, which holds no hand-authored files — everything there is copied or generated at build time.
From docs/ARCHITECTURE.md
What it's built with
The stack
The charter listed candidates; this is what shipped. Explicitly not adopted: Motion, GSAP, Lenis, @react-three/drei — the site’s motion vocabulary is deliberately small, and a dependency that exists to exceed it invites exceeding it.
From docs/adr/0007-website-stack.md
| Layer | Choice | Why |
|---|---|---|
| Framework | Next.js 16 (App Router), static export | Full HTML at the edge, Cloudflare Pages target, no server runtime to operate |
| UI | React 19 + TypeScript strict | `any` prohibited (website/CLAUDE.md) |
| Styling | Tailwind v4 consuming the generated token theme | Tokens are law (ADR-0001) |
| 3D | three + @react-three/fiber, lazily loaded, hero only | The one surface that earns WebGL; poster-first fallback |
| Scroll/reveal | CSS transitions + IntersectionObserver (~40 lines) | Token-driven timing, progressive-enhancement gate, zero dependency weight |
| Themes | next-themes | Pre-hydration attribute, system mode, persistence |
| Fonts | @fontsource-variable self-hosted | Determinism, no third-party requests (ADR-0005) |
From docs/adr/0007-website-stack.md
What it costs
Performance budgets
One performance principle governs the build: the page is complete before the enhancement arrives. The budget exists to keep the cinematic hero from ever being the reason the site feels slow.
From docs/PERFORMANCE.md
| Budget | Target | Scope | Status |
|---|---|---|---|
| LCP | < 1.8 s | Mid-tier mobile | TARGET — not yet measured on a live URL |
| First-load JS (gzip) | < 200 KB | Excludes the lazily-loaded 3D scene chunk | PASS — 198.3 KiB measured |
| CLS | < 0.02 | No layout shift from hero, fonts, or scroll reveal | TARGET — not yet measured on a live URL |
| Bundle | Gzip | Result |
|---|---|---|
| First-load JS, total (all chunks in index.html) | 198.3 KiB | PASS (thin margin — non-regression invariant) |
| Largest first-load chunk | 69.2 KiB | recorded |
| CSS | 5.8 KiB | recorded |
| Three.js/R3F hero chunk | 218.1 KiB, lazy | excluded by budget — behind next/dynamic, absent from index.html |
From docs/PERFORMANCE.md — production build, Next 16 (Turbopack) static export.
Why it's reproducible
Determinism principles
Hero scene RNG is seeded
iris-scene.tsx uses mulberry32(0x76e00e) — a fixed-seed PRNG — for lane angle jitter, per-particle radius/z offsets, and neighbor-link sampling. The same seed produces the same particle layout on every render and every build.
Token generation is byte-deterministic
tokens/build.mjs produces identical output for identical input — same key order, LF endings, no embedded timestamps — so re-running it is always safe and never produces a spurious diff.
Generated artifacts are committed alongside their sources
SVG masters, PNG/ICO exports, and the generated CSS/Tailwind token files are checked in next to the scripts that produce them. Regeneration is expected to be a no-op when sources haven’t changed — a generator that produces a different output for unchanged input is the defect, not the commit that captures it.
From docs/ARCHITECTURE.md §Determinism notes