Portfolio · card deep-dive · v6 · final · 2026-04-12

Featured card system
+ tuned typography

v6 locks the card spec. Three changes from v5 drive it, all in response to your direction: (1) Geist 500 at 120px was overwhelming the content — tuned down to Geist 400 with lucide stroke at 2; (2) featured treatment is unified — border + "FEATURED" kicker pill + gradient effect on the visual element, one treatment, no tiers; (3) gradient-mark strip type is dropped entirely — the gradient lives only on featured-card treatments now, not as a visual type an author can pick.

The "one exception" rule: on a featured card, and only on a featured card, the gradient effect applies to whatever visual type the author chose — screenshot gets a gradient auto-tint, diagram gets a gradient overlay, numeral and monogram get gradient text fills, icon gets a gradient SVG stroke. The gradient becomes the mark of "featured" across every visual type, instead of gradient-mark being its own type that replaces content.

§1 · typography — tuned lighter

Geist 400 for text marks, lucide stroke 2

v5 moved numerals and monograms to Geist 500 to match lucide's geometric weight. At 120px that read as too heavy — the numeral started competing with the card title for attention instead of sitting under it. v6 drops everything one weight step: Geist 400 for numeral and monogram, lucide stroke-width 2 for icon. Same family, one weight lighter, same visual pairing.

v5 — Geist 500 + lucide 2.25. The 120px numeral competes with the title; at 2m reading distance the numeral is the first thing your eye lands on, not the card's real content.
01
SELECTED WORK · 01

Planner App

v5 — Geist 500 / 120px. Heavy enough to pull focus from the title.

  • v5
SELECTED WORK · 03

MOB analysis

v5 — lucide stroke 2.25. Matches Geist 500 but reads heavy next to lighter body text.

  • v5
PLN
SELECTED WORK · 01

Planner App

v5 — Geist 500 / 72px. Smaller size masks the weight, but still on the heavy side.

  • v5
v6 — Geist 400 + lucide 2. Numeral recedes to a supporting role; the card title reads as the primary element. Icon stroke drops in step so the family stays consistent.
01
SELECTED WORK · 01

Planner App

v6 — Geist 400 / 120px. Numeral now supports the title, doesn't compete with it.

  • v6
SELECTED WORK · 03

MOB analysis

v6 — lucide stroke 2. Sits in the same weight register as Geist 400.

  • v6
PLN
SELECTED WORK · 01

Planner App

v6 — Geist 400 / 72px. Lighter but still confident at this size.

  • v6
Sibling rule still holds. v6 moves all three marks in lockstep — numeral, icon, monogram all step down one notch together. The shared-shell logic from v4 still means they render as family in any frame. Fraunces 500 stays on the card title (h3), which now reads as the dominant element in the content column — exactly what the card hierarchy wants.
§2 · featured card treatment

One treatment, five visual types

Every featured card gets three things, always together: (1) a gradient border around the perimeter, (2) a gradient "FEATURED" kicker pill as the single kicker content, (3) a gradient effect applied to whatever visual type the strip is using. This is the one exception to the "text marks and icons use card register colour, never gradient" rule — on a featured card, the visual element becomes the gradient.

There are no tiers. A card is featured or it isn't. One per grid, as before. The visual type the author picks is still their call — the featured treatment adapts to all five.

Type 1 — Screenshot featured. The mix-blend-mode: color overlay (opacity 0.9) already existed as the auto-tint mechanism; on a featured card, the overlay background changes from flat royal-8 to var(--grad-rv). The screenshot's pixels now carry the gradient across the strip — royal top-left, violet bottom-right.
Type 2 — Diagram featured. Same mix-blend-mode: color technique applied as a ::after overlay on the strip. Diagram strokes now render in gradient colour — royal in the top-left, violet in the bottom-right. Luminance of the strokes is preserved so the diagram still reads.
Type 3 — Numeral featured. The numeral drops its card-register colour and picks up a gradient fill via background-clip: text. The numeral reads as a gradient mark directly — the featured signal lives on the mark itself, not on an overlay.
Type 5 — Icon featured. The lucide SVG stroke swaps from a flat card-register colour to a linearGradient referenced via stroke="url(#grad-rv-svg)". One shared gradient definition sits in a hidden SVG at the top of the document; every featured icon references it. Result: icon strokes trace the gradient from corner to corner.
Type 6 — Monogram featured. Same background-clip: text technique as the numeral. Two- or three-letter lockups pick up the gradient fill directly — the mark IS the gradient.
In context — landing 2×2 grid. One featured card (screenshot) sits alongside three non-featured cards using three different visual types. The featured card reads as the anchor without overwhelming the others; the gradient border, gradient kicker pill, and gradient auto-tinted screenshot all push in the same direction.
Input Parse Output
SELECTED WORK · 02

The Weekly

Coles recipes become a single consolidated shopping trolley. POC in three weekends.

  • REACT
  • POC
R/W
NOTE · FRAGMENT

Read-write reciprocity

Writing as the thing that forces you to understand what you were claiming.

  • notes
Visual type Gradient effect Technique
Screenshot Auto-tint overlay ::after with background: var(--grad-rv), mix-blend-mode: color, opacity 0.9. Same mechanism as the non-featured auto-tint, different fill.
Diagram Overlay blend Same ::after + mix-blend-mode: color technique. Diagram strokes retain luminance, pick up gradient hue.
Numeral Text gradient fill background: var(--grad-rv) with background-clip: text. The "01" / "04" mark IS the gradient.
Icon SVG stroke reference stroke: url(#grad-rv-svg). Single shared <linearGradient> definition at document root; every featured icon references it.
Monogram Text gradient fill Same as numeral. Two- or three-letter lockups take the gradient via background-clip: text.
§3 · border thickness

1.5px vs 2px side by side

Your call. Same featured card, same treatment, different border weight. 1.5px is what v5 shipped; 2px is the "slightly louder" alternative.

1.5px border — current v5/v6 default. Subtle perimeter; gradient is present but not shouting.
2px border — louder alternative. Perimeter becomes a deliberate frame; the featured card pops harder off the page.
My lean: 2px. The 1.5px version reads a little timid next to the full gradient treatment on the visual element — the border gives up too much of the "featured" job to the strip overlay, and on a writing card with a numeral the perimeter almost disappears. 2px reclaims its share of the signal. Not a strong preference though — take a look and tell me which one you want to lock.
§4 · decisions locked

Card spec freeze

Everything below ships into the Card component's prop surface. Nothing left open except the 1.5px / 2px border pick in §3.

Locked

Typography Geist 400 for centred marks

Numeral: Geist 400, 120px, tight tracking, tabular lining nums. Monogram: Geist 400, 72px. Icon: lucide stroke-width 2 at 88px. Shared shell unchanged from v4 (same background, padding, grid texture, register tint). Fraunces stays on headings and prose — never used for UI marks.

Featured One treatment, three things together

Every featured card gets all three: gradient border (1.5px or 2px — TBD in §3), "FEATURED" gradient kicker pill (single word, replaces the normal kicker content entirely), and a gradient effect on the visual element adapted to the visual type the author picked. No tiered options, no opt-out on any of the three. Card prop:

  • featured?: boolean — that's the whole API.

At most one featured card per grid. Enforced by review, not by types.

Gradient Reserved to featured cards, five techniques

The gradient (var(--grad-rv)) appears in exactly the following places:

  • Featured-card border — perimeter frame.
  • Featured-card kicker pill — "FEATURED" label background.
  • Featured-card visual element — type-specific:
    • Screenshot: mix-blend-mode: color overlay with gradient fill.
    • Diagram: same technique as screenshot.
    • Numeral: background-clip: text gradient fill.
    • Monogram: background-clip: text gradient fill.
    • Icon: stroke="url(#grad-rv-svg)" via shared SVG gradient definition.

The v5 "gradient-mark strip" visual type is dropped entirely. There is no sixth visual type. The default author pool is five types: screenshot, diagram, numeral, icon, monogram. The gradient is never a visual type an author picks — it's an effect that applies when the author (or the system) sets featured to true.

Q2 Screenshot helper variant API (unchanged from v5)

The Card component's imagery surface stays small. M5 (meta split) and M6 (detail zoom) live in the <Screenshot> helper as a variant prop. Default is variant="detail" (M6); M5 is explicit opt-in via variant="meta-split". The hierarchy rule ("max one M5 per grid") lives in the style guide and is enforced by review.

Visual types Five, no more

The final visual-type pool: screenshot, diagram, numeral, icon, monogram. Card prop: kind: "screenshot" | "diagram" | "numeral" | "icon" | "monogram". Rendering rules per type unchanged from v4 — shared shell for centred marks (numeral / icon / monogram), dedicated treatment for screenshot and diagram.

§5 · next

Card spec freezes, foundation work resumes

Once you pick the border thickness in §3, the card component spec is frozen. Nothing else on the card side until chunk 4c.1 (page layout mockups), when the component gets built straight from this doc. The iteration trail (v1 → v6) stays preserved in plans/portfolio-stitch-assets/ as the spine of a future design-system case study — "here's what we rejected at each step and why" is more interesting than the final spec alone.

The next work on the critical path is chunk 4a.4 — synthesising the voice research, diary audit, and imagery standards into .claude/rules/writing-style.md at the workspace root. Foundation work (4a.4 → 4a.5 → 4a.6) still gates chunk 4b.