Planner App→
Numeral: Fraunces 300. Serif letterforms read editorial and dramatic.
Two changes from v4, both driven by the same principle: visual marks that sit in the same frame should read as siblings, not strangers.
(1) Typography fix. v4 had numerals and monograms on Fraunces and icons on lucide-react. Fraunces is a transitional display serif; lucide draws with geometric sans strokes. Sitting in the same grid, types 3, 5, and 6 looked like three different projects pretending to be one. v5 moves numerals and monograms to Geist sans 500 and tunes lucide to stroke-width 2.25 so all three share a single visual family. Fraunces stays where it belongs — headings and prose — and is no longer asked to carry UI marks it wasn't drawn for.
(2) Featured card variations. With the gradient-mark type now reserved to featured cards only (Q1 resolution below), featured needs its own treatment vocabulary. v5 explores four options: gradient border (F1), gradient kicker pill (F2), gradient-mark strip (F3), and the combined border-plus-strip "hero" treatment (F4) reserved for the single most important card on a page.
The v4 "three fonts in one frame" problem shows up clearest in a row of three cards. Below: v4 first, then v5. Same strip shell, same register colour, same sizing rules — only the typography family changes.
Numeral: Fraunces 300. Serif letterforms read editorial and dramatic.
Icon: lucide stroke 1.5. Geometric sans line-work with rounded caps.
Numeral: Geist 500. Clean lining figures, tight tracking, tabular-nums locked.
Icon: lucide stroke 2.25. Heavier stroke visually matches Geist 500 glyph weight.
Monogram: Geist 500. Same family as numeral, half the size, same stroke weight.
A featured card is the anchor of a grid — the "start here" mark. There is at most one per grid (the landing 2×2, the /projects index hero, the /writing index hero). It doesn't replace hierarchy from content — it reinforces the hierarchy that's already there from position and writing.
With Q1 resolved to gradient-mark is reserved for featured cards only, the gradient leaves the default-content pool entirely. It becomes a featured-card treatment, not a visual type the author can pick. Four variations below, from lightest to heaviest.
Border says "featured." Numeral says "this is piece 01." The register colour (royal) still reads. Everything else unchanged.
Writing-register featured. Same gradient border; the violet register still reads in the kicker, tags, and icon stroke.
Featured signal lives inside the content, not on the perimeter. Reads quieter than F1 at a glance.
Same treatment, writing side. Pill uses the gradient; register colour still reads in the icon stroke and tag tint.
The strip IS the gradient. No screenshot, no diagram, no numeral — the gradient mark is the imagery. Strongest "featured" signal short of combining treatments.
Register-neutral by design — the gradient is the signal, register colour still reads in kicker, tags, and border on hover.
Border plus gradient strip. Reserved for the hero card on the landing grid — the unambiguous "start here" anchor. Never more than one per page.
F4 on the writing side. Same treatment, same one-per-page rule. Only appears on the /writing index hero, never inside a 2×2 landing grid that already has a work hero.
A GTD personal planner built around persistent SMS reminders, UTC-safe scheduling, and spend-protected AI coaching.
Coles recipes become a single consolidated shopping trolley. POC in three weekends.
Killswitch, budget cap, idempotency, rollback. Why each layer is non-negotiable.
Writing as the thing that forces you to understand what you were claiming.
| Option | Where the gradient lives | Strip freedom | Strength | Good for |
|---|---|---|---|---|
| F1 · Gradient border | Perimeter | Any visual type | Light | Any featured card where strip content needs to do the talking. Plays well with screenshot and diagram. |
| F2 · Gradient kicker pill | Content (kicker label) | Any visual type | Lightest | Featured-tagging without perimeter weight. Subtle — might read as "just a label style" at distance. |
| F3 · Gradient-mark strip | Strip (fills the whole slot) | None — the strip IS the gradient | Strong | Featured cards where no specific imagery earned the slot. Reserved — not a "no screenshot available" fallback. |
| F4 · Hero (border + strip) | Perimeter + strip | None | Maximum | The single anchor card on the landing grid. At most one per page. The clearest "start here" the system allows. |
Ship all four as available treatments, but apply them with a fixed rule. The rule has two parts:
/projects index hero, /writing index hero, related-work footer anchors.F2 (gradient kicker pill) drops out. Two reasons: it's too subtle to carry a featured signal on its own at a glance, and it introduces a second role for the kicker label that conflicts with the kicker's existing job (index number, type label). One more element is one more thing to maintain — and F1 already covers the "light featured" case better.
Why this works. F1 plays with every visual type (author keeps control of the imagery slot), F4 is the unambiguous hero (one per page, impossible to confuse with "just a featured card"), and the gradient-mark strip never leaks out of F4 context — which is exactly the discipline Q1 was reaching for. The gradient stays rare and meaningful. Every time a reader sees it, it's saying "this is the one."
Implementation in the Card component: add an optional prop featured?: "border" | "hero" (default: none). The "hero" variant forces the strip to the gradient-mark type regardless of what imagery was passed — the component ignores the other imagery props when featured === "hero". This means the author can't accidentally combine F4 with a screenshot; the combination is either hero treatment or normal treatment, nothing in between.
With typography unified and featured treatments defined, both open questions from v4 can lock. The card component spec is now a complete design — everything below ships into the Card component's prop surface.
The gradient-mark strip type (v-gradmark) is no longer part of the author's default-content pool. It cannot be picked for a regular card — not for palette-subject writing posts, not for "nothing else fits" cases, not as a fallback. The default pool is five visual types: screenshot, diagram, numeral, icon, monogram. Gradient-mark only appears as the strip half of the F4 hero treatment, and F4 is capped at one per page on the landing grid only.
Why stricter than the original recommendation. Keeping gradient-mark available for palette-subject writing posts ("Royal Tonal in twelve steps") looked reasonable, but it creates two authorship contexts for the gradient (featured cards + "my post is about colour") and those two contexts will drift — the line between "about colour" and "mentions colour" is not defensible. Reserving it to a single context (featured hero treatment, one per page) makes the rule mechanical: the gradient marks the hero, nothing else. Palette-subject writing posts use whatever visual type fits (typically numeral or diagram), and if one of them happens to earn the hero slot on the /writing index, the gradient shows up through F4 — not through a separate authorship permission.
The Card component's imagery surface stays small: kind: "screenshot" | "diagram" | "numeral" | "icon" | "monogram". The M5 (meta split) and M6 (detail zoom) variants are composition decisions inside the <Screenshot> helper, not sub-types on Card. The helper signature:
<Screenshot src="..." variant="detail" | "meta-split" eyebrow? num? />
Default is variant="detail" (M6). M5 is explicit opt-in — the author types variant="meta-split" when they want anchor treatment. This makes M6 the common case (zero effort) and keeps M5's "max one per grid" rule a deliberate choice at the call site, not an accident. The hierarchy rule lives in the style guide and is enforced by review, since it's a page-level constraint TS can't check anyway.
Why not sub-types on Card. The main argument for sub-typing was compile-time misuse prevention — but the constraint we'd be enforcing ("max one M5 per grid") is about page composition, not component use. TS can't express "at most one instance in this map call" without turning the Card surface into something much more complicated. Keeping Card's surface simple means M5/M6 can evolve (new variants, retired variants) without a Card breaking change. The composition decision stays in the component that implements it.
Numeral: Geist 500, 120px, tight tracking, tabular lining nums. Monogram: Geist 500, 72px, slightly looser tracking. Icon: lucide stroke-width 2.25 at 88px. All three marks share the shared shell from v4 (same background, padding, grid texture, register tint). Fraunces stays on headings and long-form prose — it is not used for UI marks anywhere in the card system.
featured?: "border" | "hero" on the Card component. F1 "border" adds the gradient perimeter and leaves strip content untouched — any visual type is valid. F4 "hero" forces the strip to gradient-mark regardless of the imagery props passed, and is capped at one per page on the landing grid only. F2 (kicker pill) and F3 (strip-only) are dropped from the API surface.
If v5 locks, the card component spec is frozen. The next work on the critical path is not a card iteration — it's chunk 4a.4, the workspace-wide writing and imagery style guide at .claude/rules/writing-style.md. Foundation work (4a.4 → 4a.5 → 4a.6) still gates chunk 4b.
The card component gets built in chunk 4c.1 alongside the case study layout mockups. By then the spec is stable, the decisions are locked, and the component can be written straight from this doc — no more live iteration. The iteration trail (v1 → v5) will be preserved for the eventual design-system case study, where "here's what we rejected at each step and why" becomes the spine of the narrative.