Story
Two public marketing surfaces — the animated ad at /story and the scrollable page at /story-page — and the shared vocabulary they draw the same wordmark, buttons, and block card from.
Two screens, one source
/story and /story-page show the same content in two different media — a
timed animation and an ordinary scrollable page. Neither is a document
screen: both are public marketing surfaces with no auth gate, no Convex
reads, and no Convex writes. This page documents both together because they
share one set of presentational building blocks; a screen page per route
would restate the same wordmark and block-card contract twice.
Routes
| Screen | Route | Rendered by |
|---|---|---|
| Story (animated) | /story | src/app/routes/story.tsx → src/pages/story/ |
| Story page (scrollable) | /story-page | src/app/routes/story-page.tsx → src/pages/story-page/ |
Both are thin createFileRoute(...) shells with no route params, no search
params, and no layout parent beyond the app's root providers. Neither
requires an authenticated session — they are viewable cold, the way a public
marketing page must be.
Purpose
Goldie Blocks' pitch — find the right words every time, one block per fact,
one source of truth from chat to form to document — told as a short story
about Goldie Locks drafting a will. /story is built to eventually become
a recorded video export (its scene/timeline architecture exists for that
reason); /story-page is built to be linked, scrolled, and read at the
visitor's own pace, the way an ordinary marketing page is.
The retired manual Library-saving scene and its simulated shelf count were removed on 2026-09-09. No replacement membership or tagging interaction is shown; see the Library target.
Content, told twice
Both routes walk the same beats, from the same copy source
(plans/references/2026-08-15 goldie-blocks-ad.html, ported and verified
against /story's Storybook stories):
| Beat | Headline | What it shows |
|---|---|---|
| Hero / Open | "Find the right words every time." | Wordmark, tagline, primary CTA |
| Pillar 1 | "There's a block for every story." | Three blocks — too hot / too cold / just right — with Find/Edit/Create step labels |
| Pillar 2 | "There's two sides to every story." | A clause's two faces: the drafted text, and its block metadata |
| Pillar 3 | "There's many views, but only one truth." | Chat → Form → Document: one answer resolving a @name token everywhere it's referenced |
| Context | "Right words, right time." | Document → Chat → Block: a clause drafted from the matter's own facts |
| End | (wordmark repeat) | Wordmark, tagline, closing CTAs |
/story plays this as a click-to-play timed animation: one
scene visible at a time, rotating headline words, a 3D-flipping card, a
typewriter cursor. Its TIMELINE array
(src/pages/story/lib/timeline.ts) is the single ordered declaration of
scene order and beat timing, driven by a framework-free Clock sequencer —
kept deliberately DOM-free so the choreography could, one day, be recorded or
exported without rebuilding it (a Target, not built — see the archived
plan 2026-08-15-story-route-animated-ad's R6, "Video-ready structure").
prefers-reduced-motion scales the clock rather than only hiding CSS
transitions, so a reduced-motion visitor still reaches the end scene.
/story-page shows the same beats in normal document flow, each
beat's resolved, resting state — the frame /story's animation was
always driving toward — because a scrollable page has no "moment" to animate
through; the visitor supplies their own pace by scrolling. No timers, no
click-to-play gate, no JavaScript state machine. Its CTAs are real links
(/ to start using the app, /story to watch the animated version)
rather than replay buttons.
One source of truth
Both routes draw the wordmark, tagline, gold/ghost buttons, kicker/headline/ caption typography, and the real-block-styled card from the same three places, so a future change to any of them — the wordmark spelling, the gold token, the block's corner badge — updates both screens at once instead of drifting apart:
| Piece | Lives at | Why there |
|---|---|---|
Wordmark, Tagline, WORDMARK, WORDMARK_ACCENT_INDEX, TAGLINE, GoldButton, GhostButton, Kicker, Headline, Caption | src/shared/ui/molecules/story-marketing/ | No entity dependency — a shared/ molecule per UI Components |
StoryBlock (the real Stack/StackRow/GoldieGlyph composition, not a stylised lookalike) | src/widgets/story-block/ | Depends on #/entities/agent; shared/ may not import entities/, so a cross-page component built from an entity is a widget |
Everything that only makes sense mid-animation — SkipControl, RotatingWord, SceneFrame, the Clock/sequencer library, the live-typing PipelinePanel | src/pages/story/ (page-local) | /story-page has no timeline to drive them; it uses its own small static "pipeline panel" look built from the same tokens instead |
Every colour, font, radius, and shadow on both screens resolves through a
Counsel token — no hex literals, no bespoke font-family declarations. See
Tailwind for the token table; the ad-palette
mapping (gold accent, mono voice, block hot/cold borders with no Counsel
equivalent) is recorded in the archived plan 2026-08-15-story-route-animated-ad's
R3, "Map the ad palette onto Counsel tokens".
Reads and writes
Neither screen calls Convex. Both are pure client-rendered marketing content
with no sessions, documents, modules, or blocks footprint.
States
| State | /story | /story-page |
|---|---|---|
| Initial | Open scene only, Play button, everything else aria-hidden | Every section visible immediately, in document order |
| Mid-content | Exactly one scene active; Skip control advances it | N/A — everything is always visible; the visitor scrolls |
| Reduced motion | Clock delays scaled ×0.05; still reaches the end scene | N/A — nothing animates to begin with |
| Replay / re-visit | End scene's CTA resets every scene's state and plays again | N/A — a static page has no "replay"; reloading is the same page |
Key components
/story:StoryStagecomposes all nine scenes behindSceneFrametoggles, driven byuseStoryPlayer(src/pages/story/model/). The stage is a fixed 680×600 canvas thatuseStageScaleshrinks uniformly (transform: scale(...)) to letterbox short or narrow viewports — video-frame geometry, not a responsive redesign./story-page:StoryPagecomposes seven section components (hero-section.tsx…end-section.tsx) in ordinary responsive Tailwind layout (lg:breakpoint per Tailwind), each under 100 lines.
Related
- Plan (archived): the archived plan
2026-08-15-story-route-animated-ad— the animated ad as/story - Plan (archived): the archived plan
2026-08-16-story-page-scrollable-route— a scrollable web page at/story-page - Rules: UI Components, Tailwind, Storybook