diff --git a/.gitignore b/.gitignore
index 87939b3..60643d5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
node_modules/
/frontend/dist/
.DS_Store
+/frontend-reference/
diff --git a/AGENTS.md b/AGENTS.md
index 203dd55..c95bccf 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -17,7 +17,8 @@ Ely GPUI Component. A component library for GPUI, in light and dark.
- Pictures: `image` 0.25 (MIT OR Apache-2.0), the crate gpui decodes with, default features off; it turns decoded frames and rims map tiles.
- Maps: Natural Earth's 110m countries (public domain). `assets/maps/countries.geojson`, trimmed by `scripts/countries.py` to an ISO code, a name and positions to 0.01°, backs `maps::WorldMap`; the gallery's tiles are cut from the same file, z0 to z3, by `scripts/tiles.py` with Pillow.
- Web: on wasm32, `web-time` 1.1 (MIT OR Apache-2.0) gives the `Instant` gpui's executor returns, std's own natively; jiff takes `js`, rust-embed `debug-embed`, similar `wasm32_web_time`. The gallery's web entry takes `gpui_web`, `wasm-bindgen`, `js-sys` and `web-sys` as wasm-only dev-dependencies, and a Hebrew cut of Noto Sans Hebrew 2.003 (OFL, `examples/gallery/fonts`): gpui_web asks the browser for emoji and CJK alone. The `wasm-bindgen` CLI at Cargo.lock's version and binaryen's `wasm-opt` finish the bundle.
-- Gallery: `examples/gallery`. Website: `frontend/` (Vite 8.3, pnpm 11, TypeScript, no framework): a home page in motion with three.js 0.186 and Lenis 1.3, and a components page with chapters on the left and the chosen story on the right, after astryx.atmeta.com and gpui-kit.com. Each story runs live from the gallery built for wasm32 through gpui_web, in a same-origin iframe, never as a screenshot. Geist and Geist Mono (OFL, `@fontsource-variable`), Reicon icons (MIT, based on Solar Icons, CC BY 4.0, credited in the footer), simple-icons' GitHub mark (CC0). It deploys to Cloudflare Workers static assets through `npx wrangler` (4.143).
+- Gallery: `examples/gallery`. Website: `frontend/` (Vite 8.3, pnpm 11, TypeScript, React 19.3, TanStack Router 1.170 in code-based routes, Lenis 1.3), after `frontend-reference/`: heavy titles over thin faint text, hairlines, one accent, full-screen sections, isometric line miniatures on a canvas. Each story runs live from the gallery built for wasm32 through gpui_web, in a same-origin iframe, never as a screenshot. Geist and Geist Mono (OFL, `@fontsource-variable`), Reicon icons (MIT, based on Solar Icons, CC BY 4.0, credited in the footer), simple-icons' GitHub mark (CC0). It deploys to Cloudflare Workers static assets through `npx wrangler` (4.143).
+- Reference site: `frontend-reference/` (Vite 8.3, React 19, TanStack Router 1.170 in code-based routes, `lottie-web` 5.13, pnpm 11). A 1:1 study copy of serro.ai: the SSR DOM and the site's own CSS ported verbatim, Framer custom components replayed from runtime DOM captured at five widths (`RuntimeVariant`), 17 Lottie instances on the original JSONs, and the mock's feed sequence, ROI count-up and hover pills reimplemented from measured timings. Real fonts and assets served locally. Not deployed. `NOTES.md` there documents the pipeline under `RECON/tools/`.
## Commands
@@ -27,6 +28,7 @@ Ely GPUI Component. A component library for GPUI, in light and dark.
- `RUSTC_BOOTSTRAP=1 cargo check --lib --target wasm32-unknown-unknown` checks the web build; gpui_web's `wasm_thread` needs the bootstrap, as Zed's web examples do.
- `ELY_GALLERY_ASSETS=
scripts/web.sh ` builds the gallery for the browser, profile `web`, and fails past Cloudflare's 25 MiB. It opens at `?page=&story=&theme=light|dark`; the host page calls `gallery.setTheme(mode)` or posts `{ ely: "theme", theme }`, before the wasm runs or after, and the page posts `{ ely: "ready" }` to its parent once it runs.
- In `frontend/`: `ELY_GALLERY_ASSETS=/gallery/assets/ pnpm gallery` builds the gallery into `public/gallery`, `pnpm dev` serves the site, `pnpm build` checks types and writes `dist`, `pnpm deploy` runs `wrangler deploy`. `node scripts/og.mjs`, with `pnpm preview` up, renders `public/og.png` from the hero. The site reads `examples/gallery/stories.json` for its chapters, stories and search.
+- In `frontend-reference/`: `pnpm dev` serves it, `pnpm build` checks types and writes `dist`. serro.ai 403s plain curl and headless Chromium; measure it with Playwright's Firefox. `sh RECON/tools/pipeline.sh` regenerates the clone from the captured artifacts.
- `python3 scripts/stories.py` writes `examples/gallery/stories.json`, every page's sections in drawing order with their components, for the site: the names in a title, and in its `SHOWN` table what a story draws beyond them. It fails on a section opened inside another and on a ticked entry with a home of its own that no story names. `scripts/check.sh` refuses a stale one.
- `cargo test --lib --features test-support`, `cargo clippy --all-targets --features test-support -- -D warnings`, `cargo fmt --check`. `scripts/check.sh` runs them with the house rules and lints the gallery for wasm32.
- `rm -rf target/debug/incremental` and `cargo clean -p ely-gpui-component` after each task item keep the disk lean. Cargo keeps every old build of the crate and its tests under a new hash; by T25 they had filled the disk.
diff --git a/TASKS.md b/TASKS.md
index 4086e37..c3b865f 100644
--- a/TASKS.md
+++ b/TASKS.md
@@ -154,7 +154,12 @@ Per-component lines live in `tasks/`. Tags there:
- [x] T44b Port · Build: gpui and gpui_platform from Zed's repo by git at 1a28cff; the crate, its tests and the gallery build, and check.sh passes
- [x] T44c Port · Parity: every page and scripted state captured light and dark and matched against T44a's shots; AGENTS.md's gpui 0.2.2 and taffy 0.9 rules re-tested at 1a28cff and rewritten
- [x] T44d Web · Stories: the gallery builds for wasm32 through gpui_web; one story per component, chosen by URL, themed by the host page; what cannot run in a browser says why
-- [ ] T45 Website: `frontend/`, Vite 8, pnpm, light and dark: a home page in motion (three.js, smooth scroll), and a components page with every component live from its story, categories on the left and the chosen one's detail on the right, after astryx.atmeta.com and gpui-kit.com; no screenshots
+- [ ] T45 Website: `frontend/` rebuilt after `frontend-reference/` (serro.ai's language: heavy titles, thin faint text, hairlines, one accent), Vite 8, pnpm, React 19, TanStack Router, light and dark; isometric line miniatures that grow cell by cell on a marimba beat; every story live, a native capture where a browser cannot run it; no box inside a box, no subheadings; run locally, not published
+- [ ] T45a Site · Stack: the old `frontend/` replaced by Vite 8, React 19 and TanStack Router under pnpm; routes `/`, `/components/`, `/components/$page/$story`; theme, fonts, the stories manifest
+- [ ] T45b Site · Iso: isometric line miniatures on a canvas, no perspective, hidden lines removed, cells growing on a sixteenth-note marimba beat, playable under the pointer, light and dark, still under reduced motion
+- [ ] T45c Site · Home: a full-screen hero and full-screen sections, each a miniature beside its live component, counts, the chapters as a city of plinths, a closing call; motion from scroll and route changes
+- [ ] T45d Site · Components: the chapter index and the story page redesigned; live stories without frames, native captures for what a browser cannot run, search, keys
+- [ ] T45e Site · Local: the gallery bundle built for localhost and the site served for the owner to see; not published
- [ ] T46 E2E: Playwright against the built site
- [ ] T47 Ship: GitHub repo (public), CI, Cloudflare deploy through `npx wrangler`
- [ ] T48 Acceptance: live URL and MVP checklist
diff --git a/frontend/index.html b/frontend/index.html
index 972e1cc..7044307 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -23,10 +23,7 @@
- Skip to content
-
-
-
-
+
+