11 KiB
type, name, version, status, source, audience
| type | name | version | status | source | audience | ||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| design-system | Kontra — Broadsheet Editorial | 1.0.0 | approved 2026-09-08 |
|
desktop + mobile news-opinion site (Kontra) |
Kontra — DESIGN.md (Broadsheet Editorial)
Adopted 2026-09-08 from Google Stitch "Broadsheet Editorial" panel. Finalized 2026-09-08: brand is Kontra (not "Kontra Day"); centered masthead; "Topics" heading; responsive (≥1024 / 641–1023 / ≤640) with dropdown topic nav
- mobile sections drawer. Clickable prototype:
prototype/index.html,prototype/article.html, tokens inprototype/assets/kontra.css. Palette + typography reconciled to the rendered Stitch export (Image 2.html) — the DESIGN.md export used slightly different hexes (e.g.#F8F6F0vs#fbf9f3); the rendered HTML is what you actually saw, so it wins. Differences noted inline.
Identity
A tactile, deliberate reading environment inspired by physical print journalism and high-grade editorial typography. Intellectual, trustworthy, measured, authorial. Ultra-clean editorial minimalism: structure from hairline rules, typographic scale, and whitespace — not shadows, rounded containers, or neon accents. Rejects app-clutter (FABs, heavy shadows, dense cards).
Kontra adaptation: from a mobile-first Stitch panel, we built a desktop-first site: front page with lead stack + Topics grid + Latest feed, subject indexes, wider measures. Tokens carry over; the desktop layout is finalized in §Layout.
Palette
Base is warm newsprint, ink is soft charcoal, accent is editorial vermilion. No pure black-on-white (optical glare).
| Token | Value (rendered) | Role |
|---|---|---|
--canvas |
#fbf9f3 |
Base page background (newsprint) |
--canvas-bright |
#ffffff |
Cards/forms on dark wells; bright surfaces |
--surface |
#f0eee8 |
Secondary canvas: section wells, meta blocks |
--surface-hi |
#eae8e2 |
Tertiary wells, footer sections |
--surface-highest |
#e4e2dd |
Hairline borders, dividers (also #e4e2dd) |
--ink |
#1b1c18 |
Primary text (soft charcoal, not black) |
--ink-muted |
#444748 |
Byline, captions, secondary metadata |
--ink-faint |
#747878 |
Timestamps, reading time, tertiary |
--accent |
#ad3222 |
Editorial vermilion: breaking tags, section headers, links, active states, numerals |
--accent-deep |
#8b190d |
Accent hover/pressed states (from secondary-fixed-variant) |
--accent-soft |
#ffdad4 |
Accent tint wells, selection bg |
--on-accent-soft |
#400100 |
Text on accent-soft (selection) |
--ink-inverse |
#1c1b1b |
Dark solid: primary buttons, masthead icon well |
--on-ink-inverse |
#ffffff |
Text/icon on ink-inverse |
--outline |
#c4c7c7 |
Subtle separators, placeholder |
--hairline |
#e4e2dd |
1px rules (same as surface-highest) |
--scrim |
rgba(26,26,26,0.4) |
Warm charcoal scrim for modals/drawers |
Notes
- Default button:
--ink-inversebg,--on-ink-inversetext; hover →--accent. - Focus: hairline transitions
--hairline→--ink, no glow/shadow. - Selection:
bg #ffdad4, text#400100.
Typography
| Token | Family | Size | Weight | Line | Track |
|---|---|---|---|---|---|
--font-display |
Newsreader (serif) | — | — | — | — |
--font-body |
Literata (serif, print) | — | — | — | — |
--font-ui |
Work Sans (sans) | — | — | — | — |
masthead |
Newsreader | 38px (mob 30px) | 700 | 1.16 (44px) | -3% |
headline-xl |
Newsreader | 32px (mob 28px) | 600 | 1.19 (38px) | -2% |
headline-lg |
Newsreader | 24px | 600 | 1.25 | -1% |
headline-md |
Newsreader | 20px | 500 | 1.3 | 0 |
headline-sm |
Newsreader | 18px | 600 | 1.33 | 0 |
body-lead |
Literata | 19px | 400 | 1.58 (30px) | -0.5% |
body-md |
Literata | 17px | 400 | 1.65 (28px) | 0 |
body-sm |
Literata | 14px | 400 | 1.57 (22px) | 0 |
quote |
Newsreader italic | 21–22px | 400 | 1.45 | -1% |
label-caps |
Work Sans | 11px | 600 | 16px | +12% (uppercase) |
label-meta |
Work Sans | 12px | 500 | 18px | +2% |
label-ui |
Work Sans | 14px | 500 | 20px | +1% |
Rules
- Body measure ≤ 68ch (
max-width: 65ch); content column42remmax. - Italic serif reserved: book titles, direct quotes, editorial side notes only.
- Section lead-ins:
label-capsin--accentabove headline. - Headlines: Newsreader, tight tracking, no hyphenation; keep 2-line constraint on feeds.
- Hierarchy (approved tweak): sub-headings in feeds/subject boxes render one step smaller than the box's primary headline, and decks one step smaller again — so the leading story reads clearly above the secondary tiers.
- Fonts self-hosted (woff2) — not Google CDN at runtime (page 3 of plan).
Spacing / Grid
- Baseline: 8px grid. Vertical rhythm via
--space-md(16px) /--space-lg(24px) /--space-xl(32px). - Gutter: mobile
20px(1.25rem); tablet/desktop scales to24–32px. - Content column: centered
max-width: 42rem(672px) for article body. - Front page: two/three-tier column grid (12-col on ≥1024px) — see Desktop Extension.
- Line length hard cap:
65chbody.
Shape / Elevation
- 0px radius everywhere (buttons, cards, inputs, chips, image frames). Sharp right angles only.
- Circular allowed only for: author avatars, audio scrubbers.
- No drop shadows, no blur-layered elevation. Depth is planar + hairlines.
- Modals/drawers: solid sheet, 1px
--inkborder,--scrimbackup. Sticky masthead: hairline bottom border only.
Components
Masthead (sticky top)
- Meta line: date • edition (label-caps,
--ink-muted), edition flag (label-caps,--accent). - Brand row: masthead title (Newsreader,
--ink) + search icon + avatar circle (--ink-inverse). - Section ribbon: horizontal scroll, label-caps
--ink-muted; active =--ink+ 2px bottom rule; accent section (--accent). - Border-bottom hairline;
bg --canvas/95+backdrop-blur-md(only blur allowed).
Bottom nav (mobile)
- Fixed bar, 4 items (Edition / Sections / Reader Mode / Saved), icon + 11px label, hairline top border. (Desktop: replaced by persistent top nav.)
Article header
- Section tag chip (
--accentlabel-caps + 4px dot) →headline-xl→ byline (--inklabel-meta) → desk • dateline • read time (--ink-faint). Hairline under meta.
Hero plate / figure
- Full-bleed image, max-h 72vh; grayscale + slightly boosted contrast (Stitch used
contrast-108, true B&W look). - Figcaption:
Fig. Nlabel-caps--ink+ plate/credit--ink-faint; 1-2 line descriptionbody-sm--ink-muted. Hairline frame.
Pull quote
--surfacewell,4pxleft rule--accent, giant serif opening quote (--accent, 38px, opacity-80), Newsreader italicquotetext, cite in--accentlabel-caps with hairline above. Sharp corners.
Photo strip / field notes
- Section header:
label-caps--ink+ small icon; "X of Y"--ink-faint. - Grid (1-col mobile, 2-col tablet+). Figures:
--surfacewell, 1px hairline frame, 3:2 image,--accentlabel-caps fig caption + body-sm description.
Feed list (related / subject index)
- Stacked rows divided by hairlines. Each: section tag (
--accentlabel-caps), primary headline (headline-sm, 17–18px), sub-headline one step smaller (headline-sm16px), deckbody-sm13px--ink-muted, byline+read timelabel-meta--ink-faint. Thumb 3:2 or 16:9 with hairline frame. Hover: row/hairline shifts--ink-faint; headline →--accent. - Rows are touch-friendly (min 44px).
Subject grid boxes (front page)
- Approved: lower boxes titled World / Politics / Culture / Tech etc. (subject names). Each box: subject title (
label-caps--accent), latest story headline 17px (headline-sm), sub-headline 16px, deck 13px, byline. Subject titles stay full strength; story sub-headings step down in size to differentiate tiers.
Buttons
- Primary: solid
--ink-inverse,label-ui--on-ink-inverse, 0px, min-h 42–44px, hover →--accent. Include uppercaselabel-capsstyle for action labels. - Secondary: 1px
--inkborder,--inklabel; press = 10%--inktint. - Text links: 1px underline 3px below baseline,
--accentor--ink-faint.
Forms
- Underline or 1px bordered box (
--hairline); focus border →--ink(no glow). Placeholder--ink-faintin Literata. Sharp corners.
Newsletter / save modules
--surfaceor white card, hairline border,label-caps--accenttitle, icon, body-sm copy, inline form (input + primary button). HTMXhx-postswap-outerHTML.
Layout (finalized 2026-09-08)
Brand: Kontra (centered masthead). Home section heading: Topics (not "By Subject").
- Front page (home template):
- Lead stack: featured article (hero plate + headline-xl + deck) 2fr + right rail of
headline-mdsecondary stories 1fr. - Topics grid: 4 subject boxes (World / Politics / Culture / Tech) — kicker
--accentlabel-caps, 17px s-head, 16px s-sub, byline, "More X →". 4-col desktop → 2-col tablet → 1-col mobile. Approved. - Latest feed: 2-col article rows (kicker + headline + sub + meta) → 1-col mobile.
- Lead stack: featured article (hero plate + headline-xl + deck) 2fr + right rail of
- Subject index page: section masthead (
--accentlabel-caps + Newsreader title) + lead featured + feed. - Article: centered 42rem column; hero plate full-bleed to column edge; pull quotes and photo strips within measure; sticky masthead.
- Nav: desktop/tablet persistent top ribbon with hover dropdowns per topic (2–3 active stories + "All X →"); mobile ≤640 fixed bottom nav (Edition / Sections / Reader / Saved) where Sections opens a full-screen drawer (
<details>-based, no JS). - Responsive breakpoints: ≥1024px 12-col grid / lead+rail; 641–1023px single-column, 42rem, ribbon scrolls, topics 2-col; ≤640px single column, topics 1-col, bottom nav replaces ribbon.
Reference implementation: prototype/ (index.html, article.html, assets/kontra.css).
Media (implementation note)
- Images are git files beside their article:
content/subjects/<s>/<slug>/<file>. Reference via{{media:<slug>/<file>}}(front-matterimage:MUST be quoted —image: "{{media:slug/file.jpg}}"). The app serves/media/<path>by searching article folders (safe-path guarded). No S3/object store (Garage dropped 2026-09-10). - Hero image: grayscale plate per §Hero plate; leave
image: ""for text-only pieces.
Token wiring (for the theme)
- Implement as CSS custom properties on
:root(the design-token layer). - Subject accent overrides: each subject sets
--accent-derived token(s) via a data attribute / config (per plan:subjects/<x>/_subject.yaml→ design tokens, admin-editable values, not code).
Source: Stitch panel "The Gazette — Tides of the Outer Reach" (design.png), export Image 2.html, Image 3.markdown.