<!-- source: openspec/current/home/blocks.md -->

---
title: Home — Block Contracts
status: stable
owner: pavel
audience: [pavel, ai, engineer]
tldr: Full per-block contracts for the homepage — Nav through Footer plus amendment deltas, with purpose, content, and visual rules each.
---
# Home — block contracts

## Nav

> Sticky top-of-page navigation. Studio mark, four destinations, primary CTA. Always visible, frosted-glass over scrolled content.

### Purpose

Persistent funnel access. A visitor scrolling through the page can jump to any of the four marketing destinations or fire the primary CTA without scrolling back to the hero. The bar is chrome, not content — it does not contribute to the page's narrative arc.

The nav is the only block that renders on every marketing page (Hero is homepage-only, Closing CTA repeats across marketing pages but is per-page; the nav is one component shared by all). Behavior must be identical across `/`, `/work`, `/services`, `/network`, `/lab`, `/contact`.

### Position in page narrative

Block 1. Renders above `## Hero` in the DOM, fixed-positioned so it stays in view as the page scrolls. It is not part of the scroll narrative — visitors do not "read" it on the way down. They notice it once on arrival, and reach for it when they want to jump.

The block immediately after is `Hero`. The nav has no semantic relationship to the hero beyond visual proximity at page top.

### Content contract

| Field | Required | Type | Source | Notes |
|---|---|---|---|---|
| `studioMark` | yes | string | `brand.studio` | Wordmark only — "Rapoport Studio". No logo glyph. Links to `/`. |
| `triggerServices` | yes | string | `nav.services` | Dropdown trigger. Renders `NavPanelGrouped` (5 engagement-shape items + 2 audience-framing items + featured). |
| `linkWork` | yes | string | `nav.work` | Anchor to `/work`. |
| `linkLab` | yes | string | `nav.lab` | Anchor to `/lab`. |
| `triggerAbout` | yes | string | `nav.about` | Dropdown trigger. Renders `NavPanelStructured` (Principles · Method · OpenSpec · Network + featured). |
| `startProject` | yes | string | `cta.startProject` | Primary CTA. Same key the hero and closing use. Trailing arrow is part of the string. |
| `signIn` | conditional | string | `nav.signIn` | Rendered only when no auth cookie is present. Anchor to `app.rapoport.studio` (cross-domain). |

Source of truth for nav IA is `apps/web/src/components/nav-config.ts` (`NAV_ENTRIES`). Full contract — primitive, active indicator, hover/keyboard, mobile drawer — see [`web.md § Primary nav contract`](../web.md). No search, no language switcher (lives in `Footer`), no user-menu beyond the conditional sign-in pill.

### Component composition

| Layer | Component | Path |
|---|---|---|
| Block | `<Nav />` (server component, async — calls `getTranslations` for `nav.*`, `cta.*`, `brand.*`) | `apps/web/src/components/nav.tsx` |
| Sticky scroll wrapper | `<NavScrollWrapper>` (client component — owns scroll-position state, applies the `bg-canvas/80 backdrop-blur` and divider transitions past 24px) | `apps/web/src/components/nav-scroll-wrapper.tsx` |
| Dropdown primitive | `<NavigationMenu>` + `<NavPanelGrouped>` + `<NavPanelStructured>` (vendored Radix; renders Services + About panels) | `@rapoport-studio/ui/composed/navigation-menu` |
| Nav IA configuration | `NAV_ENTRIES` (single source of truth for top-level entries, panel items, audience framings) | `apps/web/src/components/nav-config.ts` |
| Mobile drawer | `<NavMobileDrawer>` (client component — renders the hamburger toggle + full-screen `<dialog>` overlay; no third-party library) | `apps/web/src/components/nav-mobile-drawer.tsx` |
| Mobile drawer links | `<NavMobileLinks>` (client island — owns the `<details>` accordion state driven by `usePathname()`) | `apps/web/src/components/nav-mobile-links.tsx` |
| Locale-aware links | `<Link>` | `@rapoport-studio/i18n/navigation` |
| Sign-in pill | conditional render based on `getCloudflareContext()` cookie read | inline in `nav.tsx` |

The nav is reused on every marketing page. The split is functional, not aesthetic: `nav.tsx` owns content + i18n; `nav-scroll-wrapper.tsx` owns the scroll-state-driven background transition (must be a client component because it reads `window.scrollY`); `nav-mobile-drawer.tsx` owns the responsive drawer state. All three live at `components/` root (not under `home/`) because they are reused on every marketing page. Locale switching lives in `<LocaleSwitcher>` (`components/locale-switcher.tsx`), consumed by the footer — see the Footer block § Component composition.

### Visual contract

**Bar.** `fixed top-0 inset-x-0 z-50 h-[64px]`. Background transitions from `bg-transparent` at scroll-y 0 to `bg-canvas/80 backdrop-blur` past 24px. Border `border-b border-grid` (0.5px) appears on the same threshold. Max-width inside the bar matches `max-w-page` (1200px) with the standard gutter.

**Studio mark.** `font-serif font-medium text-base text-ink`. No icon, no glyph — wordmark only. Hover transitions to `text-ink-light` (120ms).

**Links.** `font-mono text-xs uppercase tracking-[0.15em] text-ink-light`. Hover transitions to `text-ink` (120ms). Spacing: 32px gap on desktop. No underline at any state.

**Primary CTA.** Identical to Hero primary CTA: `bg-ink text-canvas border border-ink px-4 py-2 font-mono text-xs uppercase tracking-[0.15em]`. Sharp corners (radius 0). One source of truth shared with Hero and Closing CTA.

**Sign-in pill.** `text-ink-light font-mono text-xs uppercase tracking-[0.15em] border-b border-transparent hover:border-ink-light pb-1`. Ghost variant — no background, no border-box. Sits to the right of the primary CTA.

**Forbidden in this block.** No shadow, no rounded corners, no gradient, no logo glyph, no colored icons, no background fill at scroll-y 0 (purely transparent until scroll). No raw hex (always tokens).

### Motion contract

| Phase | Trigger | What animates |
|---|---|---|
| Background appearance | scroll-y crosses 24px | `bg-transparent` → `bg-canvas/80 backdrop-blur`, 200ms `--ease-settle`. Grid divider fades in over the same window. |
| Background disappearance | scroll-y returns below 24px | reverse, same 200ms. |
| Mobile drawer open | hamburger click | `<dialog>` slide-down from top, 240ms `--ease-deploy`. Backdrop fades in concurrently. |
| Mobile drawer close | backdrop click / Escape / link click | reverse slide, 240ms. |
| Link hover | pointer enter | `text-ink-light` → `text-ink`, 120ms. |

**Reduced-motion fallback.** When `prefers-reduced-motion: reduce`: background and drawer state changes are instant; no transition timing applied. Hover color changes still apply (color-only, not transform).

### Responsive contract

| Breakpoint | Behavior |
|---|---|
| `< 768px` | Hamburger button replaces link list. Tapping opens a full-screen overlay drawer with the four links + primary CTA + sign-in (if anonymous) stacked vertically with 24px gap, centered. Drawer closes on backdrop tap, Escape, or link selection. |
| `≥ 768px` | Horizontal layout: studio mark left, four links centered, primary CTA + conditional sign-in right. All visible simultaneously. |
| `≥ 1200px` | Same layout, contents centered within `max-w-page` parent. |

Touch target on hamburger ≥ 44px (`p-3` minimum). Each link ≥ 44px tall via `py-3`. Primary CTA ≥ 44px tall.

### Accessibility contract

- The bar is `<header role="banner">`; the nav inside is `<nav aria-label="Primary">`.
- A skip-link `<a href="#hero">Skip to content</a>` precedes the nav in the DOM, visually hidden until focused (per WCAG 2.4.1).
- Hamburger is `<button aria-expanded aria-controls="primary-drawer">`; `aria-expanded` toggles between `true` / `false`.
- Mobile drawer is `<dialog id="primary-drawer">`. Opening traps focus inside; closing restores focus to the hamburger. Dismissable with `Escape` (browser default for `<dialog>`).
- Studio mark is `<a>` to `/`, focusable, with the standard 1px blueprint outline / 2px offset focus ring.
- Tab order: skip-link → studio mark → links (left-to-right) → primary CTA → sign-in (if rendered) → hamburger (mobile only).
- Conditional sign-in render does not change focus order (the element is fully removed from the DOM when not present, not visually hidden).
- Color contrast: ink/canvas, ink-light/canvas, and CTA contrast all meet AA at the 12px mono size; the CTA uses the same ink/canvas combination as Hero (>12:1 in dark mode).

### Localization

Ships in all three locales: `en` (default), `ru`, `ro`. All seven content fields are required in every catalog (sign-in label is required even if conditionally rendered).

Translation keys (chrome — shared across all marketing pages):
- `brand.studio`
- `nav.work`
- `nav.network`
- `nav.services`
- `nav.lab`
- `nav.signIn`
- `cta.startProject` (shared with `Hero`, `ClosingCTA`)

All keys above live in `common.json`, not in `web.json`. The nav is chrome shared across every marketing page; page-specific `web.json` keys never duplicate the nav surface.

### Out of scope

- **Language switcher.** Lives in the header right-cluster (`EN · RO · RU` glyphs) — see [`web.md § Header right-cluster contract`](../web.md). Not part of the linkset.
- **Search.** No search anywhere on the marketing site at v1.
- **User menu / account dropdown.** Beyond the binary sign-in pill, no account UI in marketing nav. Logged-in users live at `app.rapoport.studio` and don't return through marketing chrome.
- **Notification badges, cart icons, etc.** Not applicable to a marketing surface.
- **Breadcrumbs.** No deep marketing IA at v1.
- **Locale-aware nav reordering.** Same four links in the same order across all three locales.

### References

- `design-system.md § Surfaces` — frosted-glass + blur conventions.
- `design-system.md § Typography § Casing rules` — mono caps for nav labels.
- `design-system.md § Hard constraints` — radius 0, no shadows.
- `design-system.md § Hover & press` — 120ms color-only hover convention.
- `web.md § Page contracts › /` — block 1 in the page sequence; "logo + 4 links + primary CTA" requirement.
- `web.md § Marketing-specific components` — `<Nav />` component table entry.
- `ui.md § Layout & utility` — `Container` primitive used for the inner max-width wrapper.
- `i18n.md` — locale routing for `<Link>` from `@rapoport-studio/i18n/navigation`.
- `auth.md § Cookie domain handling` — sign-in cookie detection (cross-subdomain).

---

## Hero

> The first impression. One sentence describing the studio's thesis, paired with the studio's primary ask.

### Purpose

Convert a qualified visitor's first three seconds into a tap on `Start a project`. If a visitor reads only the hero and bounces, they should leave with one thought: this studio designs platforms with AI as the architecture layer, and engagements start at €50,000.

The hero is not a promise of capabilities, not a pitch about Pavel, not a list of services. It is one declarative thesis + one ask + one secondary path for the not-yet-ready visitor.

### Position in page narrative

First scrolled-to block, immediately after the sticky `Nav`. No block before it. The block immediately after is `What we build`, which expands the thesis introduced here.

The hero is the only block on the page wrapped in a `TacticalFrame` with the `tone="primary"` (terracotta corner brackets). This gives it visual weight — every other bracketed block on the page (`WorkCard`, `PersonCard`) uses the same tone but at smaller `size`, so the hero reads as the heaviest tactical element.

### Content contract

| Field | Required | Type | Source | Notes |
|---|---|---|---|---|
| `eyebrow` | yes | string | `home.hero.eyebrow` | 2–5 words. Mono caps tactical label. Positioning claim, not a tagline. |
| `headline` | yes | rich-text string | `home.hero.headline` | Single sentence ending in a period. Allows one inline `<em>` segment for emphasis (rendered via `t.rich`). Max ~14 words. |
| `sub` | legacy | string | `home.hero.sub` | Sub-line v1. Retained as i18n key for fallback only. Hero now consumes `subWithFounders`. |
| `subWithFounders` | yes | string | `home.hero.subWithFounders` | Sub-line v2 (acknowledges three audiences: client, founder, specialist). Single-CTA invariant preserved per `add-founder-track/design.md § 5` invariant 2 — founder acknowledgement lives in copy, never in a button. |
| `seeWhatWeBuild` | yes | string | `home.hero.seeWhatWeBuild` | Ghost-CTA label. Anchor link to `#what`. |
| `startProject` | yes | string | `cta.startProject` | Primary-CTA label. Reused in `ClosingCTA`. Trailing arrow `→` is part of the string. |

No images. No video. No background pattern. The block is type + frame.

### Component composition

| Layer | Component | Path |
|---|---|---|
| Block | `<Hero />` (server component, async — calls `getTranslations`) | `apps/web/src/components/home/hero.tsx` |
| Frame | `<TacticalFrame animated tone="primary" size="md">` | `@rapoport-studio/ui/components/tactical-frame` |
| Locale-aware links | `<Link>` | `@rapoport-studio/i18n/navigation` |
| Blueprint rule below frame | inline `<span data-tactical-line>` | hardcoded in `hero.tsx` |

The hero is **not** reused on any other page. `TacticalFrame` is reused widely across `/work` and inside `<WorkCard>` / `<PersonCard>`. The blueprint-line motif is reused but each instance composes the animation locally rather than via a shared component (acceptable until a second instance proves the abstraction).

### Visual contract

**Eyebrow line.** `font-mono`, `text-[10px]`, `font-medium`, `uppercase`, `tracking-[0.2em]`, `text-accent`, `mb-6`. The micro-label pattern from `design-system.md § Typography § Casing rules`. Terracotta — never blueprint, never ink.

**Headline.** Renders as `h1` at `--text-display-xl` (64 / Lora 500 / 1.05 / -0.015em), `text-ink`, `mb-6`, `max-w-[18ch]`. This is the only block paired with `Closing CTA` that consumes this token. The italic emphasis segment renders as `<em className="italic font-medium text-ink-light">` — half a step lighter in color, italic in weight, same size and family.

**Sub.** `font-serif`, `text-lg`, `leading-[1.7]`, `text-ink-light`, `max-w-[56ch]`, `mb-12`.

**Primary CTA.** `bg-ink text-canvas border border-ink px-6 py-[14px]`. Sharp corners (radius 0 per `design-system.md § Borders, radius, shadows`). Hover transitions to `bg-ink-light border-ink-light`. No shadow, no scale.

**Ghost CTA.** `text-blueprint border-b border-transparent py-[14px]`. Hover transitions both color (`text-blueprint-light`) and underline (`border-blueprint-light`). No background, no padding-x.

**Frame.** `<TacticalFrame animated tone="primary" size="md">` — four 16px L-corners in `--color-accent` (terracotta in light, terracotta-light in dark). Children get padding via the inner `data-hero-reveal` div: `px-8 py-16 md:px-16 md:py-24`. Padding goes on the inner so brackets sit at the visual outer edge of the bracketed area, not inset by the same amount as the content.

**Blueprint line.** Sibling of the frame, `mt-12`, centered, `h-[2px] max-w-[720px] bg-blueprint origin-center`. Acts as the section divider between Hero and the next block.

**Forbidden in this block.** No shadows, no gradients, no emoji, no rounded corners, no colored icons, no images, no background fills inside the frame, no raw hex (always tokens), no `font-family` overrides (always tokens).

### Motion contract

The hero plays the three-phase **card reveal sequence** from `design-system.md § Animation`:

| Phase | Timing | What animates |
|---|---|---|
| 1 — Brackets deploy | 0–560ms | Four corners deploy from frame center, `cubic-bezier(0.22, 1, 0.36, 1)`. Driven by `TacticalFrame animated`. |
| 2 — Blueprint line | 560–1120ms | Sibling line scales `scaleX(0)` → `1` from center, same easing. Inline animation on the `<span data-tactical-line>`. |
| 3 — Content fade | 880–1200ms | The `data-hero-reveal` wrapper transitions `opacity 0` → `1`, `cubic-bezier(0.4, 0, 0.2, 1)`. Driven by the `[data-hero-reveal]` rule in `globals.css`. |

Total: ~1.2s from page mount to fully visible. Triggered on mount only — not on scroll, not on intersection, not on hover.

**Hover.** Color-only on the two CTAs. 120ms transition. No scale, no translate, no shadow.

**Scroll.** None on the hero itself. Hero leaving the viewport triggers the appearance of `<StickyCTA>` (specified separately).

**Reduced-motion fallback.** When `prefers-reduced-motion: reduce`:
- Brackets render at final position with no animation.
- Blueprint line renders at full width.
- Content renders fully opaque.

The `data-tactical-animated` and `[data-hero-reveal]` rules in CSS each carry their own `@media (prefers-reduced-motion: reduce)` override. The component does not need a JS fallback.

### Responsive contract

| Breakpoint | Behavior |
|---|---|
| `< 600px` | Container gutter shrinks to 24px. Frame inner padding becomes `px-8 py-16`. Headline scales fluidly via the `clamp(34px, 8vw, 64px)`. CTA row wraps if needed. |
| `≥ 768px` | Frame inner padding becomes `px-16 py-24`. Headline reaches its 64px ceiling around 1100px viewport. CTA row stays single-row up to ~480px. |
| `≥ 1200px` | Hero centers within `max-w-page` (1200px). No further size growth — clamp ceiling holds. |

Touch targets on the two CTAs are `≥ 44px` tall (`py-[14px]` × 2 + ~17px line-height ≈ 45px). Acceptable per WCAG 2.5.5 minimum.

### Accessibility contract

- The block is wrapped in `<section id="hero">`. The `id` is consumed by `<StickyCTA>`'s `IntersectionObserver` and by anchor links from elsewhere in the site.
- The headline is the page's only `<h1>`. No other `<h1>` on `/`.
- The eyebrow is a `<p>`, not a heading — it's a decorative label, not a section anchor in the outline.
- The `<em>` inside the headline is semantic emphasis, not styling — assistive tech announces emphasis, which matches intent (`that orchestrate` is the conceptually loaded part of the sentence).
- Both CTAs are `<a>` (rendered by `<Link>`), not `<button>` — they navigate.
- Focus order is left-to-right, top-to-bottom: primary CTA, then ghost CTA. No focus traps. Focus ring is the design-system default (1px blueprint outline, 2px offset).
- Color contrast at AA: ink on canvas in dark mode = `#E8E6E0` on `#1A1A1C` = >12:1. Ink-light on canvas = `#B4B2A9` on `#1A1A1C` = >7:1. Brand-accent on canvas (eyebrow) = `#E8795A` on `#1A1A1C` = ~5.4:1, AA-compliant for the 10px size only because it's a non-essential decorative label; if the eyebrow becomes load-bearing copy, lift contrast.

### Localization

Ships in all three locales: `en` (default), `ru`, `ro`. All four content fields plus the primary-CTA label are required in every catalog. No fallback to English.

Translation keys:
- `home.hero.eyebrow`
- `home.hero.headline` (rich-text — `<em>...</em>` segment must be preserved across locales)
- `home.hero.sub`
- `home.hero.seeWhatWeBuild`
- `cta.startProject` (shared with `ClosingCTA`)

Rich-text rule: the `<em>` markup in `headline` is part of the contract. A translator must keep one `<em>...</em>` pair in the translated string. Empty `<em></em>` or missing tags break the visual rhythm.

### Out of scope

- **Hero illustration / Canvas.** No SVG, no animated background, no video. The frame and type do the work. A future Canvas hero is deferred per `web.md § Out of scope`.
- **A/B variants.** One hero, one variant. If we A/B-test headlines later, that's a separate change to this spec.
- **Personalization.** No locale-based hero swap, no UTM-aware copy, no first-time-vs-returning split.
- **Carousel / autoplay / scroll-driven storytelling.** None of these. Hero is static after the mount sequence.
- **Email capture in hero.** The only conversion path is the primary CTA → `/contact`. No inline email field.

### References

- `design-system.md § Animation › Card reveal sequence` — three-phase reveal timing.
- `design-system.md § Tactical frame` — corner-bracket motif.
- `design-system.md § Typography` — Lora display + Inter + JetBrains Mono mono-label.
- `design-system.md § Hard constraints` — radius 0, no shadows, no gradients, no emoji.
- `web.md § Page contracts › /` — block 2 in the page sequence.
- `ui.md § TacticalFrame` — frame component contract.

---

## What we build

> The thesis expansion. An eyebrow, a sentence, a centered orchestra diagram, a supporting paragraph, a pull-quote. Earns the Hero claim with a concrete picture.

### Purpose

Convert the abstract Hero claim ("we design platforms with AI as the architecture layer") into a picture a visitor can hold. The orchestra metaphor is the studio's load-bearing framing — AI is the conductor, specialised models are the sections, the platform is the score. This block introduces the metaphor and earns it with one supporting paragraph and one pull-quote.

A visitor who reads this block should walk into `Now building` already understanding *what kind of object* the studio produces. Without that understanding, the in-progress cards downstream are decontextualised.

### Position in page narrative

Block 3. Sits between `Hero` and `Now building`. Hero introduces the thesis; What we build expands it; Now building shows the expansion in production.

The block immediately before is `Hero`. The block immediately after is `Now building`. The pull-quote sits at the bottom of the block — the visitor reads heading → lede → diagram → supporting → quote, then crosses a 0.5px grid divider into the next section.

### Content contract

| Field | Required | Type | Source | Notes |
|---|---|---|---|---|
| `eyebrow` | yes | string | `home.whatWeBuild.eyebrow` | 2–4 words. Mono caps tactical label. |
| `heading` | yes | string | `home.whatWeBuild.heading` | One sentence. Max ~10 words. Sentence case. |
| `lede` | yes | string | `home.whatWeBuild.lede` | 2–3 sentences. Names the orchestra metaphor explicitly. |
| `nodeLabel.conductor` | yes | string | `home.whatWeBuild.diagram.conductor` | Diagram center node label. ≤2 words. |
| `nodeLabel.strings` | yes | string | `home.whatWeBuild.diagram.strings` | Section label. ≤2 words. |
| `nodeLabel.brass` | yes | string | `home.whatWeBuild.diagram.brass` | Section label. ≤2 words. |
| `nodeLabel.winds` | yes | string | `home.whatWeBuild.diagram.winds` | Section label. ≤2 words. |
| `nodeLabel.percussion` | yes | string | `home.whatWeBuild.diagram.percussion` | Section label. ≤2 words. |
| `supporting` | yes | string | `home.whatWeBuild.supporting` | 2–3 sentences. Translates the metaphor into concrete platform terms. |
| `pullQuote` | yes | rich-text string | `home.whatWeBuild.pullQuote` | One sentence, ≤22 words. Allows one inline `<em>` segment. **No `byline` field** — studio voice. |

The pull-quote contract deliberately omits an `author` or `byline` field. The studio site does not center on Pavel (per `platform.md § Brand boundaries`), and an attributed quote would either point to Pavel (off-brand) or to a fabricated voice (dishonest). The quote stands as studio statement.

### Component composition

| Layer | Component | Path |
|---|---|---|
| Block | `<WhatWeBuild />` (server component, async) | `apps/web/src/components/home/what-we-build.tsx` |
| Diagram | `<OrchestraDiagram />` | `apps/web/src/components/shared/orchestra-diagram.tsx` |
| Pull-quote | `<PullQuote />` | `apps/web/src/components/shared/pull-quote.tsx` |

The diagram is a custom inline SVG inside `<OrchestraDiagram />` — not an `<img>` to a static file. Inline SVG is required because the diagram nodes participate in the deploy/blueprint motion choreography (see Motion contract). A reused asset from the previous web could not be animated in step.

`<OrchestraDiagram />` lives under `components/shared/` because it may be reused on `/services` later (per `web.md § Marketing-specific components`). `<PullQuote />` is also shared — used here and inside MDX articles on `/lab/[slug]`.

### Visual contract

**Section.** `border-t border-grid` (0.5px), `py-32 md:py-40`. Same divider rhythm as every other section.

**Eyebrow.** `font-mono text-[10px] font-medium uppercase tracking-[0.2em] text-accent mb-6`. Same micro-label pattern as Hero eyebrow.

**Heading.** `font-serif font-medium text-[clamp(32px,4.5vw,48px)] leading-[1.2] tracking-[-0.01em] text-ink mb-6 max-w-[20ch]`. One step lighter than Hero (48px ceiling vs 64px) — the visitor has scrolled past the loudest type.

**Lede.** `font-serif text-lg leading-[1.7] text-ink-light max-w-[56ch] mb-16`. Same body type as Hero sub.

**Diagram.** Centered, `max-w-[720px] mx-auto my-16`. Five nodes (one conductor, four sections) connected by 0.5px blueprint lines. Each node is a `MonoLabel` (`font-mono text-[10px] uppercase tracking-[0.2em] text-ink`). Conductor uses `text-accent`; sections use `text-ink-light`. No fills, no shadows, no decorative chrome.

**Supporting paragraph.** `font-serif text-base leading-[1.7] text-ink-light max-w-[56ch] mt-16`.

**Pull-quote.** `font-serif italic font-medium text-2xl leading-[1.4] text-ink-light max-w-[40ch] mx-auto mt-24 text-center`. The italic clause inside, if any, renders as `<em className="not-italic font-medium text-ink">` — italic-on-italic is hard to read, so the inner emphasis flips back to roman + ink. No quote marks rendered (the visual context — centered serif italic block — is enough).

**Forbidden in this block.** No tactical frame (the diagram is the visual anchor; brackets would compete). No image, no photo, no decorative SVG outside the diagram. No background color shift. No raw hex.

### Motion contract

The diagram plays a node-stagger reveal on intersection.

| Phase | Trigger | What animates |
|---|---|---|
| 1 — Conductor appears | Section enters viewport (threshold 0.2) | Conductor node fades in over 360ms `--ease-deploy`. |
| 2 — Section nodes deploy | 240ms after phase 1 | Four section nodes fade in with 60ms stagger between, `--ease-deploy`. Connecting blueprint lines scale `scaleX(0)` → `1` from the conductor outward, in step with each node. |
| 3 — Pull-quote fades | Pull-quote enters viewport (separate observer) | `opacity 0` → `1` over 400ms `--ease-settle`. No transform. |

The lede and supporting paragraphs do not animate — they render at final state. Theatrical entry on text would slow the visitor's read.

**Hover.** None. The diagram is decorative at v1 — node hover does not reveal additional detail.

**Reduced-motion fallback.** All nodes, lines, and the pull-quote render at final state with no transitions. The diagram is fully visible on first paint.

### Responsive contract

| Breakpoint | Behavior |
|---|---|
| `< 600px` | Diagram scales fluidly to viewport width. Node labels truncate to first word at viewport widths below ~360px (CSS clamp on font-size, with overflow ellipsis). Section padding shrinks to `py-24`. |
| `≥ 768px` | Diagram reaches its 720px ceiling. Full node labels visible. |
| `≥ 1200px` | Section centers within `max-w-page` parent. No further size growth. |

Touch targets are not applicable — the diagram has no interactive nodes at v1.

### Accessibility contract

- Section is `<section id="what" aria-labelledby="what-heading">`.
- Heading is `<h2 id="what-heading">` — first `<h2>` on the page after the Hero `<h1>`.
- The orchestra diagram is `<div role="img" aria-label="{generated description}">` — the `aria-label` text is a translatable string `home.whatWeBuild.diagram.altText` describing the orchestra metaphor in one sentence (e.g., "An orchestra diagram: one conductor at center, four section labels arranged around it.").
- Individual diagram nodes are `aria-hidden="true"` (the parent `aria-label` carries the semantic content; nodes are decorative SVG text).
- Pull-quote is `<blockquote><p>...</p></blockquote>`. No `<cite>` element (no attribution).
- Inline `<em>` inside the pull-quote is semantic emphasis.
- Focus order: previous block's last interactive element (Hero ghost CTA) → next block's first interactive element. The What we build block has no focusable elements.
- Color contrast: ink-light/canvas (lede, supporting, pull-quote) >7:1 in dark mode; accent/canvas (conductor label, eyebrow) ~5.4:1, AA-compliant for non-essential micro-labels.

### Localization

Ships in all three locales. All ten content fields plus the diagram alt-text are required in every catalog.

Translation keys:
- `home.whatWeBuild.eyebrow`
- `home.whatWeBuild.heading`
- `home.whatWeBuild.lede`
- `home.whatWeBuild.diagram.conductor`
- `home.whatWeBuild.diagram.strings`
- `home.whatWeBuild.diagram.brass`
- `home.whatWeBuild.diagram.winds`
- `home.whatWeBuild.diagram.percussion`
- `home.whatWeBuild.diagram.altText`
- `home.whatWeBuild.supporting`
- `home.whatWeBuild.pullQuote` (rich-text — `<em>` preservation rule applies)

Diagram node labels translate independently. Translators must keep each label ≤2 words to preserve the visual rhythm.

### Out of scope

- **Interactive diagram.** No hover-reveal node detail, no click-to-expand at v1.
- **Author byline on the pull-quote.** Studio voice; no attribution UI.
- **Multiple pull-quotes.** One quote, one position. If the studio voice grows multiple quotes, that's a separate change to this spec.
- **Video version of the diagram.** Animated SVG only.
- **Illustration replacement.** No painterly alternative; the studio's brand is type and tactical chrome, not illustration.
- **Section-page deep-link.** No anchor link to `/services` from this block — the closing CTA is for next steps, not in-block navigation.

### References

- `design-system.md § Animation` — deploy stagger and node-reveal timing.
- `design-system.md § Typography` — Lora display + Inter mono labels.
- `design-system.md § Tactical components › MonoLabel` — diagram node label spec.
- `design-system.md § Hard constraints` — radius 0, no shadows, no decorative chrome.
- `web.md § Page contracts › /` — block 3 in the page sequence.
- `web.md § Marketing-specific components` — `<OrchestraDiagram />`, `<PullQuote />` component table entries.
- `home.md § Hero` — preceding block; sets the thesis this block expands.
- `platform.md § Brand boundaries` — studio-voice rule that determines no-byline pull-quote.

---

## Now building

> Concrete proof. A heading, a lede, a card grid sourced from MDX with `status: in-progress`. Stealth cards mask their identity but signal motion.

### Purpose

Show the studio is currently producing real platforms. After Hero (thesis) and What we build (metaphor expansion), the visitor needs evidence that this is not aspirational — it is in flight today. Each card is a concrete project: client, year, one-line summary, link to the full case study.

The block deliberately separates from the `/work` page surface. `/work` carries both featured current builds (top) and the archive (below); `Now building` on home is the **teaser** — it shows up to 2 in-progress cards plus an explicit CTA to the full `/work` page (applied 2026-05-15 from change `redesign-work-featured-current-builds-archive`, RAP-826). The signal here is "the orchestra is currently playing"; `/work` carries the discography plus the active scores.

### Position in page narrative

Block 4. Sits between `What we build` and `How we work`. The thesis (Hero) → metaphor (What we build) → evidence (Now building) → process (How we work) flow is the four-beat case for engagement before the block 5–7 capability beats.

The block immediately before is `What we build`. The block immediately after is `How we work`.

### Content contract

| Field | Required | Type | Source | Notes |
|---|---|---|---|---|
| `eyebrow` | yes | string | `home.nowBuilding.eyebrow` | 2–4 words. Mono caps. |
| `heading` | yes | string | `home.nowBuilding.heading` | One sentence, ≤8 words. |
| `lede` | yes | string | `home.nowBuilding.lede` | 1–2 sentences. Sets context for the cards below. |
| `stealthLabel` | yes | string | `home.nowBuilding.stealthLabel` | Renders inside the `StatusPill` on stealth cards. Default copy "Under embargo" or per-locale equivalent. |
| `cta` | yes | string | `home.nowBuilding.cta` | CTA label below the card grid. Default copy "See current builds + archive →" or per-locale equivalent. Added 2026-05-15 by RAP-826. |
| `ctaAriaLabel` | yes | string | `home.nowBuilding.ctaAriaLabel` | Screen-reader-only context for the CTA link (the visible "→" carries no semantic meaning on its own). Added 2026-05-15 by RAP-826. |
| `cards[]` | yes | array | `content/work/*.mdx` filtered to frontmatter `status: in-progress` | Sorted by frontmatter `year` desc, then `slug` asc. **Capped at 2 cards on the home teaser** (added 2026-05-15 by RAP-826); the full set renders in the `/work` featured zone. |

**Per-card frontmatter contract** (defined by `content/work/*.mdx` shape, surfaced here for completeness):

| Frontmatter field | Required | Type | Notes |
|---|---|---|---|
| `title` | yes | string | Public title. Hidden when `stealth: true`. |
| `client` | yes | string | Client name. Hidden when `stealth: true`. |
| `year` | yes | number | Used for sort order. |
| `status` | yes | enum | Filter key. `in-progress` includes the card; other values exclude it from this block. |
| `summary` | yes | string | One-sentence outcome or current state. ≤24 words. |
| `team[]` | yes | array | Roles + names. Surfaced on `/work/[slug]`, not on the homepage card. |
| `stealth` | no | bool | Defaults `false`. When `true`, masks `title` and `client`; uses `summary` as is (authoring responsibility to keep stealth-safe). |

**Empty state.** When the filter returns zero entries, the entire `## Now building` section does not render. No placeholder copy, no "nothing here yet" text — the section is simply absent from the page. This mirrors the `Lab preview` empty-state pattern.

### Component composition

| Layer | Component | Path |
|---|---|---|
| Block | `<NowBuilding />` (server component, async — reads MDX at build time) | `apps/web/src/components/home/now-building.tsx` |
| Card | `<WorkCard />` | `apps/web/src/components/work/work-card.tsx` |
| Stealth card variant | `<WorkCard variant="stealth">` | same file, internal variant prop |
| Frame around each card | `<TacticalFrame size="sm" tone="primary">` | `@rapoport-studio/ui/components/tactical-frame` |
| Status pill on stealth cards | `StatusPill` (forward-reference — see References) | spec at `design-system.md § Tactical components` line 420 |

The stealth variant masks `title` (renders "Stealth project" or per-locale equivalent — uses `home.nowBuilding.stealthLabel` as the rendered title) and `client` (renders an empty space, not "anonymous"; the tactical pill carries the embargo signal). Summary still renders, on the assumption that the MDX author wrote a summary that is stealth-safe.

### Visual contract

**Section.** `border-t border-grid` (0.5px), `py-32 md:py-40`.

**Eyebrow / Heading / Lede.** Same scale and color as `What we build` block — heading clamps `text-[clamp(32px,4.5vw,48px)]`, lede `font-serif text-lg leading-[1.7] text-ink-light max-w-[56ch]`.

**Card grid.** `grid grid-cols-1 md:grid-cols-2 gap-8 mt-16`. Two columns at desktop; single column on mobile. No expansion to 3 columns at any breakpoint — preserves card density and prevents the page from feeling like an archive.

**Card.** Each `<WorkCard>` is wrapped in a `<TacticalFrame size="sm" tone="primary">`. Inner padding `px-8 py-10`. Layout inside: client (small mono caps, ink-light) at top, title (serif, ink, ~24px) below, summary (serif, ink-light, body size) below, year (mono caps, ink-light) at bottom-right. No image, no thumbnail.

**Stealth card.** Same frame and layout as standard card. Top-left: `<StatusPill>` with terracotta dot and `stealthLabel` text. Title slot renders the same `stealthLabel` text in serif (placeholder for the masked title). Client slot renders an empty `<span>` (preserves vertical rhythm without showing "Hidden" or similar copy). Summary renders normally.

**Forbidden in this block.** No card images, no thumbnails, no logos, no decorative dividers between cards. No background fill on cards (transparent over canvas). No raw hex.

### Motion contract

Cards reveal on intersection with deploy stagger.

| Phase | Trigger | What animates |
|---|---|---|
| Bracket deploy | Card enters viewport (threshold 0.3) | `<TacticalFrame>` brackets deploy from card center, 360ms `--ease-deploy`. |
| Content fade | 200ms after brackets begin | Card content (`opacity 0` → `1`), 400ms `--ease-settle`. |
| Inter-card stagger | Multiple cards visible simultaneously | 60ms delay between consecutive cards in DOM order (the `--ease-deploy` deploy stagger from `design-system.md § Animation`). |

Heading, lede, and section chrome do not animate — they render at final state.

**Hover.** Cards have a subtle hover state: bracket tone shifts from `accent` to `accent-light` (60ms), title transitions from `text-ink` to `text-ink-light` (120ms). No scale, no shadow, no translate.

**Reduced-motion fallback.** All cards render at final state with brackets at full deploy, content fully opaque. No transitions.

### Responsive contract

| Breakpoint | Behavior |
|---|---|
| `< 768px` | Single column. Card frame inner padding shrinks to `px-6 py-8`. Cards stack with 24px gap. |
| `≥ 768px` | Two-column grid. Card frame `px-8 py-10`. 32px gap. |
| `≥ 1200px` | Two-column grid persists; centered within `max-w-page`. No 3-column expansion. |

Touch targets: each card is fully-clickable via the title link (entire card surface activates the link, but the focusable target is the title `<a>` for accessibility). Card height ≥ 200px so the touch target meets the 44px minimum trivially.

### Accessibility contract

- Section is `<section id="now" aria-labelledby="now-heading">`.
- Heading is `<h2 id="now-heading">`.
- Card grid is `<ul>` with each card as `<li>`. Each card is also internally `<article>` for semantic clarity.
- Card title is `<h3>`. Standard cards: visible title text. Stealth cards: title is `<h3>` with `stealthLabel` text and a visually-hidden `<span class="sr-only">: stealth project, details under embargo</span>` to give screen-readers context for why the title looks generic.
- Stealth `StatusPill` has `aria-label="{stealthLabel}"` so it announces consistently with the visible text.
- Card link wraps the title only (semantically); the entire card surface is clickable via the standard CSS-only "card anchor" pattern (`::before` overlay on the link).
- Focus ring on title link: 1px blueprint outline, 2px offset (design-system default).
- Empty-state behavior: the entire `<section>` is absent from the DOM, so the page outline skips from the previous section's `<h2>` directly to the next.

### Localization

Ships in all three locales for chrome (`eyebrow`, `heading`, `lede`, `stealthLabel`).

Card content (title, client, summary) is MDX-driven and English-only at launch (per `web.md § Locale strategy` line 110: "Long-form MDX — English-only"). Romanian and Russian visitors see English card content with localized chrome. This is the documented translation policy; not a defect.

Translation keys (chrome):
- `home.nowBuilding.eyebrow`
- `home.nowBuilding.heading`
- `home.nowBuilding.lede`
- `home.nowBuilding.stealthLabel`

### Out of scope

- **Completed work archive.** Lives on `/work`, not on the homepage.
- **Filter chips by domain / client / year.** The homepage shows in-progress only; no filtering needed.
- **Card hover-reveal additional detail.** No expanded preview, no inline case-study snippet.
- **Client logos.** Cards are typographic only; no logo grid.
- **Cross-card linking / "related" suggestions.** Each card links to its own case study; no inter-card navigation.
- **Cards with no link target.** Every in-progress entry must have a corresponding `/work/[slug]` page (even if the page is stealth-marked itself). MDX without a published case-study page does not render here.

### References

- `design-system.md § Animation` — bracket deploy + 60ms inter-card stagger.
- `design-system.md § Tactical frame` — `<TacticalFrame size="sm" tone="primary">` spec.
- `design-system.md § Tactical components › StatusPill` (line 420) — the stealth-card pill spec. `StatusPill` ships at `packages/ui/src/components/status-pill.tsx` and is documented in `ui.md § Component inventory`. (An earlier note here flagged this as a forward reference; the implementation has landed.)
- `design-system.md § Typography` — serif card titles, mono client/year labels.
- `web.md § Page contracts › /` — block 4 in the page sequence.
- `web.md § Marketing-specific components` — `<WorkCard />` component table entry.
- `web.md § Content storage` — MDX frontmatter contract.
- `home.md § What we build` — preceding block; metaphor that the cards make concrete.
- `home.md § Lab preview` — sibling block; same empty-state pattern.

---

## How we work

> The engagement model in four numbered acts. Brief. Curate. Build. Deliver. Mono numerals, serif step names, ink-light bodies. No diagram, no swim-lane.

### Purpose

Make the engagement model legible before a visitor commits cognitive effort to evaluating fit. A studio process is opaque by default; the four acts turn that opacity into four concrete things — write the brief, curate the team, build the platform, hand it over. A visitor who reads this block knows whether the model fits their situation without needing a sales call.

### Position in page narrative

Block 5. Sits between `Now building` and `The network`. The "how does this actually work" beat follows the "what is in production" beat. The block immediately before is `Now building`. The block immediately after is `The network`.

### Content contract

| Field | Required | Type | Source | Notes |
|---|---|---|---|---|
| `eyebrow` | yes | string | `home.howWeWork.eyebrow` | 2–4 words. Mono caps. |
| `heading` | yes | string | `home.howWeWork.heading` | One sentence, ≤8 words. |
| `lede` | yes | string | `home.howWeWork.lede` | 1–2 sentences. |
| `steps[]` | yes | fixed-length array of 4 | inline (numerals + i18n keys for name/body) | See Step contract below. |

**Step contract** (one entry per act):

| Sub-field | Required | Type | Source | Notes |
|---|---|---|---|---|
| `numeral` | yes | string | hardcoded `"01"` / `"02"` / `"03"` / `"04"` | **Not localized.** Western Arabic numerals across all three locales. Two-digit zero-padded. |
| `name` | yes | string | `home.howWeWork.steps.{brief,curate,build,deliver}.name` | One word in English (Brief / Curate / Build / Deliver); per-locale equivalent. Sentence case. |
| `body` | yes | string | `home.howWeWork.steps.{brief,curate,build,deliver}.body` | 1–2 sentences. Concrete, not aspirational. |

Step labels are fixed: Brief / Curate / Build / Deliver. The four-act structure is part of the studio's contract with the world; renaming or reordering requires a separate change.

### Component composition

| Layer | Component | Path |
|---|---|---|
| Block | `<HowWeWork />` (server component, async) | `apps/web/src/components/home/how-we-work.tsx` |
| Step row | `<StepRow />` | `apps/web/src/components/home/step-row.tsx` |

Four `<StepRow />` rendered in fixed order. No `.map` over a configurable array — the four steps are hardcoded into the block, with content sourced from the i18n catalog. This deliberate hardcoding prevents the structure from drifting via catalog edits.

### Visual contract

**Section.** `border-t border-grid` (0.5px), `py-32 md:py-40`.

**Eyebrow / Heading / Lede.** Same scale and color as `What we build` and `Now building`. Heading clamps `text-[clamp(32px,4.5vw,48px)]`.

**Step row.** Three-column layout on desktop: numeral | name | body. Numeral fixed-width column (~96px). Name + body share the remaining width.
- **Numeral.** `font-mono text-accent text-2xl font-medium leading-none` (~24px). Terracotta — picks up the eyebrow color rhythm.
- **Name.** `font-serif font-medium text-xl text-ink leading-tight`.
- **Body.** `font-serif text-base leading-[1.7] text-ink-light max-w-[56ch] mt-2`.

**Inter-row divider.** `border-t border-grid` (0.5px) between consecutive `<StepRow />` (not above the first, not below the last). `py-12` per row produces the rhythm.

**Forbidden in this block.** No icons, no swim-lane diagram, no decorative connectors between steps, no progress bar, no checkbox glyphs. The numerals do the work.

### Motion contract

Each `<StepRow />` reveals on intersection.

| Phase | Trigger | What animates |
|---|---|---|
| 1 — Numeral appears | Row enters viewport (threshold 0.3) | Numeral fades in over 240ms `--ease-deploy`. Slight `translateY(8px) → 0` on the numeral character. |
| 2 — Name + body fade | 120ms after phase 1 | Name and body fade in together (`opacity 0` → `1`, 360ms `--ease-settle`). |
| Inter-row stagger | Multiple rows visible simultaneously | 60ms delay between consecutive rows in DOM order (`design-system.md § Animation` deploy stagger). |

**Hover.** None. The block is read-only narrative; no hover affordances.

**Reduced-motion fallback.** All numerals and content render at final state with no transitions or transforms.

### Responsive contract

| Breakpoint | Behavior |
|---|---|
| `< 768px` | Numeral above name above body, single column. Numeral keeps its mono accent style; sits flush-left above the row. Inter-row divider still applies. Section padding shrinks to `py-24`. |
| `≥ 768px` | Three-column layout (numeral fixed-width, name + body share). Inter-row divider full-width. |
| `≥ 1200px` | Same layout, centered within `max-w-page`. |

Touch targets: not applicable — the block has no interactive elements.

### Accessibility contract

- Section is `<section id="how" aria-labelledby="how-heading">`.
- Heading is `<h2 id="how-heading">`.
- Steps render as `<ol>` with `<li>` per row. The `<ol>` semantic carries the order; the visible numeral is decorative (`aria-hidden="true"` on the numeral element so screen-readers don't announce "01 Brief 1 Brief").
- Each step name is `<h3>` per row, scoped to its `<li>`.
- Step body is `<p>`.
- Focus order: previous block's last interactive element → next block's first interactive element. The block has no focusable elements.
- Color contrast: ink-light/canvas (body) >7:1; accent/canvas (numeral, ~24px) >5:1, AA-compliant for the size.

### Localization

Ships in all three locales for `eyebrow`, `heading`, `lede`, and each step's `name` + `body`.

Translation keys:
- `home.howWeWork.eyebrow`
- `home.howWeWork.heading`
- `home.howWeWork.lede`
- `home.howWeWork.steps.brief.name`
- `home.howWeWork.steps.brief.body`
- `home.howWeWork.steps.curate.name`
- `home.howWeWork.steps.curate.body`
- `home.howWeWork.steps.build.name`
- `home.howWeWork.steps.build.body`
- `home.howWeWork.steps.deliver.name`
- `home.howWeWork.steps.deliver.body`

**Numerals are not localized.** "01"/"02"/"03"/"04" render identically in all three locales. (Romanian and Russian both use Western Arabic numerals in technical contexts.)

### Out of scope

- **Process diagram, timeline visualization, swim-lane.** The four numbered rows are the diagram.
- **"Click for detail" expansion.** Each step's body is the full content for the homepage.
- **Per-step case-study links.** A future pattern, not v1.
- **Alternative engagement models** (sprint, retainer, audit, etc.). v1 has one model — the four acts — and `/services` lists the engagement-shape variations. The homepage block is single-model.
- **Step skipping or non-linear flow.** All four acts always apply; the spec does not document skipping.

### References

- `design-system.md § Animation` — deploy stagger between rows; numeral entry transform.
- `design-system.md § Typography` — serif step name, mono accent numeral, ink-light body.
- `design-system.md § Tactical components › MonoLabel` — numeral typography pattern.
- `web.md § Page contracts › /` — block 5 in the page sequence; step-label source of truth.
- `web.md § Marketing-specific components` — `<StepRow />` component table entry.

---

## Who we work with

> Four founder cohorts. Geo-tagged, pain-tagged, offer-tagged. Resolves "we work with founders" into four specific cohort shapes.

> **Removed from home 2026-05-23 per RAP-1190 D-HTN-6.** The component file `apps/web/src/components/home/who-we-work-with.tsx` is retained for a future v2 restoration as a quote-strip variant (see `archive/2026-05-23-fix-home-trust-blocks-and-narrative/design.md § D-HTN-6 ratified`). The block-template below documents the pre-RAP-1190 contract and is retained for v2 reference; it does not describe the current home arc. See `flows.md § Page narrative arc` for the live arc.

### Purpose

Resolve the studio's founder audience into four named cohorts. A visiting founder asks "is that me?" — four cards answer with the cohort's geography, pain shape, and the specific offer that addresses it.

### Position in page narrative

Block 9, between `ForFounders` (block 8) and `TheNetwork` (block 10). `ForFounders` frames story-shapes of founder pain; `WhoWeWorkWith` maps those shapes to four named buyer cohorts with geos; `TheNetwork` shows who delivers the work. Reader sequence: "we serve founders" → "these four founder shapes specifically" → "via this specialist network."

### Content contract

| Field | Required | Type | Source | Notes |
|---|---|---|---|---|
| `eyebrow` | yes | string | `home.whoWeWorkWith.eyebrow` | All-caps mono label. |
| `heading` | yes | string | `home.whoWeWorkWith.heading` | "Four founder shapes." |
| `lede` | yes | string | `home.whoWeWorkWith.lede` | One to two sentences framing why four cohorts. |
| `cohorts[].name` | yes × 4 | string | `home.whoWeWorkWith.cohorts.{slug}.name` | Cohort name. Slugs: `seriesABAi`, `midCapSaas`, `deepTech`, `diaspora`. |
| `cohorts[].geo` | yes × 4 | string | `home.whoWeWorkWith.cohorts.{slug}.geo` | Geo-marker string. Preserved in English across all locales. |
| `cohorts[].painLine` | yes × 4 | string | `home.whoWeWorkWith.cohorts.{slug}.painLine` | One-sentence pain. |
| `cohorts[].offerLine` | yes × 4 | string | `home.whoWeWorkWith.cohorts.{slug}.offerLine` | One-sentence offer. |

No CTA per card. Block is informational — conversion stays in ClosingCTA.

### Component composition

| Layer | Component | Path |
|---|---|---|
| Block | `<WhoWeWorkWith />` (async server component) | `apps/web/src/components/home/who-we-work-with.tsx` |
| Section header | `<SectionHead />` | `@rapoport-studio/ui/components/section-head` |
| Geo-marker pill | `<Chip kind="skill" />` | `@rapoport-studio/ui/components/chip` |

### Visual contract

Four cards in a CSS grid (`grid-cols-1 md:grid-cols-2 gap-8`). Each card (`<article>`):

- Geo-marker: `<Chip kind="skill">` — `rounded-full border font-mono text-xs uppercase tracking-[0.15em]`
- Cohort name: `font-serif font-medium text-xl leading-tight text-ink`
- Pain line: `font-serif italic text-base leading-[1.7] text-ink-light`
- Offer line: `font-serif text-base leading-[1.7] text-ink-light`

Forbidden: per-card CTA buttons. No pricing. No competitor names. No named client references.

### Motion contract

No entry animation. Standard hover transitions from Tailwind. Reduced-motion: no additional changes needed.

### Responsive contract

- Mobile (`< md`): single column. Four cards separated by `border-t border-grid pt-8`.
- Desktop (`≥ md`): 2×2 grid. `gap-8` between cells.
- Minimum width: 320px (site-wide minimum).

### Accessibility contract

- Section landmark: `<section id="who-we-work-with" aria-labelledby="who-we-work-with-heading">`.
- Heading hierarchy: `<h2>` for block heading (via `SectionHead`), `<h3>` per cohort name.
- Geo-marker `<Chip>` renders as `<span>` — no interactive role.
- No keyboard traps; no interactive elements within cards.

### Localization

Three locales: `en`, `ro`, `ru`. Keys under `home.whoWeWorkWith.*` in `packages/i18n/messages/{en,ro,ru}/web.json`.

**Geo strings** (`cohorts.*.geo`) are preserved in English across all locales — city/region names and language abbreviations (`EN · RO · RU · HE`) are language-invariant proper nouns.

Pain lines, offer lines, heading, and lede are translated per locale.

### Out of scope

- Per-card CTA button.
- Pricing per cohort.
- Named client references within a cohort.
- "And many more" tail — the four cohorts are exhaustive of the studio's current focus.
- Competitor comparison language.
- Proof-line strip or live stats.

### References

- `openspec/archive/2026-05-11-expand-home-with-operating-model-and-cohorts/design.md § Block 2 — WhoWeWorkWith` — canonical copy source and four-cohort rationale.
- `openspec/current/design-system.md § Typography` — serif card body pattern.
- `openspec/current/home/spec.md § Founder Track delta` — the ForFounders block this follows.

---

## The network & community

> A single block addressed to specialists. Open registration + OpenSpec apprenticeship + adversarial review for idea-stage founders, plus the curated specialist roster when populated. Replaces the previous `§ The network` and `§ Community signal` pair (merged 2026-05-12 from change `merge-community-signal-into-network`).

### Purpose

A single block addressed to specialists (`AudienceTag tone="spc"` per `flows.md § Page invariants` invariant 2). Answers two questions in order:

1. **What is the network?** Layer A — open registration, OpenSpec apprenticeship, adversarial review for idea-stage founders, expressed today as a single-paragraph body. Always renders.
2. **Who is in the network?** Layer B — the `PersonCard` grid of opted-in specialists. Renders only when at least one entry exists.

A visitor scanning this block should leave with: there is a way in (Layer A — anyone can join the community track) and there is curation (Layer B — every face here actively chose to be visible via `optInPublic: true`). The opt-in mechanism is what makes the curated roster credible; the open registration is what makes the network self-renewing.

### Position in page narrative

Block 9. Sits between `Who we work with` and `Services`. The "who builds it" beat follows the "who is this for" beat. WhoWeWorkWith resolves the founder audience into four cohorts; this block opens the specialist invitation by itself, no longer split between two side-by-side sections.

The block immediately before is `Who we work with`. The block immediately after is `Services`.

### Renders if

**Always.** The block mounts unconditionally on `/`. Layer A is unconditional. Layer B mounts when `roster.length >= 1`; otherwise Layer B unmounts and the block ends at the secondary-link row. No skeleton, no "network forming" placeholder for Layer B — the absent grid is documented as part of the block's resting state.

The previous `§ The network § Renders if § Empty roster` clause (which unmounted the entire block when the roster was empty) is **deleted** along with §9. Empty-roster behaviour is now block-internal (Layer B unmounts), not block-level. The merged block always carries the community CTA and body, so the page does not lose the specialist arc when the roster is quiet.

### Content contract

| Field | Required | Type | Renders in | Source | Notes |
|---|---|---|---|---|---|
| `eyebrow` | yes | string | block header | `home.networkAndCommunity.eyebrow` | 2–4 words. Mono caps. |
| `heading` | yes | string | block header | `home.networkAndCommunity.heading` | One sentence, ≤8 words. New value: "The network & community". |
| `lede` | yes | string | Layer A | `home.networkAndCommunity.lede` | 1–2 sentences. |
| `communityEyebrow` | yes | string | Layer A | `home.networkAndCommunity.communityEyebrow` | Mono label above the community body, signalling the sub-theme. Migrated from the deleted `home.network.communitySignal.eyebrow`. |
| `communityBody` | yes | string | Layer A | `home.networkAndCommunity.communityBody` | Single body paragraph below the community eyebrow. Migrated verbatim from the deleted `home.network.communitySignal.body`. Expanding into a registration / apprenticeship / adversarial-review triplet is a separate proposal — out of scope here. |
| `rosterCta` | yes | `{ label: string; href: string }` | Layer A | `home.networkAndCommunity.rosterCta` | Secondary link (per `flows.md § Page invariants` invariant 1) — mono, blueprint, underlined. Default `href='/network'`. |
| `communityCta` | yes | `{ label: string; href: string }` | Layer A | `home.networkAndCommunity.communityCta` | Secondary link to community apprenticeship sign-up (`studio.signupUrl` per `add-studio-self-serve-signup`). Migrated from the deleted `home.network.communitySignal.cta`. |
| `statsTemplate` | yes | rich-text string | Layer B | `home.networkAndCommunity.stats` | Contains `{count}` and `{cities}` placeholders. Computed at build time from the filtered roster. Example: "12 collaborators · 7 cities". |
| `roster` | yes | `PersonCardProps[]` | Layer B | `content/network.json` filtered to `optInPublic: true`, sorted by `joinedYear` desc, take first 6. | Empty array → Layer B unmounts. Per-card contract unchanged from the deleted `§ The network § Per-card contract`. |

**Per-card contract** (Layer B; defined by `content/network.json` shape, unchanged from the deleted block):

| Sub-field | Required | Type | Notes |
|---|---|---|---|
| `name` | yes | string | Display name. |
| `role` | yes | string | One short phrase (e.g., "Backend / Distributed systems"). ≤6 words. |
| `location` | yes | string | City. ≤2 words. |
| `photo` | yes | string | Path to portrait. 1:1 aspect, no crop variation. |
| `links.personal` | no | string | Personal site URL. Optional — some collaborators have no public site. |
| `joinedYear` | yes | number | Used for sort order. |
| `optInPublic` | yes | bool | Filter key. Only `true` entries render anywhere on the public site. |

**Empty Layer B.** When the filter (`optInPublic: true`) returns zero entries, only Layer B unmounts (no internal divider, no stats line, no grid). Layer A continues to render the community CTA + body as the block's resting state. When the filter returns 1–5 entries, render what exists (no minimum-six requirement); the visual rhythm degrades gracefully.

The retired `home.network.communitySignal.heading` ("Open access. Curated review.") is **dropped** in the merge — the merged block has one H2; the inner H3-equivalent demotes to `communityEyebrow`.

### Component composition

| Layer | Component | Path |
|---|---|---|
| Block | `<TheNetworkAndCommunity />` (server component, async — calls `getTranslations('web.home.networkAndCommunity')` and `getNetworkPreview()` at build time) | `apps/web/src/components/home/the-network-and-community.tsx` |
| Section header | inline header — eyebrow + H2 + lede | hardcoded in `the-network-and-community.tsx` |
| Layer A — community CTA cluster | inline `<div>` — `communityEyebrow` + `communityBody` + `rosterCta` + `communityCta` | hardcoded in `the-network-and-community.tsx` |
| Layer A → Layer B divider | `<div className="border-t border-grid">` (`data-testid="layer-divider"`) | hardcoded; renders only when `roster.length >= 1` |
| Layer B — stats line | inline `<p>` with mono typography | hardcoded in `the-network-and-community.tsx` |
| Layer B — card grid | `<ul>` of `<PersonCard />` (`data-testid="roster-grid"`) | `apps/web/src/components/network/person-card.tsx` |
| `rosterCta` link | `<Link>` (locale-aware, in-app `/network` route) | `@rapoport-studio/i18n/navigation` |
| `communityCta` link | `<a href={studio.signupUrl}>` (cross-domain to `app.rapoport.studio/community/signup`) | inline; `studio.signupUrl` from `@rapoport-studio/config` per `web.md § Community signup CTA target` |

`<PersonCard />` is reused on `/network` (full roster) and inside MDX case-study `<TeamCredits />` callouts. The homepage instance uses the same component with no variant prop.

### Visual contract

**Section.** `border-t border-grid` (0.5px), `py-32 md:py-40`. `data-screen-label="09 The network & community"` for storytelling overlays.

**Eyebrow / Heading / Lede.** Same scale as preceding blocks (per `flows.md § Page invariants` audience-tag invariant — `AudienceTag tone="spc"` sits at the top of the visual contract once the wrapper ships in `packages/ui`; until then the eyebrow carries the cohort signal).

**Layer A cluster.** Sits below the section header. Order: `communityEyebrow` (mono, accent, `--text-micro`) → `communityBody` (serif, `text-base`, `leading-[1.7]`, `text-ink-light`, `max-w-[56ch]`) → secondary-link row (`rosterCta` then `communityCta`, separated by a 16px gap, both styled per `flows.md § Page invariants` invariant 1 — mono, blueprint, underlined). Both links use `font-serif text-blueprint border-b border-blueprint pb-1 inline-block`; hover transitions colour (`text-blueprint-light`) and underline (`border-blueprint-light`).

**Internal divider.** `border-t border-grid mt-16 pt-16` between Layer A and Layer B. Only renders when Layer B renders. When Layer B is absent, no internal divider; Layer A occupies the full block.

**Layer B stats line.** `font-mono text-xs uppercase text-ink-light tracking-[0.15em] mt-0 mb-12`. Sits above the grid. The `·` separator is a real character, not a pseudo-element.

**Layer B card grid.** `grid grid-cols-2 md:grid-cols-3 gap-6`. Two columns on mobile (preserves portrait visibility), three columns on tablet+ (the homepage preview is denser than `/network`'s grid by intent — six cards, three across).

**Layer B card.** No tactical frame (preserves visual lightness vs the framed Now-building cards). Inner layout: portrait (`aspect-square`, `object-cover`), name (`font-serif text-base text-ink mt-3`), role (`font-mono text-xs uppercase text-ink-light mt-1 tracking-[0.1em]`), location (`font-mono text-xs text-ink-light mt-1`). Personal-site link, when present, wraps the entire card via the standard CSS-only "card anchor" pattern; when absent, the card is non-interactive.

**Forbidden in this block.** No avatar fallback (silhouette glyph) — every Layer B entry must have a portrait or be excluded from `optInPublic`. No social-icon row (Twitter/GitHub icons) — the personal-site link is the only outbound. No "View profile" button — the entire card is the link. No second H2 inside the block — the merged block has exactly one heading; the community sub-theme is signalled by `communityEyebrow` only. No primary-button styling on `rosterCta` or `communityCta` — both are secondary links per invariant 1.

### Motion contract

Block-level entry inherits the entry contract that the deleted `§ The network § Motion contract` and `§ Community signal § Motion contract` carried — entry-from-bottom with stagger across Layer A children, per `design-motion.md § Card reveal sequence` and `§ Choreography rules`.

Layer B, when present, carries its own staggered entry across `PersonCard`s — same contract as the deleted `§ The network § Motion contract` for the roster grid:

| Phase | Trigger | What animates |
|---|---|---|
| Layer A header reveal | Block enters viewport (threshold 0.2) | Section header + community cluster fade-in / rise per `design-motion.md § Card reveal sequence`. |
| Internal divider fade | Same `inView` trigger as Layer B (only when Layer B renders) | Short fade-only transition (180ms `--ease-settle`); the divider lands last. |
| Card fade | Card enters viewport (threshold 0.2) | `opacity 0` → `1` over 360ms `--ease-settle`. No transform on cards (portraits are stable). |
| Inter-card stagger | Multiple cards visible | 60ms delay between consecutive cards in DOM order. |
| Image load | Per-image | Portraits fade in as they load over their network response. No skeleton placeholder. |

**Hover.** Card with personal-site link: name transitions `text-ink` → `text-ink-light` (120ms), portrait subtly desaturates (`filter: saturate(0.85)`, 200ms). Cards without a link have no hover state. Secondary links use the standard colour-and-underline hover transition (120ms).

**Reduced-motion fallback.** Per `design-motion.md § Reduced motion`: all animations collapse to opacity-only transitions. Cards render at final opacity. Image fade-on-load suppressed. Internal divider renders without fade.

### Responsive contract

| Breakpoint | Behavior |
|---|---|
| `< 600px` | Single-column Layer A. Layer B grid is two columns; cards stack vertically — portrait on top, name + role + location below. Secondary links wrap to two rows when needed. |
| `≥ 768px` | Layer B grid is three columns. Secondary links sit on a single row. |
| `≥ 1200px` | Three-column Layer B grid persists; centered within `max-w-page`. Wider gutters but no 4-column expansion. |

Touch targets: each Layer B card link ≥ 44px tall via the portrait dimension (~120px minimum on mobile). Non-link cards have no touch target. Both secondary links have ≥ 44px tappable height via `pb-1` underline + line-height padding.

### Accessibility contract

- Section is `<section id="network-and-community" aria-labelledby="network-and-community-heading">`.
- Heading is `<h2 id="network-and-community-heading">`. Single H2 per block; `communityEyebrow` is `<p>` with mono styling, not a heading.
- Layer A community body is `<p>` with serif styling.
- Both secondary links are `<a>` (the `rosterCta` uses `<Link>` from `@rapoport-studio/i18n/navigation`; the `communityCta` is a raw `<a>` because it crosses domain to `app.rapoport.studio`).
- Layer B stats line is `<p>` with the mono styling, non-interactive.
- Layer B card grid is `<ul>` with each card as `<li>`. Each card is `<article>`.
- Layer B card name is `<h3>` per row.
- Portraits have `alt=""` (decorative — name carries the identity). Screen-readers announce name + role + location, not a redundant image description.
- Personal-site link wraps the card via `::before` overlay anchor; the focusable target is the name link. External-link convention: same tab (no `target="_blank"`), per `design-system.md § Hover & press` interaction conservatism.
- Focus order: section header → `rosterCta` → `communityCta` → (when Layer B renders) cards left-to-right top-to-bottom.
- Empty-Layer-B behavior: Layer B `<ul>` and stats `<p>` absent from DOM; page outline keeps the merged block's `<h2>` (the block always mounts).

### Localization

Ships in all three locales for chrome (`eyebrow`, `heading`, `lede`, `communityEyebrow`, `communityBody`, `rosterCta`, `communityCta`, `stats`).

Card content (`name`, `role`, `location`) is sourced from JSON and English-only at launch (per `web.md § Locale strategy` line 111: "Network roster bios — English-only"). The studio's network is internationally distributed; localizing roles into Romanian and Russian without a translation budget would either delay launch or produce uneven quality. English is the canonical surface.

Translation keys (chrome):
- `home.networkAndCommunity.eyebrow`
- `home.networkAndCommunity.heading` (new value: "The network & community"; translators sign off on RU/RO equivalents)
- `home.networkAndCommunity.lede`
- `home.networkAndCommunity.communityEyebrow`
- `home.networkAndCommunity.communityBody` (single paragraph; expansion to a triplet is a separate proposal)
- `home.networkAndCommunity.rosterCta`
- `home.networkAndCommunity.communityCta`
- `home.networkAndCommunity.stats` (rich-text — `{count}` and `{cities}` placeholders preserved across locales)

`stats` rich-text rule: the placeholders are part of the contract. Translators receive a string like `"{count} collaborators · {cities} cities"` and must keep both placeholders.

The previous `home.network.*` namespace and the nested `home.network.communitySignal.*` keys are migrated and retired. See `archive/2026-05-12-merge-community-signal-into-network/design.md § i18n migration` for the one-to-one mapping.

### Out of scope

- **Full roster.** Lives on `/network`.
- **Filter chips by discipline.** Live on `/network` only (per `web.md § /network` line 154). Homepage preview shows the cross-section without filters.
- **Search.** Not on the homepage; not on `/network` at v1.
- **Sort controls.** Sort is fixed (most recent first, by `joinedYear`).
- **Expanded card detail / modal preview.** Cards link to personal sites or are non-interactive. No in-page expansion.
- **Per-person contact form.** All inbound goes through `/contact`.
- **Disciplines as visible card metadata.** `disciplines[]` exists in JSON and powers the `/network` filter chips, but the homepage preview shows only role text.
- **Expanding `communityBody` into a registration / apprenticeship / adversarial-review triplet.** Single paragraph today; expansion is a separate proposal (out of scope per the change's `proposal.md § Out of scope`).
- **Live community counters.** Deferred per RAP-82 D-11; placeholder body remains until `add-community-canvas-and-archetypes` ships.

### References

- `design-system.md § Animation` — fade-in stagger.
- `design-system.md § Typography` — serif name, mono role/location.
- `design-system.md § Hover & press` — desaturation hover convention.
- `design-system.md § Imagery` — portrait conventions.
- `design-motion.md § Card reveal sequence` — block-level entry contract.
- `design-components.md § AudienceTag wrapper` — `tone="spc"` cohort signal (introduced by `extend-home-typography-and-audience-tag`).
- `web.md § Page contracts › /` — block 9 in the page sequence; six-card preview requirement for Layer B.
- `web.md § Page contracts › /network` — full roster behavior; filter chips.
- `web.md § Content principles` — "Network as first-class brand asset" rule.
- `web.md § Content storage` — `network.json` schema.
- `web.md § Marketing-specific components` — `<PersonCard />` component table entry.
- `web.md § Community signup CTA target` — `studio.signupUrl` resolution for `communityCta`.
- `home.md § Now building` — sibling block; same empty-state pattern (degraded grid).
- `archive/2026-05-12-merge-community-signal-into-network/` — the merge proposal and i18n migration mapping.

---

## Services

> Two columns. We take on / We don't. Mono-pill bullets. A closing italic note. The boundary that prevents wasted intake.

### Purpose

Set engagement boundaries early. The "What we don't" column is load-bearing for intake quality (per `web.md § Content principles` line 183: "the 'What we don't' column on /services is load-bearing — it prevents wasted intake"). A homepage visitor who reads this block and recognizes their project in the right column saves both the studio and themselves a wrongly-directed intake form.

The block previews the same content as the `/services` "What we take on / What we don't" subsection (per `web.md § /services` line 158) — same component, same copy, smaller surface area. Reuse rather than restate.

### Intro

The block opens with a single-paragraph prose intro above the five-card grid. The intro acknowledges that engagements arrive in three shapes — **Founder-led**, **Client-led**, **Specialist-led** — and names how the studio composes around them in one sentence each. The intro ends with a single secondary link (per `flows.md § Page invariants` invariant 1) pointing at `/founders` for founders walking into architecture diligence.

The intro is **not** a card grid. It is a continuous prose paragraph with three highlighted archetype names rendered inline (semibold, ink) and one trailing secondary link. The intro replaces the deleted `§ Design first` block per `collapse-design-first-into-services`.

i18n keys: `home.services.intro.body`, `home.services.intro.archetypeLabels.{founderLed, clientLed, specialistLed}`, `home.services.intro.foundersLink`.

### Position in page narrative

Block 7. Sits between `The network` and `Lab preview`. Boundary-setting beat between capability beats (Network: who we are) and credibility beats (Lab preview: how we think).

The block immediately before is `The network`. The block immediately after is `Lab preview`.

### Content contract

| Field | Required | Type | Source | Notes |
|---|---|---|---|---|
| `eyebrow` | yes | string | `home.services.eyebrow` | 2–4 words. Mono caps. |
| `heading` | yes | string | `home.services.heading` | One sentence, ≤8 words. |
| `lede` | yes | string | `home.services.lede` | 2–3 sentences. **Must include the €50,000 engagement floor and the 6-month minimum.** Same constraints as `/services` lede (per `web.md § /services` line 158). |
| `takeOnHeading` | yes | string | `home.services.takeOnHeading` | Column header. ≤4 words. Default: "We take on". |
| `dontTakeHeading` | yes | string | `home.services.dontTakeHeading` | Column header. ≤4 words. Default: "We don't". |
| `takeOn[]` | yes | array of strings | `home.services.takeOn` | ~5 items. Each item ≤14 words. |
| `dontTake[]` | yes | array of strings | `home.services.dontTake` | ~5 items. Each item ≤14 words. |
| `note` | yes | string | `home.services.note` | One italic sentence below both columns. |

Each item in `takeOn[]` / `dontTake[]` is a single phrase, not a paragraph. The list is scannable; visitors recognize themselves in 8 seconds or move on.

### Component composition

| Layer | Component | Path |
|---|---|---|
| Block | `<Services />` (server component, async) | `apps/web/src/components/home/services.tsx` |
| Take-on column | `<ServiceList tone="takeOn">` | `apps/web/src/components/services/service-list.tsx` |
| Don't-take column | `<ServiceList tone="dontTake">` | same file, internal `tone` prop |
| Closing note | inline `<p>` | hardcoded in `services.tsx` |

`<ServiceList />` is reused on `/services` for the same content shape. Same component, same items array, no variant divergence between homepage and `/services`. The single source of truth is the i18n catalog.

### Visual contract

**Section.** `border-t border-grid` (0.5px), `py-32 md:py-40`.

**Eyebrow / Heading / Lede.** Same scale as preceding blocks.

**Two-column layout.** `grid grid-cols-1 md:grid-cols-2 gap-8 md:gap-16 mt-16`. Stacked on mobile (take-on first, don't-take second); side-by-side on tablet+ with a 0.5px vertical grid divider between (`md:divide-x md:divide-grid` or equivalent).

**Column header.** `font-mono text-xs uppercase text-ink-light tracking-[0.15em] mb-8`.

**List item.** Each item is a row with a leading `StatusPill` bullet and the item text:
- **Take-on bullet.** Terracotta dot inside mono `LIVE`-style pill (no label text, just the dot at ~6px).
- **Don't-take bullet.** Ink-light dot inside the same pill structure.
- **Item text.** `font-serif text-base leading-[1.6] text-ink mt-1 ml-4`.

Item rows have `py-3` spacing; no inter-item divider (whitespace alone carries the rhythm).

**Closing note.** `font-serif italic text-ink-light text-base text-center max-w-[56ch] mx-auto mt-16`. The italic typography signals studio voice closing the section.

**Forbidden in this block.** No checkmark / X glyphs (the colored bullet dots carry the signal). No expandable items. No icons inside list items. No numbered list (the items are unordered set, not sequence).

**Intro paragraph.** Sits below the H2 + lede and above the five-card grid. Same `max-w-prose` width as the lede. Body type token `--text-body`; archetype labels at `--text-body` semibold ink (`font-semibold text-ink`); secondary link mono blueprint underlined (`font-mono text-[12px] tracking-[0.2em] uppercase text-blueprint underline`).

### Renders if

The intro renders unconditionally. The five-card grid was already unconditional; the intro inherits that contract.

### Motion contract

List items reveal on intersection.

| Phase | Trigger | What animates |
|---|---|---|
| Item fade | Item enters viewport (column-level threshold 0.3) | `opacity 0` → `1` over 360ms `--ease-settle`. |
| Inter-item stagger | Multiple items visible | 40ms delay between consecutive items in DOM order. Faster than the 60ms card stagger — list rhythm, not card rhythm. |
| Closing note fade | Note enters viewport | `opacity 0` → `1` over 400ms `--ease-settle`. |

**Hover.** None. The block is read-only narrative.

**Reduced-motion fallback.** All items render at final state. No transitions.

### Responsive contract

| Breakpoint | Behavior |
|---|---|
| `< 768px` | Stacked vertically: take-on column above don't-take column. No vertical divider between (the visual separation is the column header break). Section padding shrinks to `py-24`. |
| `≥ 768px` | Two-column side-by-side. 0.5px vertical grid divider between. |
| `≥ 1200px` | Same layout, centered within `max-w-page`. Wider gutters between columns. |

Touch targets: not applicable — items are non-interactive.

### Accessibility contract

- Section is `<section id="services" aria-labelledby="services-heading">`.
- Heading is `<h2 id="services-heading">`.
- Each column header is `<h3>` (visually styled per visual contract above).
- Each list is `<ul>` with `<li>` per item. The `<ul>` carries the unordered semantic; the colored bullet is decorative (`aria-hidden="true"` on the bullet element).
- Item text is the `<li>` contents; no nested `<p>` (single-paragraph items don't need the wrapper).
- Closing note is `<p>` (italic via CSS, not `<em>` — the italic is voice, not emphasis).
- Focus order: previous block's last interactive element → next block's first interactive element. The block has no focusable elements.
- Color contrast: ink/canvas (item text), ink-light/canvas (note), accent/canvas (take-on bullet) all AA-compliant.

### Localization

Ships in all three locales for all fields.

Translation keys:
- `home.services.eyebrow`
- `home.services.heading`
- `home.services.lede`
- `home.services.takeOnHeading`
- `home.services.dontTakeHeading`
- `home.services.takeOn` (array — translators receive ordered list, translate item-by-item, may reorder within the list)
- `home.services.dontTake` (array — same rule)
- `home.services.note`

**Lede must mention €50,000 + 6-month** in every locale. Translators may render the threshold in locale-appropriate currency notation (`€50.000` / `50 000 €` / `€50,000`) but the number itself is fixed.

### Out of scope

- **Engagement-shape detail.** Lives on `/services` (per `web.md § /services` line 158: "Engagement shapes — Bespoke platform / AI orchestration retrofit / Compliance-grade build").
- **Pricing tiers, package matrix.** Studio engagement is bespoke; no fixed packages.
- **Comparison matrix vs other studios.** Out of brand voice.
- **FAQ.** Lives on `/services` (or doesn't exist; not in this PR's scope).
- **Per-item link to a case study.** Items are categorical, not specific; no per-item evidence link.
- **Customer testimonials.** None at v1.

### References

- `design-system.md § Tactical components › StatusPill` (line 420) — bullet-pill spec. Implemented at `packages/ui/src/components/status-pill.tsx`; see `ui.md § Component inventory § Studio components`.
- `design-system.md § Typography` — serif item text, italic closing note.
- `design-system.md § Layout rules` — two-column responsive convention.
- `design-system.md § Animation` — 40ms list-item stagger (lighter than card stagger).
- `web.md § Page contracts › /` — block 7 in the page sequence; "two-column 'we take on / we don't'".
- `web.md § Page contracts › /services` — full services page; same `<ServiceList />` component reused.
- `web.md § Marketing-specific components` — `<ServiceList />` component table entry.
- `web.md § Content principles` — load-bearing "What we don't" rule.

---

## Lab preview

> Three most recent posts. Card-grid layout. Hidden when the lab has no posts. Signal that the studio writes — proof of practice beyond delivered platforms.

> **Conditional on `/lab` having published content.** Per RAP-1190 D-HTN-3 split policy and `archive/2026-05-24-sync-home-arc-with-rap-1190/design.md § D-SHA-1`, this block is mounted in `apps/web/src/app/[locale]/(marketing)/page.tsx` but returns `null` until the Lab corpus is non-empty. Counted as a conditional thirteenth block in `flows.md § Page narrative arc`, not as a visible block — does not contribute to the twelve-visible-block invariant in `flows.md § Page invariants 3`.

### Purpose

Signal that the studio thinks out loud. Architecture notes, methodology, network observations — not blog posts in the SEO sense, but written artefacts of practice. The Lab preview provides the credibility beat between the Services boundary and the Closing CTA: a visitor who reads here sees the studio engages with its own ideas in public.

The block also serves as a long-tail SEO anchor. Lab articles index for technical queries; the homepage preview surfaces new posts to returning visitors and search crawlers.

### Position in page narrative

Block 8. Sits between `Services` and `Closing CTA`. The "we think out loud" beat before the closing ask.

The block immediately before is `Services`. The block immediately after is `Closing CTA`.

### Content contract

| Field | Required | Type | Source | Notes |
|---|---|---|---|---|
| `eyebrow` | yes | string | `home.lab.eyebrow` | 2–4 words. Mono caps. |
| `heading` | yes | string | `home.lab.heading` | One sentence, ≤8 words. |
| `lede` | yes | string | `home.lab.lede` | 1–2 sentences. |
| `cta` | yes | string | `home.lab.cta` | Link label to `/lab`. Trailing arrow `→` is part of the string. |
| `posts[]` | yes | fixed array of 3 | `content/lab/*.mdx` sorted by frontmatter `publishedAt` desc, take first 3. | Only renders if at least 1 post exists. |

**Per-card frontmatter contract** (defined by `content/lab/*.mdx` shape):

| Frontmatter field | Required | Type | Notes |
|---|---|---|---|
| `title` | yes | string | Post title. |
| `slug` | yes | string | URL slug. |
| `excerpt` | yes | string | One-sentence preview. ≤30 words. |
| `readTime` | yes | string | Computed at build time. e.g., "8 min read". |
| `publishedAt` | yes | ISO date | Used for sort order. |
| `topic` | yes | enum | Used for `/lab` filter chips (when chips exist). Not surfaced on homepage card. |

**Empty state.** When `content/lab/` is empty (zero posts), the entire `## Lab preview` section does not render. No "lab launching soon" copy, no placeholder card. Mirrors `Now building` and `The network` patterns. The page outline skips from `Services` directly to `Closing CTA`.

When `content/lab/` has 1–3 posts, the block renders per the count-trigger render rule below. The mode is chosen by `posts.length`, not by per-post editorial intent.

### Component composition

| Layer | Component | Path |
|---|---|---|
| Block | `<LabPreview />` (server component, async — reads MDX at build time) | `apps/web/src/components/home/lab-preview.tsx` |
| Card | `<PostCard mode="default" \| "featured" />` | `apps/web/src/components/lab/post-card.tsx` |
| CTA link | `<Link>` | `@rapoport-studio/i18n/navigation` |

`<PostCard />` is reused on `/lab` (full archive). On the index page, `/lab` chooses its own mode per its own contract; the home block selects mode by count per the render rule below.

### Render rule

| Component | Mode | Count | Renders when |
|---|---|---|---|
| `PostCard` | `featured` | exactly 1 | `posts.length === 1` |
| `PostCard` | `default` | 2 or 3 | `posts.length >= 2` (capped at 3) |

When the Lab corpus carries exactly one post, that post renders as a single full-width `featured` `PostCard`. When the second post ships, the block reverts to a 3-up grid of `default` `PostCard`s. The container block (`§ Lab preview`) controls mode selection per `design-components.md § Canonical wrappers › PostCard`. The featured post is `posts[0]` — the most recent by publish date; no separate editorial mechanism picks the featured slot.

### Visual contract

**Section.** `border-t border-grid` (0.5px), `py-32 md:py-40`.

**Eyebrow / Heading / Lede.** Same scale as preceding blocks.

**Card grid.** `grid grid-cols-1 md:grid-cols-3 gap-8 mt-16`. Three columns at desktop; single column on mobile (no 2-column intermediate — the card content is dense enough that 2-up reads cramped). No tactical frame around cards (preserves visual lightness vs framed Now-building cards; the lab is for reading, not display).

**Card.** Inner layout:
- Title (`font-serif text-xl text-ink leading-tight mb-3`).
- Excerpt (`font-serif text-base leading-[1.6] text-ink-light mb-4`).
- Meta row: `<MetaBar>` with `{readTime} · {publishedAt formatted as 'MMM yyyy'}` (`font-mono text-xs uppercase text-ink-light tracking-[0.1em]`).

The card surface is fully clickable via the title link (CSS-only "card anchor" pattern, ::before overlay). Cards have no border, no background, no shadow.

**CTA link.** Same style as `The network` CTA: `font-serif text-blueprint border-b border-blueprint pb-1 mt-16 inline-block`. Hover transitions both color and underline.

**Forbidden in this block.** No card images / hero illustrations per post. No author byline (single-author at v1 — Pavel; surfacing the byline would re-center on the founder against `platform.md` rule). No comments / share counts / reaction emoji. No featured-post highlighting.

### Motion contract

Cards reveal on intersection.

| Phase | Trigger | What animates |
|---|---|---|
| Card fade | Card enters viewport (threshold 0.2) | `opacity 0` → `1` over 360ms `--ease-settle`. Slight `translateY(8px) → 0`. |
| Inter-card stagger | Multiple cards visible | 60ms delay between consecutive cards in DOM order. |

**Hover.** Card title transitions `text-ink` → `text-ink-light` (120ms). Excerpt and meta unchanged. No scale, no shadow.

**Reduced-motion fallback.** All cards render at final state with no transform.

### Responsive contract

| Breakpoint | Behavior |
|---|---|
| `< 600px` | Single column. Cards stack with 24px gap. |
| `≥ 600px` | Single column persists (avoid 2-up cramping). |
| `≥ 1024px` | Three-column grid with 32px gap. |
| `≥ 1200px` | Same three-column, centered within `max-w-page`. |

Touch targets: each card title link ≥ 44px tall via the title font-size + line-height. The CSS-only card-anchor extends the touch area to the full card surface.

### Accessibility contract

- Section is `<section id="lab" aria-labelledby="lab-heading">` (rendered only if at least 1 post exists).
- Heading is `<h2 id="lab-heading">`.
- Card grid is `<ul>` with each card as `<li>`. Each card is `<article>`.
- Card title is `<h3>` per row, wrapping a `<Link>`.
- Excerpt is `<p>`.
- Meta is `<p>` with text-only dot separators (real `·` characters, not pseudo-elements).
- Empty-state behavior: section absent from DOM; outline skips from `Services` `<h2>` to `Closing CTA` `<h2>`.
- Focus order: tab moves through card title links left-to-right top-to-bottom, then to the CTA link.
- Color contrast: ink/canvas (titles), ink-light/canvas (excerpts and meta) AA-compliant.

### Localization

Ships in all three locales for chrome (`eyebrow`, `heading`, `lede`, `cta`).

Post content (title, excerpt, body) is MDX, English-only at launch (per `web.md § Locale strategy` line 110: "Long-form MDX — English-only"). Romanian and Russian visitors see English post cards with localized chrome.

Translation keys (chrome):
- `home.lab.eyebrow`
- `home.lab.heading`
- `home.lab.lede`
- `home.lab.cta`

Date formatting on the meta row uses the visitor's locale via `Intl.DateTimeFormat` (e.g., `Intl.DateTimeFormat('ru', { year: 'numeric', month: 'short' })` produces `"янв. 2026"`). The `publishedAt` ISO date is locale-neutral; only the rendered string varies.

### Out of scope

- **Full lab archive.** Lives on `/lab`.
- **Topic filter chips.** Live on `/lab` once 10+ posts exist (per `web.md § /lab` line 166).
- **Author bylines on cards.** Single-author at v1 — Pavel; the studio voice rule keeps him uncredited at the card level.
- **Comments, reactions, share controls.** None at v1.
- **Related-post suggestions.** Per-post related posts are an `/lab/[slug]` feature, not homepage.
- **Featured / pinned posts.** Sort is strictly reverse-chronological.
- **RSS / newsletter signup.** Out of scope until subscription channels exist.

### References

- `design-system.md § Animation` — fade + 8px translate-y reveal.
- `design-system.md § Typography` — serif title and excerpt, mono meta.
- `design-system.md § Tactical components › MetaBar` — meta-row spec.
- `web.md § Page contracts › /` — block 8 in the page sequence; "3 most recent posts; entire section hidden if `content/lab/` is empty".
- `web.md § Page contracts › /lab` — full archive; topic filter chip rule.
- `web.md § Content storage` — MDX frontmatter contract.
- `web.md § Marketing-specific components` — `<PostCard />` component table entry.
- `home.md § Now building` — sibling block; same empty-state pattern.
- `home.md § The network` — sibling block; same CTA-link visual style.

---

## Closing CTA

> The last ask. Larger type, no frame, paired with the same primary CTA as the hero. The mirror of the hero at the other end of the page.

### Purpose

Convert a visitor who has read the page but not yet acted. By the time a visitor reaches this block, they've seen the orchestra thesis, current work, the process, the network, the services boundary, and (optionally) lab posts. The closing block presents one clean ask with no distractions.

The closing must feel like a quiet statement, not a sales push. Copy is literary, not exclamatory. One sentence with a parenthetical italic clause is the entire heading; one paragraph of expectation-setting follows; one CTA. That's it.

### Position in page narrative

Tenth block of the eleven (the eleventh is the always-mounted `StickyCTA`, which technically renders alongside the page rather than inline). Comes after `Lab preview` (or after `Services` if `Lab preview` is hidden because no posts exist). The `Footer` follows it.

This is the block whose `id="contact"` is observed by `<StickyCTA>` — when the closing scrolls into the middle of the viewport, the floating sticky CTA hides itself, because the in-place CTA is now visible.

### Content contract

| Field | Required | Type | Source | Notes |
|---|---|---|---|---|
| `heading` | yes | rich-text string | `home.closing.heading` | One sentence with one inline `<em>` segment. Total length ≤ 14 words. Italic clause is the action ("Tell us about your project"); root clause is the question ("Have a brief?"). |
| `sub` | yes | string | `home.closing.sub` | 2–3 sentences. Must set response-time expectation (48 hours). Must mention the alternative ("polite redirect to someone better suited"). |
| `startProject` | yes | string | `cta.startProject` | Same key the hero uses. One source of truth for this label. |

No secondary CTA. Removed in current iteration; `web.md § Page contracts › /` block 9 is updated to reflect this.

No email. The previous `or hello@rapoport.studio` line was removed because the studio doesn't operate that mailbox today; the only route is through `/contact`.

### Component composition

| Layer | Component | Path |
|---|---|---|
| Block | `<ClosingCTA />` (server component, async) | `apps/web/src/components/shared/closing-cta.tsx` |
| Locale-aware link | `<Link>` | `@rapoport-studio/i18n/navigation` |

Lives under `components/shared/` because it's reused on other marketing pages — `/work`, `/services`, `/network`, `/lab` all close with this same block (per `web.md`, though those pages aren't ported yet). The hero, by contrast, lives under `components/home/` because it's homepage-only.

No tactical frame. The closing is intentionally unframed — the absence of brackets at the bottom of the page balances the heavy bracketed hero at the top. Frame as opening gesture, no-frame as closing gesture.

### Visual contract

**Section.** `border-t border-grid` (0.5px grid line above), `py-32 md:py-40`. The grid divider above is the same `--color-grid` 0.5px rule that separates every section on the page; the closing doesn't get a louder divider.

**Heading.** Renders as `h2` at `--text-display-xl`, `text-ink`, `max-w-[16ch]`, `mb-6`. Pairs with the Hero block; same ramp ceiling, opposite end of the page. The `<em>` segment is `italic font-medium text-ink-light` — same lightening trick as the hero headline.

**Sub.** `font-serif`, `text-lg`, `leading-[1.7]`, `text-ink-light`, `max-w-[56ch]`, `mb-12`. Identical typography to the hero sub — same family, size, color, line-height. The two ends of the page rhyme.

**Primary CTA.** Identical to the hero primary CTA: `bg-ink text-canvas border border-ink px-6 py-[14px]`, sharp corners, color-only hover. One source of truth for the CTA visual; the second instance must not drift.

**Forbidden in this block.** No frame (no `TacticalFrame`). No secondary CTA. No icons, no images, no email link, no social links (those are the footer's job), no testimonials, no pricing.

### Motion contract

**Entry.** None. The closing does not deploy brackets, does not scale a blueprint line, does not fade. It appears on scroll with no animation. By this point in the page the visitor doesn't need theatrical entry.

**Hover.** Same as hero primary CTA: 120ms color transition on `bg` and `border`. No scale.

**Scroll.** The closing's `id="contact"` is intersection-observed by `<StickyCTA>`. When more than 30% of the section is in the viewport (from either edge), the floating sticky hides. When it scrolls back out, sticky reappears (if hero is also out of view).

**Reduced-motion fallback.** Trivially compliant — there are no animations to disable.

### Responsive contract

| Breakpoint | Behavior |
|---|---|
| `< 600px` | Heading clamps down to 36px. Section padding becomes `py-32`. CTA stays full-text (no icon-only collapse). |
| `≥ 768px` | Heading reaches 56px ceiling around 1120px viewport. Section padding `py-40`. |
| `≥ 1200px` | Centered within `max-w-page` parent (the page-level container, set on `<main>`). |

Touch target on the CTA: same 45px tall as the hero's primary. Acceptable.

### Accessibility contract

- Wrapped in `<section id="contact">`. The `id` is consumed by `<StickyCTA>`'s observer and by anchor links (`<a href="#contact">` from the nav and footer's "Contact" link).
- Heading is `<h2>` — second in the page outline, after the hero's `<h1>`. There are seven `<h2>` blocks total on the homepage (one per section); the closing is the last of them.
- The `<em>` is semantic emphasis. The closing question becomes "Have a brief? *Tell us about your project.*" in screen-reader output, with the italic clause carrying emphasis intonation.
- Single `<a>` element for the CTA, focusable, default focus ring (1px blueprint outline, 2px offset).
- No focus traps. Tab order: previous block's last interactive element → CTA → footer's first interactive element.
- Contrast: ink/canvas and ink-light/canvas as in the hero — both AAA in dark mode.

### Localization

Ships in all three locales: `en` (default), `ru`, `ro`. All three content fields are required. No English fallback.

Translation keys:
- `home.closing.heading` (rich-text — must contain one `<em>...</em>` pair)
- `home.closing.sub`
- `cta.startProject` (shared)

The italic clause in `heading` must remain a complete clause that can stand alone as the action statement. In Russian: `Расскажите о проекте.` In Romanian: `Spune-ne despre proiectul tău.` The translator's freedom is in the wording, not in the structure.

### Out of scope

- **Form embedded in the closing.** The closing's job is to be the ask, not the form. The form lives on `/contact`. A future iteration may inline a minimal email-capture, but that requires reopening the spec.
- **Email / Telegram / WhatsApp links.** Reach channels are footer-only. The closing is single-CTA on purpose.
- **Calendar booking, Cal.com, Calendly.** `web.md § Out of scope` is explicit — intake is the only conversion path.
- **Newsletter signup.** Out of scope until there's a newsletter to sign up to.
- **Social proof (logo strip, testimonials).** Out of scope here. If we add social proof, it goes earlier in the page (between Network and Services), not in the closing.

### References

- `design-system.md § Hard constraints` — radius 0, no shadows, no emoji, no cockpit clichés.
- `design-system.md § Typography` — Lora display.
- `web.md § Page contracts › /` — block 9 in the page sequence (now without the email line).
- `home.md § Hero` — companion block at the other end of the page; CTA visuals must stay in sync.
- `home.md § Sticky CTA` — observer that consumes `#contact`.

---

## Sticky CTA

> The floating ask. Appears when the hero scrolls past, hides when the closing scrolls in. One pill, one CTA, one close-X. Never the loudest thing on the page.

### Purpose

Keep the primary ask in the visitor's field of view through the middle of the page. Between Hero (top of page) and Closing CTA (bottom of page) is a long scroll — the studio's case lives there, but the conversion path can disappear. The Sticky CTA recaptures intent by surfacing the same `Start a project` action the Hero and Closing CTA fire, anchored to the viewport rather than the document.

The block exists in DOM order between `Closing CTA` and `Footer` for spec readability, but renders as an overlay mounted by the marketing layout — not inline at this position. The page narrative arc diagram (lines 38–48) shows it as overlay-mounted, not in-flow.

### Position in page narrative

Block 10 in the file; conceptually overlay-mounted between block 2 (`Hero`) and block 9 (`Closing CTA`) in the rendered page. Not part of the document narrative — the visitor reads past it without scrolling through it.

The block immediately before in file order is `Closing CTA`. The block immediately after is `Footer`. Neither relationship matters in the rendered page (overlay).

### Content contract

| Field | Required | Type | Source | Notes |
|---|---|---|---|---|
| `startProject` | yes | string | `cta.startProject` | Same key the Hero, Closing CTA, and Nav use. One source of truth for the CTA label. |
| `closeLabel` | yes | string | `a11y.close` | Screen-reader label for the close-X button. Not visible. |

**No `home.stickyCta.*` namespace.** The Sticky CTA is pure CTA reuse — no copy specific to this surface. Adding a block-specific namespace would invite copy drift from the canonical CTA label.

### Component composition

| Layer | Component | Path |
|---|---|---|
| Block | `<StickyCTA />` (client component, uses `IntersectionObserver`) | `apps/web/src/components/shared/sticky-cta.tsx` |
| Mount point | marketing layout (`apps/web/src/app/[locale]/(marketing)/layout.tsx`) | mounted once, persistent across page navigations |
| Locale-aware link | `<Link>` | `@rapoport-studio/i18n/navigation` |

The component runs two `IntersectionObserver` instances — one observes `#hero` (the Hero block's section id), one observes `#contact` (the Closing CTA block's section id). State machine: `hidden | visible | dismissed`. Visibility computed as `(hero out of viewport) AND (contact <30% in viewport) AND (state !== dismissed)`.

The component is mounted in the marketing layout, not at the page level — it persists across page navigations within the marketing surface. (Studio subdomain pages do not mount it.)

### Visual contract

**Pill.** `bg-ink text-canvas border border-ink px-4 py-3` with `font-mono text-xs uppercase tracking-[0.15em]`. Sharp corners (radius 0). Same visual language as the Hero primary CTA — one source of truth for the CTA visual.

**Layout.** `fixed bottom-6 right-6 md:bottom-8 md:right-8 z-40`. Below modal z-index (modals are `z-50`+). Respects `env(safe-area-inset-bottom)` for iOS notched devices via `pb-[env(safe-area-inset-bottom)]` on the wrapper.

**Close-X.** `text-ink-light hover:text-ink ml-3 -mr-1`. Sits to the right of the CTA label inside the same pill. Click dismisses the CTA for the rest of the session.

**Backdrop / shadow.** None. The pill relies on backdrop contrast (`bg-ink` on `bg-canvas` in light mode, inverted in dark) — no drop shadow per `design-system.md § Borders, radius, shadows` ("no shadows").

**Forbidden in this block.** No drop shadow, no rounded corners, no animated glyph, no badge / counter / new-message indicator, no expandable variant. No "remind me later" option. No multi-action variants (the close-X is the only secondary action).

### Motion contract

| Phase | Trigger | What animates |
|---|---|---|
| Enter | Hero exits viewport (Hero IntersectionObserver `isIntersecting === false`) | Pill fades in (`opacity 0` → `1`) and translates up (`translateY(8px) → 0`) over 200ms `--ease-settle`. |
| Leave (closing approaches) | Closing CTA crosses 30% in viewport (Contact IntersectionObserver with `threshold: 0.3`) | Reverse: fade-out + translate-down over 200ms `--ease-settle`. |
| Leave (user dismisses) | Click on close-X | Same fade-out + translate-down. State flips to `dismissed`; observers stop affecting visibility for the session. |
| Hover on CTA | Pointer enter pill | 120ms color transition: `bg-ink-light border-ink-light`. (Same hover as Hero primary CTA.) |
| Hover on close-X | Pointer enter X | 120ms color transition: `text-ink`. |

**Reduced-motion fallback.** When `prefers-reduced-motion: reduce`: enter/leave snap (display none ↔ display flex) with no opacity transition, no transform. Hover color transitions still apply (color-only, not transform).

### Responsive contract

| Breakpoint | Behavior |
|---|---|
| `< 600px` | Bottom-center alignment (`bottom-4 left-4 right-4`), full-width minus 32px gutter. CTA label keeps the same text — no truncation. |
| `≥ 600px` | Bottom-right alignment (`bottom-6 right-6`), intrinsic width. |
| `≥ 768px` | Bottom-right (`bottom-8 right-8`), wider safe distance from page edge. |

Touch targets: pill height ≥ 44px (`py-3` × 2 + ~17px line-height ≈ 47px). Close-X tap area ≥ 44px (`p-2` minimum on the button element even if the visible glyph is smaller).

### Accessibility contract

- The block is `<aside aria-label="Quick action">` — not `<dialog>`. The Sticky CTA does not trap focus (it is non-modal), does not require dismissal to interact with the page, and does not interrupt the visitor's reading position.
- Inserted into the DOM at the marketing layout root, after `<main>`. Tab order picks it up after all in-flow content; visitors using `Tab` reach it after the Footer.
- CTA is `<a>` (rendered by `<Link>`), focusable, with the standard 1px blueprint outline / 2px offset focus ring.
- Close-X is `<button aria-label="{closeLabel}">`. The visible glyph is `×` (multiplication sign, not lowercase x — better visual weight).
- When `state === hidden`: `aria-hidden="true"` on the wrapper; pointer events disabled; the `<aside>` is removed from the screen-reader tree. When `state === visible`: `aria-hidden="false"`. When `state === dismissed`: same as hidden (aria-hidden + removed from interaction).
- The element does not auto-focus when it appears. The visitor's keyboard position is not interrupted.

### Localization

Ships in all three locales via shared chrome keys:
- `cta.startProject` (shared with `Hero`, `ClosingCTA`, `Nav`)
- `a11y.close`

No block-specific keys.

### Out of scope

- **Multi-action variants** (e.g., "Start a project / View work" two-button bar). One CTA, one action.
- **A/B copy variants.** The label is the canonical `cta.startProject`.
- **Scroll-progress integration.** The pill does not show a progress bar, scroll indicator, or "X% read" badge.
- **Dwell-time triggers.** Visibility is purely viewport-position based — not "after 30 seconds of reading".
- **Exit-intent triggers.** No mouse-out detection.
- **Persistent dismissal across sessions.** Close-X dismisses for the current session only (in-memory state, no `localStorage`). A returning visitor sees the pill again on the next session.
- **Mobile-app-style fixed CTA bar.** The Sticky CTA is a single floating pill on mobile too, not a full-width bottom bar.
- **Secondary contact channels** (Telegram quick-link, etc.). Reach lives in the Footer.

### References

- `design-system.md § Animation` — fade + 8px translate-y reveal pattern.
- `design-system.md § Hover & press` — 120ms color-only hover.
- `design-system.md § Hard constraints` — radius 0, no shadows.
- `design-system.md § Surfaces` — overlay z-index conventions.
- `web.md § Page contracts › /` — block 10 in the page sequence; "appears after hero scrolls past; hides when closing section enters the viewport".
- `web.md § Marketing-specific components` — `<StickyCTA />` component table entry.
- `home.md § Hero` — observer source: `#hero` section id consumed for visibility threshold.
- `home.md § Closing CTA` — observer source: `#contact` section id consumed for hide threshold (30%).
- `ui.md § Conventions` — overlay-mounted component pattern.

---

## Footer

> Page chrome that closes the document. Four columns. A bottom strip. Telegram is the only reach channel at launch.

### Purpose

Page chrome at the bottom of every marketing page. Provides locale control, legal access, and reach channels without competing with the Closing CTA above it. The Footer is functional, not narrative — visitors arrive here to find a link, not to be persuaded.

The same `<Footer />` component renders on every marketing page. Behavior must be identical across `/`, `/work`, `/services`, `/network`, `/lab`, `/contact`.

### Position in page narrative

Block 11. Last block in the file and last block in the page. Renders after `Closing CTA`. Not part of the narrative — a visitor who reaches the Footer has either acted on the Closing CTA or is leaving.

### Content contract

| Field | Required | Type | Source | Notes |
|---|---|---|---|---|
| `studioMark` | yes | string | `brand.studio` | Same value as Nav's `studioMark`. Wordmark, no glyph. |
| `studioDescriptor` | yes | string | `brand.descriptor` | One-line studio descriptor. ≤14 words. Sentence case. |
| `siteHeading` | yes | string | `footer.site.heading` | Column header. Default "Site". |
| `siteLinks[]` | yes | fixed array | `nav.{work,network,services,lab,contact}` | Same five anchors as Nav (plus Contact). Reused — no per-footer copy. |
| `reachHeading` | yes | string | `footer.reach.heading` | Column header. Default "Reach". |
| `reachLinks[]` | yes | array | `footer.reach.{telegram}` | **At launch:** Telegram only, single entry pointing to `https://t.me/{handle}`. WhatsApp + email entries deferred (see Out of scope). |
| `legalHeading` | yes | string | `footer.legal.heading` | Column header. Default "Legal". Renders even when zero legal links exist. |
| `legalLinks[]` | conditional | array | `footer.legal.{privacy,terms}` | Each entry rendered only when its corresponding route exists. **At launch:** zero rendered links (Privacy and Terms routes ship in a separate change). |
| `bottomCopyright` | yes | rich-text string | `footer.bottom.copyright` | Contains `{year}` placeholder. Example: `"© {year} Rapoport Studio SRL"`. Year computed at build time. |
| `localeSwitcher` | yes | derived | rendered from `i18n.md` locale list (`en`, `ro`, `ru`) | Three labels in their own scripts: "English" / "Română" / "Русский". |

### Component composition

| Layer | Component | Path |
|---|---|---|
| Block | `<Footer />` (server component, async — calls `getTranslations`) | `apps/web/src/components/footer.tsx` |
| Locale switcher | inline (uses `next-intl` `usePathname` + `<Link>` swap) | hardcoded in `footer.tsx` |
| Locale-aware links | `<Link>` | `@rapoport-studio/i18n/navigation` |

The Footer is reused on every marketing page (same component, same rendered output across `/`, `/work`, `/services`, `/network`, `/lab`, `/contact`). Lives at `components/footer.tsx` (root of marketing components) for that reason. No tactical frame — chrome, not content.

### Visual contract

**Section.** `bg-canvas border-t border-grid` (0.5px), `py-24`. Sits flush against the Closing CTA section above (the section's `border-t` is the visual break, not a margin gap).

**Column grid.** `grid grid-cols-1 md:grid-cols-4 gap-12 max-w-page mx-auto`.

**Column header.** `font-mono text-xs uppercase text-ink-light tracking-[0.15em] mb-6`. All four columns use this header style; the Brand column header is the studio mark itself rendered larger (`font-serif text-base text-ink mb-6`), not a "Brand" label.

**Brand column.** Studio mark (`font-serif font-medium text-base text-ink`), descriptor below (`font-serif text-sm text-ink-light leading-[1.6] mt-3 max-w-[28ch]`). No social-icon row.

**Site / Reach / Legal columns.** Vertical link list. Each link `font-serif text-base text-ink-light hover:text-ink leading-[1.8]`. No bullet, no underline. 4–8px spacing between links.

**Bottom strip.** `border-t border-grid mt-16 pt-8 flex justify-between items-center text-xs text-ink-light font-mono`. Copyright on the left, locale switcher on the right. (Brand mark in the bottom strip is omitted — it's already in the Brand column above; duplicating creates clutter.)

**Locale switcher.** Three locale labels rendered as `<a hreflang="{locale}">` elements with `·` separators between. The current locale is `aria-current="page"` and visually `text-ink` (vs `text-ink-light` for the others). Hover transitions to `text-ink` (120ms).

**Forbidden in this block.** No tactical frame. No newsletter signup form. No social icons. No payment-method icons. No "made with" / "powered by" credit. No country/region picker (locale switcher is the only language control).

### Motion contract

**Entry.** None. The Footer renders at final state on first paint. No fade-in, no reveal sequence — by the time a visitor reaches the Footer they don't need theatrical entry.

**Hover.** Color-only on link elements. 120ms transition on `color`. No background, no underline, no scale. Locale switcher entries hover the same way.

**Reduced-motion fallback.** Trivially compliant — there are no animations to disable. Hover transitions still apply (color-only).

### Responsive contract

| Breakpoint | Behavior |
|---|---|
| `< 768px` | Columns stack vertically with 32px gap. Brand column first, then Site, Reach, Legal. Bottom strip wraps onto two lines: copyright above the locale switcher. |
| `≥ 768px` | Four-column grid. Bottom strip single-row with copyright left, locale switcher right. |
| `≥ 1200px` | Same four-column grid, centered within `max-w-page`. |

Touch targets: each link ≥ 44px tall via the `leading-[1.8]` × `text-base` ≈ 29px line + adjacent link spacing. Locale switcher entries get explicit `py-2` to meet the 44px minimum on mobile.

### Accessibility contract

- The block is `<footer role="contentinfo">`. The `role` is explicit because some assistive tech doesn't infer the contentinfo landmark from the tag alone.
- Site, Reach, and Legal columns are each wrapped in `<nav aria-label="{siteHeading|reachHeading|legalHeading}">`. The Brand column is `<div>`, not a nav.
- Each column header is rendered as a `<p>` with mono-caps styling — not `<h2>` (the page already has section `<h2>`s; the Footer's column headers are visual labels, not document outline anchors).
- Link lists are `<ul>` with `<li>` per link.
- Locale switcher is three `<a hreflang="{locale}" lang="{locale}">` elements (the `lang` attribute lets screen-readers pronounce each label in its native script). Current locale carries `aria-current="page"`.
- Copyright is `<small>`. The `{year}` placeholder is rendered as a number; `<small>` is the semantic match for "copyright fine print".
- Empty Legal column behavior: `<nav aria-label="Legal">` renders with the `<h3>`-style header but no `<ul>` (or an empty `<ul>` with `aria-hidden="true"`). The header alone is acceptable per WAI-ARIA — no AT announcement is misleading.
- Focus order: Brand column is non-interactive (skipped); tab moves through Site links → Reach links → Legal links (when present) → locale switcher entries.

### Localization

Ships in all three locales for chrome.

Translation keys:
- `brand.studio` (shared with `Nav`)
- `brand.descriptor`
- `footer.site.heading`
- `footer.reach.heading`
- `footer.reach.telegram` (label string for the Telegram link entry; URL is hardcoded)
- `footer.legal.heading`
- `footer.legal.privacy` (rendered only when `/privacy` route exists)
- `footer.legal.terms` (rendered only when `/terms` route exists)
- `footer.bottom.copyright` (rich-text — `{year}` placeholder preserved across locales)
- `nav.{work,network,services,lab,contact}` (shared with `Nav`)

Locale switcher labels (`English` / `Română` / `Русский`) are not translated — each label appears in its own native form across all three locales.

### Out of scope

- **Newsletter signup.** Out of scope until subscription channels exist.
- **Social-media icons** (Twitter, LinkedIn, GitHub). The studio has no public social presence at v1; surfacing icons that lead to dormant or empty profiles is worse than no link.
- **Contact form embedded in the footer.** The form lives on `/contact`.
- **Site map link.** The sitemap is at `/sitemap.xml` for crawlers; not surfaced as a user-facing link.
- **Backlinks to other Rapoport Studio properties** (separate businesses, personal sites). The studio's brand is bounded.
- **Dark/light-mode toggle.** Theme follows OS preference per `design-system.md § Palette` (no manual override at v1).
- **Privacy and Terms link rendering at launch.** The Legal column header renders; the link entries do not. When the `/privacy` and `/terms` routes ship via a separate change, the Footer block will conditionally render those links — no Footer code change required, just route existence.
- **WhatsApp and email reach entries at launch.** Per `home.md § Closing CTA` line 212 ("the studio doesn't operate that mailbox today"), email is intentionally absent. WhatsApp is documented in `CLAUDE.md` as a secondary client-comms channel but is not surfaced in the Footer at launch — added later via separate change once channels are operationally answered. Reach column launches with Telegram only.

### References

- `design-system.md § Surfaces` — footer chrome conventions.
- `design-system.md § Typography` — serif link list, mono column headers, italic-free chrome.
- `design-system.md § Hard constraints` — radius 0, no shadows, no decorative chrome.
- `design-system.md § Hover & press` — 120ms color-only hover.
- `web.md § Page contracts › /` — block 11 in the page sequence; "four columns (brand, site, reach, legal), bottom strip with locale switcher".
- `web.md § Marketing-specific components` — `<Footer />` component table entry.
- `home.md § Closing CTA` — preceding block; sets the precedent that email is absent until the studio operates a mailbox.
- `home.md § Nav` — sibling chrome block; reuses `nav.*` keys for site links.
- `i18n.md` — locale list and routing for the locale switcher.

---

## Founder note

> Mono-strip carrying the studio's founder identity. Avatar (or studio mark) + name + one credibility line + single anchor. Text-only; no CTA button. Inserted between `OperatingModel` and `ForFounders` as a restrained personal-attribution beat.

### Purpose

Surface the studio's founder identity at a moment in the read where the visitor has just seen *how the studio operates* (`OperatingModel`) and is about to be addressed *as a founder* (`ForFounders`). The block answers "who runs this?" inline, without hijacking the Hero or competing visually with the page's primary CTA at `ClosingCTA`. Pavel-the-person is mentioned in the JSON-LD `organizationLd.founder` field elsewhere on the page; this block is the only on-page surface where the founder is named.

The block is restrained by design. It is not a Hero, not a bio page, not a testimonial. The credibility line is one sentence; the anchor is one link (Telegram default; configurable via i18n to GitHub). Adding a second CTA, a quote, an image, or a long-form bio is out of scope (see `### Out of scope`).

### Position in page narrative

Position 8 in the visible-block arc (per `flows.md § Page narrative arc`). Sits between `OperatingModel` (block 7) and `ForFounders` (block 9). Reader sequence: "how the studio operates" → "who runs it" → "is this for founders like me?". The block immediately before is `OperatingModel`; the block immediately after is `ForFounders`.

### Content contract

| Field | Required | Type | Source | Notes |
|---|---|---|---|---|
| `name` | yes | string | `home.founderNote.name` | "Pavel Rapoport" across all locales. Proper noun; not translated. |
| `credibility` | yes | string | `home.founderNote.credibility` | One sentence. ≤ 25 words. Authored per locale (en/ru/ro symmetric per `D-CCP-7`). |
| `linkLabel` | yes | string | `home.founderNote.linkLabel` | Link text. Default "Telegram" / "GitHub" — Pavel chooses at implementation. |
| `linkUrl` | yes | string | `home.founderNote.linkUrl` | Destination URL (e.g., `https://t.me/...` or `https://github.com/...`). Preserved across locales (not translated). |

No CTA button. The single anchor is a secondary link per `flows.md § Page invariants 1`.

### Component composition

| Layer | Component | Path |
|---|---|---|
| Block | `<FounderNote />` (server component) | `apps/web/src/components/home/founder-note.tsx` |
| Avatar | mono-styled image or studio mark | local asset, small |
| Anchor | `<Link>` | `@rapoport-studio/i18n/navigation` |

### Visual contract

Mono-strip composition. Single horizontal band at section padding `py-16 md:py-20` (lighter than the adjacent OperatingModel and ForFounders which use `py-32 md:py-40`). `border-t border-grid` on top edge per the page's section-divider convention.

Layout: avatar (left, fixed small size — e.g., `h-12 w-12 rounded-full`) + text block (right, two lines max). Text block:

- Line 1: name (`font-serif text-lg leading-tight text-ink`) followed inline by an em-dash + credibility (`font-serif italic text-base leading-[1.6] text-ink-light`).
- Line 2: anchor link (`font-mono text-xs uppercase tracking-[0.15em] text-blueprint border-b border-blueprint pb-0.5`).

No tactical frame. No background tint. No icon. The studio's design system reserves visual weight for the page's primary CTA and the structural diagrams; FounderNote sits in the gaps between them as paper-toned attribution.

**Forbidden in this block.** No CTA button. No second anchor. No quote. No long-form bio. No social-media icon grid. No image larger than the avatar. No animation beyond the standard intersection-fade pattern shared with adjacent blocks.

### Motion contract

Standard fade-in on intersection. Opacity `0 → 1` over 360ms `--ease-settle`; slight `translateY(8px) → 0`. Reduced-motion: no transition, final state on first paint.

### Responsive contract

- Mobile (`< md`): avatar + text stack vertically. Avatar centered above name. Anchor below credibility.
- Desktop (`≥ md`): avatar + text side-by-side. Avatar left, text right.
- Minimum width: 320px (site-wide minimum).

### Accessibility contract

- Section landmark: `<section aria-label="Founder">`. No heading — the block is a mono-strip, not a content section with a hierarchy.
- Avatar image: `alt={name}` (e.g., `alt="Pavel Rapoport"`).
- Anchor: explicit `aria-label` combining name + platform (e.g., `aria-label="Pavel Rapoport on Telegram"`) since the visible link text is the platform name, not the destination context.
- No keyboard traps. Single tab stop (the anchor).

### Localization

Three locales: `en`, `ro`, `ru`. Keys under `home.founderNote.*` in `packages/i18n/messages/{en,ro,ru}/web.json`.

`name` is preserved across locales (proper noun). `linkUrl` is preserved (URLs are language-invariant). `credibility` and `linkLabel` are translated per locale; `linkLabel` may differ if the chosen platform varies by locale (it does not, in practice — same anchor target across en/ro/ru).

### Out of scope

- Pavel-the-person long-form bio. That belongs on a future `/about/founder` page if it ships.
- Testimonial / quote.
- CTA button. Single anchor only.
- Multiple anchors. One link target; not a "social hub".
- Hero-scale avatar. Small, restrained.
- Founder-led OpenSpec / capability cross-references. Those belong in `platform.md` and the `_methodology/` corpus, not on the home page.

### References

- `archive/2026-05-23-fix-home-trust-blocks-and-narrative/design.md § D-HTN-5 ratified` — canonical composition decision and rationale (founder identity placement, Q-HTN-4 resolution).
- `archive/2026-05-23-fix-home-trust-blocks-and-narrative/tasks.md § Phase 4` — implementation phase that shipped the block.
- `archive/2026-05-24-sync-home-arc-with-rap-1190/design.md § D-SHA-3` — decision to author this block-template now (RAP-1190 deliverable) and defer the four pre-existing missing entries.
- `flows.md § Page narrative arc` — the visible-block arc that positions this block at 8.
- `blocks.md § Background patterns paint-map § 08 · founder-note` — paint-map verdict for this block (bare · adjacent to applied).

---

## Community CTA target (applied 2026-05-06 from change `add-studio-self-serve-signup`)

The two community-targeted CTAs that ship inside the homepage — `BuildOnPlatform` and `CommunitySignal` (added by `expand-home-with-services-and-community`, RAP-82) — now route to the studio's self-serve signup entry on `app.rapoport.studio/community/signup` instead of the previous dead-end target `/contact?segment=community`.

Implementation, env-var contract, and boundary discipline live in `web.md § Community signup CTA target`. This note exists so the home spec stays internally consistent with the cross-reference map: when the BuildOnPlatform / CommunitySignal blocks are eventually formalized as block-template entries in this file, their **References** subsection should cite `web.md § Community signup CTA target` plus `studio-workspace/spec.md § Community member surface` for the destination route family.

No copy or visual change ships with this amendment — only the target URL.

---

## Founder Track delta (applied 2026-05-08 from change `add-founder-track`, RAP-98)

`add-founder-track` (RAP-98) overlays a Founder Track funnel on the homepage without disturbing the locked Client Track flow. The IA delta is enumerated above in **Page narrative arc**; this note captures the per-block summary so the existing block-template entries stay correctly cross-referenced until the post-RAP-82 blocks (DesignFirst, ForFounders, CommunitySignal, BuildOnThePlatform) are formalized as block-template entries.

### Hero
Sub-line key changes from `home.hero.sub` to `home.hero.subWithFounders` (acknowledges three audiences: client, founder, specialist). Single-CTA invariant preserved: founder acknowledgement lives in copy, never in a button. Original `sub` key retained for fallback only. See block content contract above.

### DesignFirst
Founder-led card body (`home.designFirst.archetypes.founder.body`) updated to reference F1 (Series-A approach) and F2 (AI-orchestration retrofit) pain concretely. Founder-led card gains a CTA to `/[locale]/founders` via `home.designFirst.archetypes.founder.cta.label`. Other two cards (client-led, specialist-led) unchanged.

### ForFounders (NEW block)
Inserted between DesignFirst and TheNetwork. Block contract:

| Field | i18n key | Notes |
|---|---|---|
| eyebrow | `home.forFounders.eyebrow` | |
| heading | `home.forFounders.heading` | |
| lede | `home.forFounders.lede` | Pain-first sentence + diaspora-hook clause (RAP-265). EN: "…Founders who think in English, Romanian, or Russian — building EU and Israeli companies." RO: "…Fondatori care gândesc în engleză, română sau rusă — construind companii în UE și Israel." RU: "…Основатели, которые думают на английском, румынском или русском — строят компании в ЕС и Израиле." |
| segments[].geo | `home.forFounders.segments.<slug>.geo` | EN values: `seriesA` → "Tel Aviv · London · NYC"; `aiRetrofit` → "Paris · Berlin · Tel Aviv"; `reservist` → "Tel Aviv". City names identical across all three locales. Rendered as a mono-uppercase `<Chip kind="skill">` above the segment title. |
| segments[] | `home.forFounders.segments.<slug>` | Slugs: `seriesA`, `aiRetrofit`, `reservist`. All three now visible (RAP-265 unhides `reservist`). |
| cta.label | `home.forFounders.cta.label` | Links to `/[locale]/founders` |
| ideaStageHook.label | `home.forFounders.ideaStageHook.label` | Wraps an `<a href={studio.signupUrl}>` for F4/F5 community traffic |

Forbidden vocabulary on this block: `spec / methodology / process / review gate / discipline / framework`. See `platform.md § Cold-pitch vocabulary constraint`. Component lives at `apps/web/src/components/home/for-founders.tsx`.

### CommunitySignal
Body copy (`home.network.communitySignal.body`) refreshed to acknowledge idea-stage founders (F4 pre-seed AI-native, F5 idea-stage non-technical) alongside specialists and junior practitioners as part of the community audience. The placeholder copy from RAP-82 is replaced; live counters remain deferred to change 3 (`add-community-canvas-and-archetypes`) per RAP-82 D-11.

### Persona-to-block invariants
Two invariants from `add-founder-track/design.md § 5` are now load-bearing on the home spec:

1. **Founder block separation.** Founder pain lives in `ForFounders`, never bleeds into `BuildOnThePlatform`. F4/F5 idea-stage hook lives in `CommunitySignal` body and as secondary link inside `ForFounders`, not as a separate primary CTA in the homepage.
2. **Single-track-per-CTA-button.** Every CTA *button* on the home page resolves to exactly one persona's path. Multi-audience copy is allowed in headings and ledes, never in button labels. ClosingCTA is **client-facing only** — founder-track CTAs live on the `/founders` page.

References: `archive/2026-05-08-add-founder-track/design.md` (post-archive path), `research/cold-pitch-language.md` for approved positioning vocabulary and per-surface candidate copy, `platform.md § Cold-pitch vocabulary constraint` for the cross-cutting forbidden list.

---

## Extend home typography and audience tag (applied 2026-05-12 from change extend-home-typography-and-audience-tag)

Two Visual contract citations updated:

- **`§ Hero § Visual contract`** — Headline (`h1`) now renders at `--text-display-xl` (64 / Lora 500 / 1.05 / -0.015em). Hero is the only block paired with `Closing CTA` that consumes this new ramp ceiling. The prior `text-[clamp(40px,6vw,64px)]` ad-hoc clamp is replaced by a token citation.
- **`§ Closing CTA § Visual contract`** — Heading (`h2`) now renders at `--text-display-xl`. Same ramp ceiling as Hero, opposite end of the page. The prior `text-[clamp(36px,5vw,56px)]` ad-hoc clamp + "intentionally smaller than the hero" rationale are superseded by the shared token.

No copy changes. No motion changes. No other Visual contract fields touched. `--text-display-xl` lives in `design-tokens.md § Typography § Type ramp` and is documented as "Hero / closing only" in the token's Notes column; re-use by any other block requires its own proposal.

Cross-ref: `archive/2026-05-12-extend-home-typography-and-audience-tag/`. Linear: RAP-555.

---

## Clarify home block contracts (applied 2026-05-12 from change clarify-home-block-contracts)

Four contract clarifications resolving Q-HOME-2, Q-HOME-3, Q-HOME-4, Q-HOME-6 from `Redesign Brief v2.html § Pass 4`. The new `flows.md § Page invariants` section is the structural anchor; per-block contracts inherit from it.

### Q-HOME-2 — Founder-track links are secondary, not CTAs

The home page has exactly one primary CTA (`§ Closing CTA § cta.startProject`, terracotta button) per `flows.md § Page invariants` invariant 1. Every other CTA-shaped element is a **secondary link** — mono, blueprint, underlined, no button chrome, no enter-from-bottom motion. Two field-level renames:

- **`§ Design first § Content contract`** (currently scaffolded under `Founder Track delta § DesignFirst` until DesignFirst is formalized as a block-template entry). The founder-led card's spec field for the founder-track link is named `secondaryLinkFounderLed`. Description: _Secondary link pointing at `/founders` page. Mono, blueprint, underlined per `flows.md § Page invariants` invariant 1._ The underlying i18n key `home.designFirst.archetypes.founder.cta.label` is unchanged; only the spec contract noun is fixed (no prior occurrence of the old "CTA" noun appears in `current/home/`, so the rename is a one-sided establishment of the secondary-link name).

- **`§ Founders § Content contract`** (currently scaffolded under `Founder Track delta § ForFounders` until ForFounders is formalized as a block-template entry). The `seeFounderTrack` field (today exposed via `cta.label` → `home.forFounders.cta.label`) renders as a **secondary link** (mono, blueprint, underlined), not a primary CTA. The single primary CTA on `/` lives in `§ Closing CTA` per `flows.md § Page invariants` invariant 1. The `ideaStageHook.label` field stays a secondary link as it already is.

No copy changes. No i18n key renames. No component changes. The visual treatment (mono / blueprint / underlined) is already in production; the spec noun catches up.

### Q-HOME-3 — Empty-roster unmount for The network

`§ The network § Renders if` (new subsection, see above) documents the canonical unmount-not-placeholder case. When `roster.length === 0`, the section unmounts entirely from the DOM; the page does not visually compensate. Already the behaviour in production; the spec catches up. See `flows.md § Page invariants` invariant 5.

### Q-HOME-4 — §10 always-border + conditional sub-section signal

Appended to `§ Community signal § Page narrative role` (currently scaffolded under `Founder Track delta § CommunitySignal` until CommunitySignal is formalized as a block-template entry):

> **Divider contract.** Renders its own `border-t border-grid` always, regardless of whether `§ The network` mounted. When §9 is present, §10 additionally renders a sub-section signal (left rail or indent of one column) marking the parent-child relationship; when §9 is absent, the sub-section signal is dropped and §10 reads as a peer block. The top border is constant; the sub-section signal is conditional.

This is the temporary fix for the §9 → §10 divider gap. The follow-up change `merge-community-signal-into-network` will collapse §9 + §10 into one block and supersede this clause; until then, §10 always carries its own top border so the page stays sound when the roster is empty.

### Q-HOME-6 — Block count is thirteen

Reconcile pass across `openspec/current/home/`. Confirmed:

- `narrative.md` line 11 — "Thirteen blocks composed in a fixed narrative arc". No change.
- `flows.md § Page narrative arc` body — "Thirteen on-page blocks (Nav and StickyCTA are chrome / overlays)". No change.
- `flows.md § Page invariants` invariant 3 — "Block count is thirteen." Added in this change.
- `grep -rni "fourteen" openspec/current/home/` returns no matches.

`Nav` and `StickyCTA` are chrome / overlays and do not count.

### What this change did not touch

- No new tokens. No new components. No motion contract additions.
- No localisation key renames. The i18n key `home.designFirst.archetypes.founder.cta.label` is preserved; the spec contract noun above it is the only thing renamed.
- React props in `apps/web/src/components/home/*.tsx` are unchanged; a downstream change will rename props to align with the new spec nouns.
- Persona-to-block invariants in the `Founder Track delta` amendment are unchanged.

Cross-ref: `archive/2026-05-12-clarify-home-block-contracts/`. Linear: RAP-558.

---

## PostCard featured variant (applied 2026-05-12 from change add-postcard-featured-variant)

`§ Lab preview` now carries an explicit count-trigger render rule. When `posts.length === 1`, the block renders one `<PostCard mode="featured">` at full content width (`max-w-prose`) with an `<h2>` title at `--text-display-xl`. When `posts.length >= 2` (capped at 3), the block reverts to the existing 3-up grid of `<PostCard mode="default">` cards. The `posts.length === 0` empty-state pattern is unchanged (the section unmounts).

The previous "1–2 posts render gracefully — a 1- or 2-card row is acceptable" line is superseded: a single `default` `PostCard` against a section header titled "From the lab" reads as a broken row, not as intentional. The featured mode resolves that defect at the layout layer instead of holding the section back until ≥ 3 posts ship. The 3-up `default` grid contract for ≥ 2 posts is unchanged.

`PostCard` joins the canonical-wrapper inventory in `design-components.md § Components — registry` between `PersonaBadge` and `ToolStatusPill`. The wrapper's two-mode contract is documented in `design-components.md § PostCard wrapper`. `EntityCard`'s closed variant list (`inline | row | card | detail`) is unchanged; the `featured` mode composes `EntityCard`'s slot primitives at a wider geometry rather than adding a fifth variant.

Cross-ref: `archive/2026-05-12-add-postcard-featured-variant/`. Closes `Redesign Brief v2.html § Pass 4 § Q-HOME-5` and `§ Pass 2 § R-DC-3`.

---

## Merge community signal into network (applied 2026-05-12 from change merge-community-signal-into-network)

Closes Q-HOME-4 (R-HM-9 in `Redesign Brief v2.html § Pass 2`) by collapsing the previous `## The network` (§9) and the Founder-Track-delta-scaffolded `§ Community signal` (§10) into a single block contract: **`## The network & community`** (above, replacing the prior `## The network` section in the §9 slot). Layer A (community CTA cluster) renders unconditionally; Layer B (specialist roster grid) renders only when `roster.length >= 1`. The merged block always mounts on `/`, removing the §9 → §10 orphan condition that the prior change papered over with an always-border stopgap.

### Page count: thirteen → twelve

`flows.md § Page invariants` invariant 3 decrements to "Block count is twelve." Updated in lockstep across the home spec:

- `flows.md § Page narrative arc` body — "Twelve on-page blocks (Nav and StickyCTA are chrome / overlays)".
- `flows.md § Page invariants` invariant 3 — "Block count is twelve."
- `flows.md § Page invariants` invariant 2 audience-tag list — `spc` now lists `§ The network & community` (not `§ The network`, `§ Community signal`).
- `narrative.md § What this capability is` — "Twelve blocks composed in a fixed narrative arc".
- `README.md` capability index — "all 12 blocks".
- `spec.md § Cross-reference map` — row "The network" renamed to "The network & community" with the new component path.

### Obsoleted by this change

- **`§ Community signal § Page narrative role § Divider contract`** clause in the prior `clarify-home-block-contracts` amendment (§ Q-HOME-4) is **obsolete** — the `## Community signal` sub-block it described was merged into `§ The network & community § Renders if` and `§ Visual contract § Internal divider`. The amendment text remains in `blocks.md` for historical record (per OpenSpec convention, prior amendments are not edited retroactively); reviewers should treat its "always carries its own top border" clause as superseded by the merged block's "block always mounts" contract.
- **`§ Founder Track delta § CommunitySignal`** sub-entry (lines 1577–1578) is **functionally obsolete** — the `home.network.communitySignal.body` key it documented has been migrated to `home.networkAndCommunity.communityBody` and the inner sub-block dissolved. The Founder-Track persona-to-block invariants 1 and 2 (line 1583–1584) still apply: "F4/F5 idea-stage hook lives in `CommunitySignal` body" now reads as "lives in `§ The network & community § communityBody` and as secondary link inside `ForFounders`". The amendment text is left intact for historical record.
- **`spec.md § Cross-reference map`** row "The network → `components/home/the-network.tsx` (uses `PersonCard`)" — replaced by the renamed row "The network & community → `components/home/the-network-and-community.tsx` (uses `PersonCard`)".

### i18n migration (one-to-one mapping)

| Old key | New key | Value transform |
|---|---|---|
| `home.network.eyebrow` | `home.networkAndCommunity.eyebrow` | verbatim |
| `home.network.heading` | `home.networkAndCommunity.heading` | new value: "The network & community" (translators sign off on RU "Сеть и сообщество", RO "Rețeaua și comunitatea") |
| `home.network.lede` | `home.networkAndCommunity.lede` | verbatim |
| `home.network.stats` | `home.networkAndCommunity.stats` | verbatim (`{count}` and `{cities}` placeholders preserved) |
| `home.network.cta` | `home.networkAndCommunity.rosterCta` | verbatim |
| `home.network.communitySignal.eyebrow` | `home.networkAndCommunity.communityEyebrow` | verbatim |
| `home.network.communitySignal.heading` | _deleted_ | "Open access. Curated review." retired — merged block has one H2 |
| `home.network.communitySignal.body` | `home.networkAndCommunity.communityBody` | verbatim (single paragraph) |
| `home.network.communitySignal.cta` | `home.networkAndCommunity.communityCta` | verbatim |

Each locale (`en`, `ru`, `ro`) exposes the same eight keys under `home.networkAndCommunity`.

### React

- New: `apps/web/src/components/home/the-network-and-community.tsx` (server component).
- Deleted: `apps/web/src/components/home/the-network.tsx`, `apps/web/src/components/home/community-signal.tsx`.
- Page composition: `apps/web/src/app/[locale]/(marketing)/page.tsx` swaps the two old block renders for one `<TheNetworkAndCommunity />`.

Cross-ref: `archive/2026-05-12-merge-community-signal-into-network/`. Linear: RAP-560.

---

## Collapse Design first into Services (applied 2026-05-12 from change collapse-design-first-into-services)

Closes Q-HOME-7 from `Redesign Brief v2.html § Pass 4 § What I'd cut § 01`. Deletes the standalone `DesignFirst` block and collapses its three-archetype framing into a prose `§ Services § Intro` paragraph above the five-card capability grid.

### What changed

- **`§ Founder Track delta § DesignFirst`** (the scaffolded DesignFirst block entry above) is **functionally obsolete** — the component `apps/web/src/components/home/design-first.tsx` is deleted and `DesignFirst` is removed from the page composition (`apps/web/src/app/[locale]/(marketing)/page.tsx`). The amendment text is left intact for historical record per OpenSpec convention.
- **`§ Services § Intro`** — new sub-section added above `§ Services § Position in page narrative`, documenting the prose intro paragraph contract: three archetype names inline (semibold, ink), trailing secondary link to `/founders`. See spec above.
- **`§ Services § Visual contract`** — `**Intro paragraph.**` clause appended documenting the visual tokens.
- **`§ Services § Renders if`** — new sub-section added: the intro renders unconditionally.

### Page count: twelve → eleven

`flows.md § Page invariants` invariant 3 decrements to "Block count is eleven." Updated in lockstep across the home spec:

- `flows.md § Page narrative arc` diagram — `DesignFirst  ─►` removed from the block sequence.
- `flows.md § Page narrative arc` body — "Eleven on-page blocks (Nav and StickyCTA are chrome / overlays)."
- `flows.md § Page invariants` invariant 3 — "Block count is eleven."
- `narrative.md § What this capability is` — "Eleven blocks composed in a fixed narrative arc."

### i18n migration

| Old key | Action |
|---|---|
| `home.designFirst.*` (entire namespace, including nested `archetypes.founder/client/specialist`) | **Deleted** across `en/web.json`, `ru/web.json`, `ro/web.json`. |

| New key | Notes |
|---|---|
| `home.services.intro.body` | Rich-text paragraph with `<founderLed>`, `<clientLed>`, `<specialistLed>` tag tokens for inline `<strong>` rendering via `t.rich`. |
| `home.services.intro.archetypeLabels.founderLed` | "Founder-led" per locale. |
| `home.services.intro.archetypeLabels.clientLed` | "Client-led" per locale. |
| `home.services.intro.archetypeLabels.specialistLed` | "Specialist-led" per locale. |
| `home.services.intro.foundersLink` | Link label for the `/founders` secondary link per locale. |

### React

- Deleted: `apps/web/src/components/home/design-first.tsx`.
- Deleted: `apps/web/src/components/home/__tests__/design-first.test.tsx` (was not present; design-first had no dedicated test file).
- Edited: `apps/web/src/components/home/services-section.tsx` — intro paragraph added above the five-card grid in the client track variant.
- Edited: `apps/web/src/app/[locale]/(marketing)/page.tsx` — `<DesignFirst />` import and render removed.

Cross-ref: `archive/2026-05-12-collapse-design-first-into-services/`. Linear: RAP-561.

---

## Hero / Closing CTA recipe citations (applied 2026-05-13 from change `codify-editorial-recession-pattern`)

Inline class-string descriptions in three Visual contract sections superseded by named-pattern references.

**Hero Visual contract — headline `<em>`.** Description "italic emphasis segment renders as `<em className="italic font-medium text-ink-light">`" superseded by: Headline `<em>` uses editorial recession **Recipe A**. See `design-system.md § Editorial recession § Recipe A`. Atoms: host `font-serif font-medium text-ink`; `<em>` carries `italic font-medium text-ink-light`.

**Closing CTA Visual contract — heading `<em>`.** Description "`<em>` segment is `italic font-medium text-ink-light`" superseded by: Heading `<em>` uses editorial recession **Recipe A**. Same atoms as Hero; opposite ends of the page, same ramp ceiling (`--text-display-xl`).

**What we build Visual contract — pull-quote `<em>`.** Description "renders as `<em className="not-italic font-medium text-ink">`" superseded by: Pull-quote `<em>` uses editorial recession **Recipe B**. See `design-system.md § Editorial recession § Recipe B`. `PullQuote` container is italic-recessed host; `<em>` inside carries `not-italic font-medium text-ink`.

Cross-ref: `design-system.md § Editorial recession`. `archive/2026-05-13-codify-editorial-recession-pattern/`.

---

## Background patterns applied (applied 2026-05-18 from change `apply-home-background-patterns`)

Two background-pattern placements on the home page, governed by `D-DS-8` and `design-components.md § Background patterns` — decorative fill on text-free zones only, never behind text.

- **For legacy** — `modulor` composition pattern in the section's bottom padding (the page's single composition-pattern placement). Fades upward, dense at the section's bottom edge.
- **Closing CTA** — `hatch` pattern, `accent` tone, in the section's bottom padding; the page's single accent-tone pattern. This does not introduce a frame, icon, or image — the block's "Forbidden in this block" list is unaffected.

Two tiled side-rail placements (`How we work`, `Operating model`) were proposed by the paint-map and dropped on review — a thin margin rail read as a detached grid fragment. Those blocks are unchanged.

These placements add no text-bearing chrome; the per-block content contracts above are unchanged. Patterns are decorative layers, `aria-hidden`, `pointer-events-none`.

Cross-ref: `design-components.md § Background patterns`. `openspec/decisions.md` D-DS-8. `openspec/archive/2026-05-20-add-background-pattern-system/research/` (structural audit + paint-map).

---

## Background patterns paint-map

> The 13 current home sections × per-section verdict (12 visible + 1 conditional `lab-preview`) for the
> `D-DS-8` background-pattern system. **Three** placements applied,
> **ten** bare. Density budget at **3/3** (raised from 2 by D-DS-9 —
> change `apply-connected-stack-coordinate-grid`). The governing constraint
> is now spacing, not count: placements stay ≥1 bare section apart.
>
> System reference: `design-components.md § Background patterns`.
> Audit source: `archive/2026-05-20-add-background-pattern-system/research/home-structural-audit.md`.
> Application source: `archive/2026-05-21-apply-home-background-patterns/`.

### Summary

| # | Block | Role | Density | Verdict | Pattern |
|---|---|---|---|---|---|
| 01 | `hero` | opening | medium | bare · mandate | — |
| 02 | `what-we-build` | proof / explainer | high | bare · competes | — |
| 03 | `how-we-work` | process | medium | bare · redundant rhythm | — |
| 04 | `services` | mechanism / catalog | high | bare · catalog saturated | — |
| 05 | `now-building` | proof | medium · conditional | bare · conditional | — |
| 06 | `connected-stack` | mechanism | high | **P5 · applied** | `.bg-pattern-cad` · blueprint · normal · fade-top (wrapper) |
| 07 | `operating-model` | mechanism | high | bare · SVG-saturated | — |
| 08 | `founder-note` | founder identity | low | bare · adjacent to applied | — |
| 09 | `for-founders` | segmentation | medium | bare · adjacent to applied | — |
| 10 | `for-legacy` | segmentation | low | **P3 · applied** | `<ModulorPattern>` · blueprint · subtle · fade-top |
| 11 | `the-network-and-community` | proof / community | medium · conditional | bare · conditional · already ruled | — |
| 12 | `lab-preview` | proof · conditional | medium · conditional | bare · conditional | — |
| 13 | `contact` (closing-cta) | closing | low | **P4 · applied** | `.bg-pattern-hatch` · accent · normal · fade-top |

### Applied placements

#### P3 — `for-legacy` · bottom-strip composition

File: `apps/web/src/components/home/for-legacy.tsx` · RAP-1035.

```tsx
<div
  aria-hidden
  className="pointer-events-none absolute inset-x-0 bottom-0 h-24 md:h-32"
>
  <ModulorPattern tone="blueprint" intensity="subtle" fade="top" />
</div>
```

The page's single composition-pattern placement. `for-legacy` is its
only viable host per the structural audit: lowest content density,
largest section padding (`py-32 md:py-40`), always-on top border, no
competing chrome. Modulor specifically because its
`preserveAspectRatio="none"` survives the 12:1 strip aspect (Frame and
Phi would crop their L-brackets / labels). Tone `blueprint` + intensity
`subtle` keeps it as paper texture, not figure. `fade-top` dissolves
the pattern upward toward the CTA above.

#### P4 — `closing-cta` · bottom-strip tile (accent)

File: `apps/web/src/components/shared/closing-cta.tsx` · RAP-1035.

```tsx
<div
  aria-hidden
  className="pointer-events-none absolute inset-x-0 bottom-0
             h-12 md:h-24 bg-pattern-hatch text-accent pattern-fade-top"
/>
```

The page's single accent-tone pattern. Terminal strip closing the
conversion module before the footer. `hatch` specifically (not dots or
graph) for its drawing-convention reading (GOST 2.306 § solid hatch).
`fade-top` dissolves upward toward the CTA pair.

#### P5 — `connected-stack` · bottom-strip tile (CAD coordinate grid)

File: `apps/web/src/components/home/connected-stack.tsx` · RAP-1265.

```tsx
<div
  aria-hidden
  className="pointer-events-none absolute inset-x-0 bottom-0
             h-16 md:h-32 pattern-fade-top"
>
  <div className="absolute inset-0 bg-pattern-cad text-blueprint opacity-70" />
</div>
```

The page's third placement and its first non-shipping-precedent tile.
`CAD/08` specifically: the section's content semantic is *coordinate
system* (the studio's tools plotted on a shared plane), and the 60px
crosshair grid is the catalog's one literal match. It sits in the
section's empty bottom padding — below and apart from the `grid-cols-3`
card lattice — so it reads as the registration field *beneath* the
stack, not a second content grid (see § Bare-rationale override below).

Fade is applied to the WRAPPER, not the tile: `bg-pattern-cad` owns
`mask-image` for its crosshairs, so `pattern-fade-top` on the same
element would silently override it (the documented anti-pattern). The
two masks compose across the nesting instead. `opacity-70` (normal) —
the weight P4 hatch ships at. Height tracks the section's `py-16
md:py-32` padding so the strip never overlaps the CTA.

### Bare placements — rationale

#### 01 · `hero`

The `<TacticalFrame animated tone="primary">` is the page's strongest
visual anchor. Pattern in the surrounding bands competes with the
brackets' deploy animation. Audit task brief explicitly drops hero
application — no re-litigation.

#### 02 · `what-we-build`

Densest text section. OrchestraDiagram contains `<text>` nodes — a
pattern behind it would violate `D-DS-8`. The bottom strip below the
pull-quote is text-free, but the pull-quote is already a narrative
anchor; adding pattern below it shifts emphasis away from the quote,
not toward it.

#### 03 · `how-we-work`

Per-row `border-t border-grid` already gives the section a ruled
rhythm; a strip below would sit ~24px below a section-boundary
hairline, reading as doubled rule. The dropped P1 side-rail proposal
lived here and confirmed the section over-reads when any annotation
is added.

#### 04 · `services`

Densest card block. Five ServiceCards (`border + bg-card + p-6`) leave
no text-free band. Section's strips are bracketed by intro paragraph
and final CTA. Promoted to position 4 in the post-RAP-1190 arc; sits
upstream of the P3/P4 placements so density is the limiter, not
adjacency.

#### 05 · `now-building`

Conditional section (`return null` when no in-progress MDX). A pattern
that depends on a vanishing host is brittle. WorkCards have
edge-to-edge text content, no card-edge zone.

#### 06 · `connected-stack` — bare verdict overridden by P5

The original verdict was *bare · already literal grid*: a `graph` or
`dots` tile rendered under/within the `md:grid-cols-3` card lattice
would double the section's literal grid. **D-DS-9 / RAP-1265 overrides
it on two axes:** (1) the CAD field lives in the empty bottom padding,
spatially apart from the cards — there is no lattice in the strip's
bounds to double; (2) CAD's 60px crosshair pitch is coarser than and
semantically distinct from the card grid, reading as the coordinate
registration field the stack is plotted onto. The override is argued,
not silent — see § Applied placements › P5.

#### 07 · `operating-model`

Two SVG diagrams already by this point (Orchestra + OperatingModel),
both with text. The italic nucleus statement is a narrative anchor;
a strip below it was considered and rejected because the section's
chain — diagram → 4 principles → proof block → nucleus → 2 CTAs —
already saturates attention.

#### 08 · `founder-note`

New section, RAP-1190 D-HTN-5. Mono-strip composition (avatar + name +
one credibility line + Telegram link). Density low but sits two rows
before the P3 placement at `for-legacy`; pattern here would crowd the
adjacent `fnd`/`lgc` segmentation pair (rows 09 / 10). Bare.

#### 09 · `for-founders`

Tight 3-column rule (`md:gap-0 md:border-s md:ps-8`); strips above /
below are technically clean but the section sits immediately before
10 (`for-legacy`) which owns the page's composition placement.
Patterns here would double up onto 10.

#### 11 · `the-network-and-community`

Layer B conditional (PersonCard roster renders only when
`people.length ≥ 1`). Section already carries a `layer-divider`
(`border-t border-grid mt-16 pt-16`) bracketing Layer B — adding
pattern compounds rules. Roster card-edge zones not inspected; remain
out of scope.

#### 12 · `lab-preview`

Conditional section (`return null` on empty posts per `blocks.md §
Lab preview` and `archive/2026-05-24-sync-home-arc-with-rap-1190/
design.md § D-SHA-1`). Brittle host. Same reasoning as 05.
PostCard edge zones not inspected.

### Open question — Q3 · should `build-on-platform` displace one current placement? — **RESOLVED**

**Resolved 2026-05-23 by RAP-1190 D-HTN-7.** `build-on-platform` removed from the home page entirely (component file retained at `apps/web/src/components/home/build-on-platform.tsx` for potential `/specialists` reuse). The displacement question is moot — the candidate no longer exists in the arc. Density budget remains 2/2 (P3 at `for-legacy` + P4 at `closing-cta`).

The historical analysis below is retained for audit-trail readability.

> Section 12 (`build-on-platform`) was the strongest "bare · candidate"
> on the original audit — low density, clean bottom strip, structurally similar
> to `for-legacy`. Adding it would have breached the 2/page total budget.
>
> The trade question was: is `build-on-platform`'s specialist-audience
> message worth a pattern more than `for-legacy`'s low-density
> narrative reset (P3)?
>
> **Call at the time: no.** P3 + P4 landed the two structurally quietest
> moments (mid-page reset + terminal closing). Section 12 sat inside
> the dense tail of the page; pattern there would have thickened rather than
> punctuated. The block was removed from home before this trade was reopened.

### Boundary conventions in this paint-map

All applied placements share the bottom-strip idiom documented at
`design-components.md § Background patterns › The bottom-strip idiom`.
No top-strips, no side-rails, no full-section underlay. Adding any of
these on the home page requires a new idiom proposal that resolves
the failure modes documented at
`design-components.md § Anti-patterns`.

### Cross-references (one-line additions to per-block sections)

Optional companion edits to each of the 14 block contracts, in the
"Forbidden in this block" subsection — one line surfacing the paint-
map verdict from the block's contract page:

> **Background pattern.** See § Background patterns paint-map below.
> Verdict for this block: *<bare · {reason}>* / *applied — P{N},
> {component} · {tone} · {intensity} · fade-{direction}*.

These are optional discoverability adds; the appended paint-map
section is the source of truth.

### See also

See `## Background patterns applied` above for the RAP-1035 change-history of P3/P4 — that section records *what was applied in one change*; this paint-map records *current state across all 13 current sections* (12 visible + 1 conditional `lab-preview`).

---

## Sync home arc with RAP-1190 (applied 2026-05-24 from change `sync-home-arc-with-rap-1190`)

Phase 9 of `archive/2026-05-23-fix-home-trust-blocks-and-narrative/` (RAP-1190) shipped the page rewrite but did not produce the corresponding `blocks.md` edits. This amendment closes that gap:

1. **`## Founder note` block-template added** (per RAP-1190 D-HTN-5 + this change's D-SHA-3 / Q-SHA-2 (c)). Inserted at the end of the per-block section group, before the first historical-amendment header. Full block-template structure (Purpose / Position / Content / Composition / Visual / Motion / Responsive / Accessibility / Localization / Out of scope / References) following the convention used by `## Hero` etc.

2. **`## Who we work with` annotated obsolete-from-home** (per RAP-1190 D-HTN-6). Forward note inserted after the section's opening blockquote; section body retained per OpenSpec convention (prior contracts stay; obsolescence is annotated, not deleted).

3. **`## Lab preview` annotated conditional-mount** (per RAP-1190 D-HTN-3 split policy + this change's D-SHA-1). Forward note inserted after the section's opening blockquote; section body unchanged. Block does not count toward the visible-block invariant in `flows.md § Page invariants 3`.

4. **`## Background patterns paint-map` rewritten to 13 current sections** (per this change's D-SHA-4):
   - Header line "The 14 home sections" → "The 13 current home sections (12 visible + 1 conditional `lab-preview`)".
   - `### Summary` table re-ordered to the post-RAP-1190 page sequence; `who-we-work-with` and `build-on-platform` rows removed; new `founder-note` row added at position 08.
   - `### Bare placements — rationale` subsections re-numbered to match the new Summary; `#### who-we-work-with` and `#### build-on-platform` subsections removed; new `#### 08 · founder-note` subsection added.
   - `### Open question — Q3` marked **RESOLVED** (candidate withdrawn per RAP-1190 D-HTN-7); prior analysis retained for audit-trail readability.
   - `### See also` section-count line updated.

Forward note: block-template entries for `## Operating model`, `## Connected stack`, `## For founders`, and `## For legacy` are pre-existing debt — those blocks have been on the home page for months without contracts but were not added by RAP-1190 and are scoped to a separate follow-up change. `## Founder note` is the only RAP-1190-new block-template authored here.

Cross-ref: `archive/2026-05-24-sync-home-arc-with-rap-1190/`. Parent change: `archive/2026-05-23-fix-home-trust-blocks-and-narrative/`. Linear: RAP-1190 Phase 9 follow-up.

---

## Reposition home — hero (applied 2026-06-14 from change `reposition-home`)

`reposition-home` re-aims the home page from the **founder** to the **owner of an established business at an inflection of scale** (research §2/§9). Worked one-block-per-change; this note records the **hero** deliverable. The live hero is the **`HeroC`** component (`apps/web/src/components/home/hero-c.tsx`, copy under `home.heroC.*`), not the legacy `Hero` (`hero.tsx`, used only by `/founders`). The line-140 `## Hero` block above documents the legacy `Hero`; this section is the operative contract for the live home hero.

### Hero (HeroC)

- **Audience.** Business owner, not founder. No "founder", no "audit", no price/speed thesis (D-RH-3, D-RH-5).
- **Content contract.** Three-line revenue-first lockup (canonical research-§9 line: "find where your business earns more, and grow together"; `home.heroC.line1/2/3`, line 3 rendered `text-ink-light`). Diagnostic-led subhead (`home.heroC.subhead`) — leads with a diagnostic, not a price list; the word "research" is deliberately absent from visible copy (barrier for a non-technical owner).
- **CTA contract (D-RH-6).** Primary = **external Telegram deeplink with a prefilled message** (`https://t.me/<handle>?text=<encoded home.heroC.ctaPrimaryPrefill>`, `target="_blank"`) — one-tap contact, no form, no intermediate page. Secondary = **in-page anchor `#what`** (the what-we-build section), label `home.heroC.ctaSecondary`. Both are plain links, not i18n routes; the hero therefore does not depend on `/research` existing. Single-primary-CTA invariant preserved.
- **Visual contract.** Unchanged: `TacticalFrame tone="primary"` + wireframe globe (`hero-globe-background-c.tsx`). No `OrchestraDiagram` (that belongs to `what-we-build`).
- **Metadata (D-RH-7).** `home.meta.title` + `home.meta.description` (consumed by `generateMetadata()` in `apps/web/src/app/[locale]/(marketing)/page.tsx`) repositioned off the founder/price framing.
- **Channel (D-RH-8).** Telegram for ru/en/ro. WhatsApp + a Hebrew locale are a future follow-up (need a WhatsApp number).

Cross-ref: `changes/reposition-home/design.md § Hero block`. Authority: `_methodology/research/market-landscape-and-positioning-md-ro-il-2026-06.md` §2, §9.

### What we build (applied 2026-06-14 from change `reposition-home`, RAP-1284)

Second block of the umbrella, re-aimed founder→owner with **Direction A** (outcome-first). Copy-only; the line-273 `## What we build` block above stays in place (hard rule 7). Component `apps/web/src/components/home/what-we-build.tsx`, copy under `home.whatWeBuild.*`.

- **Audience / framing (D-RH-9).** The orchestra is reframed from "what makes a platform feel intelligent" to **agents that do the business's work and report back** — revenue-facing, not abstract. Owner language, no dev-jargon lead.
- **Title unchanged.** The `eyebrow` = «Что мы строим» / "What we build" / "Ce construim" stays verbatim — it is the label the hero's secondary CTA lands on at `#what`. The big serif `heading` is the only title-level field rewritten.
- **Heading split.** The former long heading is split into a punchy `heading` («Не один чат-бот, а оркестр агентов.») plus a one-line **`lede` (retained)** above the diagram («Каждый закрывает свою часть работы вашего бизнеса.»).
- **Body (`supporting`).** Conductor + four sections (sales / operations / content / analytics), each agent does concrete work and **reports back**; "a coordinated team working on your revenue," not "AI inside an app."
- **Ownership (`trustAuthorship`).** Kept, in plain owner language: the system is described by a spec in your repository from day one; close the project and it keeps running without us. The GitHub link (`trustAuthorshipLink`/`trustAuthorshipHref`) is retained as **quiet proof**.
- **Triplet lightened.** The OpenSpec markdown/proposal/design/tasks paragraph (`openSpecAnchor`) is **dropped** — the only key removed; mechanics no longer lead.
- **Visual unchanged.** `OrchestraDiagram` + wireframe globe + `id="what"` intact.

Cross-ref: `changes/reposition-home/design.md § What we build (D-RH-9)`. Authority: `_methodology/research/market-landscape-and-positioning-md-ro-il-2026-06.md` §9.

### How we work (applied 2026-06-14 from change `reposition-home`, RAP-1285)

Third block of the umbrella, re-aimed founder→owner. Copy-only + a pillar re-wire; the line-554 `## How we work` block above stays in place (hard rule 7). Component `apps/web/src/components/home/how-we-work.tsx` (`track="client"` variant), copy under `home.howWeWork.*`. The `track="founder"` variant (`web.founders.howItWorks`) is untouched.

- **Audience / framing (D-RH-10).** The four steps are reframed from process-mechanics into a **revenue-first owner journey**: Диагностика → Доказательство → Сборка → Владение. Exactly four steps (no count change); step keys stay `brief / curate / build / deliver` internally.
- **Heading.** Variant B — «Собираем решение под вашу задачу — не подгоняем вас под пакет.» (bespoke-differentiator), replacing «Мы собираем команду под бриф…».
- **Eyebrow unchanged.** «Как мы работаем» / "How we work" / "Cum lucrăm"; anchor `id="how"` unchanged.
- **Tool names removed.** Mirror / Canvas / Muse / Forge / OpenSpec / Project no longer appear in any owner-facing step body. The agent stack lives in the `operating-model` block and on `/openspec`.
- **Trust lines retained verbatim, one relocated.** Both pillars kept word-for-word. `trustSecurity` («…не пишет код в вашем репозитории. Специалисты не получают доступ к продакшену») **moves from step 2 (`curate`) to step 3 (`build`/«Сборка»)** — where the team is now assembled — via the `CLIENT_STEPS[].pillarKey` map. `trustPortability` («Закройте проект. Заберите spec…») stays on step 4 (`deliver`/«Владение»).
- **`lede` dropped** (key removed in all three locales; the `lede` prop removed from the client `<SectionHead>`).

> Note (pre-existing, out of scope): the EN `trustSecurity` diverges from RU/RO — EN reads "Studio's bot writes PRs in your repo — your team merges," while RU/RO read "Studio does not write code in your repository." Kept verbatim per locale; trust-line wording is not rewritten here.

Cross-ref: `changes/reposition-home/design.md § How we work (D-RH-10)`. Authority: `_methodology/research/market-landscape-and-positioning-md-ro-il-2026-06.md` §9.

### Services (applied 2026-06-14 from change `reposition-home`, RAP-1286)

Fourth block, re-aimed founder→owner — the most structural change in the umbrella. The home services block was a five-form package menu; it is now a **migration-into-the-AI-era narrative**. The line-950 `## Services` block above stays in place (hard rule 7). Component `apps/web/src/components/home/services-section.tsx` (`track="client"` branch), copy under `home.services.*`, anchor `id="services"`.

- **Reframe (D-RH-11).** Out: the five fixed forms (Discovery/Migration/Modular/Platform/Subscription), "Platform — 6-month minimum", and the "Что не берём" rejection list — all removed from the home. In: eyebrow → heading → intro (the company stopped growing because of internal chaos) → mechanism (current-state map + revenue-first + land-small + each specialist migrates their layer) → three concrete examples → trust close.
- **Guardrail.** Grounded + revenue-anchored, not AI-hype: no price, no package/menu language, no 6-month minimums. Concrete examples + current-state mapping keep it tangible; differentiation lives in the studio's specifics (own the spec; agents prepare / humans decide; no lock-in), carried in the trust close.
- **Eyebrow reframed** to «Переход в новую эпоху» / "Moving into the new era" / "Trecerea în noua eră" (was «Услуги»). Anchor `id="services"` unchanged.
- **Component change.** The home-only `ServicesCatalog` (`services-catalog.tsx`) is deleted; the client branch renders the narrative via `SectionHead` + plain paragraphs + a three-row example list (flat editorial idiom). The `track="founder"` variant (`#service-with-lens`) is untouched.
- **Scope boundary.** The five-card *content* (`web.services.<slug>.*`, incl. the platform 6-month copy) and `web.services.dontTakeShared.*` are **shared with `/services`** and left untouched — the home simply stops rendering them. `/services` (independent `ServiceFunnelCatalog` + `ServicesDecisionRouter`) is unchanged.
- **Strategic follow-up (carry forward).** After this, `/services` + the five `/services/<slug>` detail pages + the nav «Услуги» dropdown still present the old package model, one click from the new home narrative — a visible contradiction window. They are the **next change**, not cosmetic nav cleanup; resolve label + destination + page fate together. Orphan-cleanup follow-up: `ServiceList` + `web.services.dontTakeShared.*` lose their only consumer with `ServicesCatalog` gone.

Cross-ref: `changes/reposition-home/design.md § Services (D-RH-11)`. Authority: `_methodology/research/market-landscape-and-positioning-md-ro-il-2026-06.md` §9.

### Now building (applied 2026-06-14 from change `reposition-home`, RAP-1287)

Fifth block, re-aimed founder/tech-proof → **owner-proof**: the studio's own ventures, built on the method offered to clients (honest conviction, not client case studies). Component `apps/web/src/components/home/now-building.tsx`, anchor `id="now"`. **Work entries are Supabase `work_engagements` rows** (loaded via `apps/web/src/content/work/loader.ts`), *not* MDX — see the corpus-drift note below.

- **Chrome reframe (D-RH-12).** `home.nowBuilding.heading` + `lede` reframed to own-ventures-proof ("the method we bet our own companies on"); eyebrow «В работе» unchanged.
- **Four own ventures, fixed order.** All four are `in-progress` and shown in editorial order via a new **`home_priority` column** on `work_engagements` (loader sorts `home_priority asc nullsFirst:false → year desc → slug asc`): **1 studio · 2 Dentour · 3 VIVOD · 4 Senzo**. Senzo is new; Dentour was flipped from `published`; the studio summary was lightly improved (DRAFT pending Pavel); VIVOD summary kept.
- **Cap raised 2 → 4** (`now-building.tsx`) so all four render (2×2). This **overrides the prior "density cap-2 / one featured TacticalFrame" contract — deliberate, Pavel's call** (`featured` auto-resolves to none at 4 cards).
- **`engagement` aligned to own-venture for all four** (data honesty under the lede): Senzo/Dentour/studio `self`, VIVOD `co-founder` (genuinely co-founded — an own-venture sub-type). `i-avocat` (published, stealth) untouched.
- **`client` = sector/market tag** for own ventures (renders as the card meta `client · year`); cards are **single-language (English)** — summaries do not localize (pre-existing limitation; only chrome localizes). `#now` + the stealth/empty-state mechanism unchanged.

> Corpus-drift note: `openspec/current/home/entities.md` still describes work cards as MDX (`content/work/*.mdx`); the implementation is Supabase `work_engagements`. A `current/` drift audit is a tracked follow-up — the spec, not this block, is wrong.

Cross-ref: `changes/reposition-home/design.md § Now building (D-RH-12)`. Authority: `_methodology/research/market-landscape-and-positioning-md-ro-il-2026-06.md` §9.

### Connected stack (applied 2026-06-14 from change `reposition-home`, RAP-1288)

Sixth block, re-aimed founder/tech → owner. **First recorded copy contract** for this block — it had none (pre-existing debt: months on the home page without a contract). Component `apps/web/src/components/home/connected-stack.tsx`, copy under `home.connectedStack.*`, anchor **`id="connections"`**. i18n-only change (no component/test edit).

- **Reframe (D-RH-13).** The studio's stack presented as a **proven asset**: `heading` «Тот же стек, на котором работаем сами.» + `lede` "assembled and honed over years of fast-paced startup development in Israel; we build clients' projects on it too." `eyebrow` reframed «Подключения» → «Наш стек». This also fixes a latent mismatch — the old heading «Работает с вашими инструментами» implied the client's tools, but the tiles are the **studio's** stack.
- **Custom-connections line reframed in place (not duplicated).** The block already had a custom-connections prompt (`cta` + `ctaLink`); the `cta` was reframed to "custom connections to your systems — a specification for each", keeping `ctaLink` (→ `/start-project`). No new `customLine` key (would have duplicated the existing line).
- **Honesty.** No "best" superlative. Provenance ("Israeli startup fast-dev") is a Pavel-verified public claim. Only 3 of 9 tiles are `connected` (3 in-development, 3 planned); the per-tile status labels + `mvpFootnote` ("all nine connected by MVP close") are **kept verbatim** so the heading/lede ("we run on it ourselves") never implies all nine are in daily production. Tiles/statuses/`<details>` disclosure/`#connections` unchanged.

> Follow-ups (not done here): `mvpFootnote` dedup ("we run on it ourselves" now also in the lede) + de-jargon ("к закрытию MVP" reads as dev-jargon on an owner page) — left verbatim to protect the honesty caveat. Open question: the 9-tile dev-infra grid is now the most technical block on an owner-facing page — candidate to demote/simplify long-term (cf. operating-model).

Cross-ref: `changes/reposition-home/design.md § Connected stack (D-RH-13)`. Authority: `_methodology/research/market-landscape-and-positioning-md-ro-il-2026-06.md` §9.

### Founder note (applied 2026-06-14 from change `reposition-home`, RAP-1289)

Eighth block, expanded. Component `apps/web/src/components/home/founder-note.tsx`, copy under `home.founderNote.*`, anchor `id="founder-note"`. Supersedes the RAP-1190 D-HTN-5 one-line strip: a **two-column block** — reflection + signature on the left, a **large B&W portrait on the right** (one row at md+). Shipped over three PRs: reflection copy (#1951), portrait wiring (#1952), and the two-column layout (this PR).

- **Expansion (D-RH-15).** The single `credibility` line is replaced by a distilled founder reflection (`body`): origin (1990 notebook / imagination) → self-taught, learned from people → honestly-framed verifiable Israeli-startup exits (Soluto, Wibbitz, Perimeter 81, Zerto) → Zerto→HPE corporate experience → lived through every era → "the AI era demands we be more human, not less" → people-first. The studio is ~1 month old, so the founder's 20-year track record is the credibility anchor.
- **Honesty.** "Helped build the products of … startups that went through major exits", not "sold them". Only the four named (no unverified fifth). No dates beyond 1990 (the intifada/move-year detail with a known error stays out — essay-only). Pavel-confirmed: naming the four + the "helped build" framing + the HPE/corporate-experience claim.
- **Keys.** `eyebrow` reframed «Основатель»→«От основателя»; `credibility`→`body`; `name` kept; **`linkUrl` corrected `t.me/paveliko`→`t.me/pavelrapoport`** (matches the hero CTA / authoritative handle). `linkLabel` + anchor unchanged.
- **Component.** Two-column layout (`flex-col` → `md:flex-row md:items-center`): **left** = eyebrow → reflection body (serif, ~60ch) → name + Telegram signature; **right** = a **large B&W portrait** (`/founder/pavel-rapoport.jpg`, 800×1218 source, `md:w-[360px]`, `aspect-[2/3]`, `grayscale`, `object-cover` via `next/image`). Sharp corners, flat-editorial tokens.

> Follow-up (not this change): a **fuller founder essay on a dedicated page** with a "full story →" link from this block.

Cross-ref: `changes/reposition-home/design.md § Founder note (D-RH-15)`. Authority: `_methodology/research/market-landscape-and-positioning-md-ro-il-2026-06.md` §9.

### Declutter scroll (applied 2026-06-14 from change `reposition-home`, RAP-1290)

Ninth deliverable — **structural, no copy**. Four blocks removed from the home scroll (`apps/web/src/app/[locale]/(marketing)/page.tsx` composition only), following the RAP-1190 D-HTN-6/D-HTN-7 precedent (remove from composition + arc, **retain component files + i18n keys**).

- **Removed from scroll (D-RH-16):** `connected-stack` (#connections — dev-infra logos, low owner-relevance), `operating-model` (#operating-model — internal agent roster + mechanics, already carried by what-we-build / how-we-work / founder-note), `for-founders` (#for-founders — founder audience → `/founders`, D-RH-2), `for-legacy` (#for-legacy — legacy-migration audience → `/legacy`, D-RH-2).
- **Retained:** all four component files + their i18n keys (`home.connectedStack/operatingModel/forFounders/forLegacy`, all locales) — orphaned but harmless, parity unchanged, reversible. So are `operating-model`'s children (`operating-model-diagram`, `operating-model-proof`) and the now-uncalled `/api/operating-model/stats` route. **Logged as cleanup-debt** (a future change strips components + keys + dead route together).
- **Reachability:** `/founders` + `/legacy` (own `page.tsx`) carry these audiences; nav "For founders" (→ `ROUTES.founders`) + footer "Legacy" (→ `/legacy`) unchanged. Internal material lives on `/method`, `/openspec`, `/principles`.
- **Paint-map (D-RH-17):** P3 ModulorPattern retired with its host `for-legacy` → home pattern budget **1/1 (P4 hatch at closing-cta only)**. P3 **not relocated** (for-legacy was its only viable host per the structural audit). The "13 current home sections" paint-map count + the `### Founder note` "between OperatingModel and ForFounders" position note and its "bare · adjacent to applied" verdict are now **stale** — founder-note follows now-building and is adjacent to no pattern.

New arc (see `flows.md` amendment): `Hero → WhatWeBuild → HowWeWork → Services → NowBuilding → FounderNote → TheNetworkAndCommunity → [LabPreview] → ClosingCTA`.

Cross-ref: `changes/reposition-home/design.md § Declutter scroll (D-RH-16/17)`. Authority: `_methodology/research/market-landscape-and-positioning-md-ro-il-2026-06.md` §9; precedent `archive/2026-05-24-sync-home-arc-with-rap-1190/` (D-HTN-6/7).

### Plain-language pass (applied 2026-06-14 from change `reposition-home`, RAP-1291)

Change 1 of the post-critique series — a **de-jargon copy pass** on the existing owner scroll, **decision-independent** (true under any resolution of the open positioning fork), so it ships before that decision. Authority: external critique ("two voices" doc — Operator vs Architect; jargon kills trust on the front door). **Supersedes D-RH-9 / #1946** (see D-RH-18).

- **what-we-build (D-RH-18):** the orchestra/conductor framing — text **and** the `OrchestraDiagram` visual — is retired in favour of plain owner-outcome copy. The diagram block + its `whatWeBuild.diagram.*` i18n keys are removed from this section (the shared `OrchestraDiagram` component is kept — `legacy-how-we-work` still consumes it). The OpenSpec/GitHub proof link (`<a>` + `whatWeBuild.trustAuthorshipLink`/`…Href`) is removed — it **relocates** to a future "how it works inside" door; `/openspec` + the closing-CTA OpenSpec link remain the interim proof surfaces. `eyebrow` («Что мы строим») unchanged.
- **how-we-work:** `продакшен`/`spec` de-jargoned in the trust lines. The RU/EN repo-write contradiction (RU claimed "studio does not write code"; EN claimed "bot writes PRs") is resolved in plain, control-framed language — *we prepare the changes; only your team applies them; outside specialists have no access to your working systems* — deliberately avoiding `PR`/`repo`/`merge` jargon. The confirmed fact (studio prepares code, the client's team approves/applies it) is preserved; the framing reads as owner control, not intrusion. Security promise ("no access to your working systems") confirmed unconditionally true before merge.
- **services / «Из беспорядка» (`services.intro`):** `AI-нативная`/`AI-native`/`AI-nativ` dropped; the routine clause replaced with "агенты берут на себя повторяющуюся работу, а решения остаются за людьми" (anti-replacement reassurance). Rest of the block unchanged.
- **meta description (`home.meta.description`):** `AI-нативный слой доставки` / "AI-native delivery layer" replaced with "технологии работают на людей, а не вместо них" / "technology that works for people, not instead of them". `meta.title` untouched.
- Applied in all three locales (ru verbatim; en/ro AI-drafted, pending native review).

**Out of scope / deferred (logged, not done here):** `/founders` still carries "AI-native platforms" (`home.hero.eyebrow`, old hero — technical audience, conscious deferral) and operatingModel jargon (not on the home scroll per D-RH-16); the home footer's «AI-оркестрацией»; the closing-CTA OpenSpec link; `/services` page metadata. A future "zero jargon on home" sweep + the Phase-2 positioning fork pick these up.

Cross-ref: `changes/reposition-home/design.md § Plain-language pass (D-RH-18)`. Authority: external critique ("two voices") + `_methodology/research/market-landscape-and-positioning-md-ro-il-2026-06.md`.

### Phase 2 — reposition (spine A) — Change A (applied 2026-06-15 from change `reposition-home`, RAP-1292)

First change of Phase 2 (the repositioning; **not** decision-independent — embodies spine A, D-RH-19). Foundation: new hero copy + re-sequence. Ships ahead of changes B–H.

- **New block sequence (D-RH-22):** `Hero → Services(pain «Из беспорядка») → FounderNote(trust) → NowBuilding(proof) → HowWeWork → WhatWeBuild(agents) → ClosingCTA`. Three structural moves vs the D-RH-16 arc: **pain ↑** (Services 4→2), **founder ↑** (FounderNote 6→3), **agents ↓** (WhatWeBuild 2→6 — shown after trust). FounderNote moves up with its **current** copy as interim (rewrite = Change B, to run immediately after).
- **Removed from the home scroll:** `TheNetworkAndCommunity` (`#network-and-community`, `spc` audience → its own door per D-RH-20) and `LabPreview` (`#lab`, single-audience focus — conscious scope addition beyond the original spec, confirmed with Pavel). Both component files + standalone pages retained.
- **Hero copy (D-RH-23, `web.home.heroC`, all locales):** added bare-name `eyebrow` «Павел Рапопорт»; added first-person `positioning` line («Помогаю расти бизнесам… технологии служат людям, а не заменяют их»); renamed `subhead`→`riskReversal` («Начинаю с диагностики, а не с прайс-листа — и с малого проверяемого шага»). Heading (`line1/2/3`) + primary CTA unchanged. **Secondary CTA repointed `#what`→`#services` and relabelled «Что мы строим →»→«С чего мы начинаем →»** so it leads into the trust arc, not past it. Voice: heading «мы», sub-lines «я» (studio-with-a-face). EN/RO AI-drafted, pending native review.
- **OpenSpec "how it works inside" door:** the relocation of the former orchestra/agent depth (down from #2) is Change D, not this change.

Cross-ref: `changes/reposition-home/design.md § Phase 2 — reposition (spine A) (D-RH-19…23)` + `flows.md § Phase 2 — reposition (spine A)`. Authority: external "two voices" critique + per-section live-site review + `_methodology/research/market-landscape-and-positioning-md-ro-il-2026-06.md`.

#### Change B — founder block as trust anchor (applied 2026-06-15, RAP-1293, D-RH-24)

The founder block (`#founder-note`, `web.home.founderNote`) — at position 3 since Change A — is rewritten as the spine-A trust anchor. **Supersedes the Change-A interim copy** (which ended inward, «…я забочусь о них — они обо мне», about the team).

- **Heading** (`eyebrow`): «От основателя» → **«Кто я»** (EN «Who I am», RO «Cine sunt»).
- **Body**: single `body` key → **`body1`/`body2`/`body3`** (three paragraphs), client-facing arc — story → why I can solve your *stalled growth* → human-first values, ending facing the client. Component renders three `<p>` in an inner `gap-4` wrapper.
- **Unchanged**: `name`, Telegram CTA (`linkLabel`/`linkUrl`), the 2:3 grayscale portrait, two-column layout, and the block's position (fixed in Change A — B is copy + the paragraph-split tweak only).
- **RO register = «tu»** (matches the entire live RO site; the RU «вы» ↔ RO «tu» divergence is pre-existing + site-wide, logged as a separate follow-up). EN/RO AI-drafted, pending native review.

#### Change G — canonical positioning phrasing (applied 2026-06-15, RAP-1294, D-RH-25 / D-RH-27)

Aligns the home to one anti-replacement phrase + clears a leftover. i18n-only, 2 keys × 3 locales.

- **`web.home.meta.description`** (all locales): «технологии работают на людей, а не вместо них» → canonical **«технологии служат людям, а не заменяют их»** (D-RH-25) — verbatim from the live hero positioning line; the meta now reads in the hero's voice (og:description + twitter:description derive from the same key, so they align too).
- **`web.home.services.trust`** (all locales): stray «спецификация» → «её описание» (EN «its spec»→«its documentation»; RO «specificația»→«descrierea lui»), matching the Phase-1 what-we-build ownership wording.
- **RO register flip begins (D-RH-27):** these two RO strings are written in the new **formal «dumneavoastră»** (supersedes Change-B «tu»); the rest of the live RO «tu» copy flips in a separate site-wide RO-formalization pass (tracked in `design.md` index). EN/RO AI-drafted, pending native review.
- Off-home `spec`-word occurrences (`hero.sub`, `connectedStack.*`, `operatingModel.*`) deliberately untouched (not on the home scroll → Change E).
