diff --git a/CLAUDE.md b/CLAUDE.md index a1748be..f1a9769 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -63,12 +63,14 @@ App lives in `apps/web`. Social media videos live in `apps/video` (Remotion, sta along the edge of an element, digits drifting off it; glow only on dark surfaces, on light ones just a few blue digits), `BitSeam` (lit top edge of a dark section), `BitGlow` (light following the pointer on `data-glow` surfaces). Reuse them instead of inventing new effects. -- The homepage is a guided story (`apps/web/src/components/story/`): it follows the questions a visitor has - (`story.chapters` in the content files). Each chapter ends with `NextChapter`, the next question as a link - that leads on; `StoryGuide` is the rail with one station per chapter and a travelling dot (a pill on - phones), and the header names the current question. Sections become chapters through `data-chapter` - (`Block` prop `chapter`). Where the visitor is, is computed in `src/domain/chapters.ts`. A new section - on the homepage needs a chapter and a question, or it breaks the thread. +- The homepage is one story with a visible thread (`apps/web/src/components/story/`). Every chapter opens + with one sentence from `story` in the content files; read one after the other they tell the way of a + project from the idea to the first email. `StoryThread` is one line down the whole page that draws itself + as the visitor scrolls: under each sentence it crosses the page, stands a figure on the line and continues + on the other side, with a glowing dot at its head. `Block` prop `chapter` gives a section its sentence and + figure; how much of the line is drawn is decided in `src/domain/thread.ts`. A new section on the homepage + needs a sentence that continues the story, or it breaks the thread. No rails, no "next question" links + (owner rejected both). - `DecodeText` is for monospaced text only; in proportional type the changing glyph widths make text jump. - Never put an in-view trigger on an element that clips itself away (clip-path): a fully clipped element never counts as visible. Observe an unclipped wrapper (see `BitWipe`). diff --git a/apps/web/app/[locale]/page.tsx b/apps/web/app/[locale]/page.tsx index 93a09c6..2774bb7 100644 --- a/apps/web/app/[locale]/page.tsx +++ b/apps/web/app/[locale]/page.tsx @@ -18,11 +18,10 @@ import { } from "@/src/components/illustrations/WebPresentation"; import { WorkShowcase } from "@/src/components/illustrations/WorkShowcase"; import { Reveal } from "@/src/components/Reveal"; -import { NextChapter } from "@/src/components/story/Chapter"; -import { StoryGuide } from "@/src/components/story/StoryGuide"; +import { StoryThread } from "@/src/components/story/StoryThread"; import { SwipeRow } from "@/src/components/SwipeRow"; import { contentFor } from "@/src/content"; -import type { ChapterId, SplitTitle } from "@/src/content/types"; +import type { SplitTitle } from "@/src/content/types"; import { DEFAULT_LOCALE, parseLocale } from "@/src/domain/locale"; import { languageAlternates, pathFor } from "@/src/domain/routes"; @@ -70,28 +69,11 @@ export default async function LandingPage({ params }: Props) { faq, } = content; - /** What makes a section a chapter, and the hand-over to the one after it. */ - const chapter = (id: ChapterId) => { - const at = story.chapters.findIndex((item) => item.id === id); - const own = story.chapters[at]; - const after = story.chapters[at + 1]; - return { - chapter: own && { id: own.id }, - next: after && { - id: after.id, - label: story.next, - question: after.question, - }, - }; - }; - const afterHello = chapter("hello").next; - return (
{hello.lead} @@ -119,14 +102,13 @@ export default async function LandingPage({ params }: Props) { {hello.careerLabel}
+ + {story} +
+ )}+ {story} +
+ {line} +
+ +