Skip to content

Type scale (rem) + serif heading hierarchy + living token spec#13104

Draft
lokesh wants to merge 4 commits into
internetarchive:masterfrom
lokesh:design/feat/type-scale
Draft

Type scale (rem) + serif heading hierarchy + living token spec#13104
lokesh wants to merge 4 commits into
internetarchive:masterfrom
lokesh:design/feat/type-scale

Conversation

@lokesh

@lokesh lokesh commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator

Type scale in rem, heading hierarchy, serif headings, and a living token spec

Third PR of the visual modernization series. Stacked on #13102 (color tokens) + #13103 (web fonts) — review the last commit; the earlier ones belong to those PRs and disappear as they merge.

What changes

  • Type scale px → rem (font-families.css): all size tokens keep their computed defaults (32px → 2rem etc.) but now honor the user's browser font-size preference — an accessibility win. Deletes --font-size-display-large/-medium (zero consumers), adds --font-size-body-small (13px, absorbing the 13px/0.8em literal cluster in later PRs) and --font-weight-{normal,medium,semibold,bold}. No fluid/clamp type, per the browser floor and the snappy brief.
  • The serif-headings moment: --font-family-heading flips to Literata. base/common.css splits headings — h1–h3 serif at weight 500 with text-wrap: balance, h4–h6 sans (Inter) at 600 — and drops today's "40%-grey-all-600" for a single ink color (--color-text); hierarchy now comes from size and the serif/sans split, not from greying out.
  • Links--color-link / -hover / -visited; hr--color-border-subtle.
  • base/headings.css pruned: dead rules deleted with grep evidence (h1.publisher, h2.authorEdition, h2.publisher, h3.Question, h4.publisher/observer-count, .titleSmall, and the forced-serif !important h5 — zero <h5> in any template/JS/Vue); remaining colors re-pointed at semantic tokens; h4.facetHead keeps its uppercase treatment.
  • Ratchet: stylelint overrides adds font-size to declaration-strict-value for the migrated files only (base/common.css, base/headings.css). Each later phase adds its globs — literals can't creep back into migrated files, without firing ~279 violations repo-wide.
  • Living spec: /developers/design gets a Design Tokens + Typography reference (design/tokens.html) — primitive ramps, semantic-token table, and a full type specimen, all resolved live from the loaded tokens.css via getComputedStyle, so the spec can never drift from shipped values. Reviewers can diff each subsequent phase against this page.

Dropped from the original plan

The design.py:82 except OSError, ValueError: "Python-2 SyntaxError" turned out to be valid PEP 758 syntax on the repo's Python 3.14 (and ruff-format actively enforces the paren-free form). /developers/design imports fine — no fix needed.

Verified

  • npm run lint (incl. the new ratchet) clean; npx jest 495/495 (incl. token-contrast test from Color tokens: warm neutral ramps, semantic layer, deprecated aliases #13102).
  • Playwright e2e: 15 passed; the 3 failures (work/edition/author console-error assertions) also fail identically on clean upstream/master — pre-existing dev-env issue (Cannot read properties of undefined (reading 'initialize')), unrelated to this diff.
  • Visual sweep at 1280/390 of home, search, work, login, and /developers/design.

Screenshots

Living spec — color tokens
Living spec — type type
Work page (before → after this PR) before after
Search search

🤖 Generated with Claude Code

lokesh added 4 commits July 2, 2026 15:01
…ted aliases

- Rewrite static/css/tokens/colors.css into three tiers: primitive ramps
  (warm neutrals, blue, red/green/amber), semantic tokens (--color-*,
  the dark-mode seam), and deprecated aliases that re-point every legacy
  token name so all ~2,100 existing var() consumers shift to the new
  palette with zero edits.
- Brand blues are bit-identical (--blue-500/600 == --primary-blue/--link-blue).
- Add tests/unit/js/token-contrast.test.js asserting the WCAG AA contrast
  matrix over the semantic tokens (runs in npm test).
- Add bundlesize budgets for tokens.css (6KB) and ol-components.css (8KB).
- Update docs/ai/design.md token documentation (fix nonexistent
  tokens/typography.css reference).
- Remove --beige-bright (zero consumers).
- Ship latin-subset variable woff2 fonts (Literata wght 400-700 /
  opsz 12-36, ~55KB; Inter wght 400-700, ~50KB), built with fonttools
  varLib.instancer + pyftsubset (pipeline documented in
  static/fonts/README.md).
- New tokens/font-faces.css: @font-face with font-display: swap, latin
  unicode-range, and metric-adjusted local fallbacks (Georgia/Arial with
  size-adjust/ascent/descent overrides) - measured CLS 0.01 on a
  throttled cold load.
- Preload both fonts in site/head.html (crossorigin, required for font
  preloads; verified single fetch per font).
- font-families.css: primitives now lead with Inter/Literata; all
  semantic tokens reference the primitives instead of verbatim copies
  (fixes --font-family-code Menlo divergence). Headings stay sans for
  now - the serif flip lands with the type-scale PR.
- Fix undefined var(--body-family) in legacy.css (-> --font-family-body).

Non-latin scripts fall back to system stacks via unicode-range; italics
are synthesized.
- font-families.css: size tokens px -> rem (same computed defaults, now
  honoring browser font-size prefs); delete unused
  --font-size-display-large/-medium; add --font-size-body-small (13px)
  and --font-weight-{normal,medium,semibold,bold} tokens; flip
  --font-family-heading to the serif (Literata) for h1-h3.
- base/common.css: one ink color for text and headings (--color-text);
  h1-h3 serif at weight 500 with text-wrap: balance, h4-h6 sans at 600;
  links -> --color-link/-hover/-visited; hr -> --color-border-subtle.
- base/headings.css: prune dead rules (h1.publisher, h2.authorEdition,
  h2.publisher, h3.Question, h4.publisher/observer-count, .titleSmall,
  forced-serif h5 - all grep-verified unused in templates/JS/Vue);
  re-point --brown/--grey/--black at semantic text tokens.
- stylelint: font-size added to declaration-strict-value for migrated
  files only (ratchet grows per phase).
- Fix Python-2 'except OSError, ValueError:' SyntaxError in design.py
  that kept /developers/design from importing.
- /developers/design: new Design Tokens + Typography reference
  (design/tokens.html) - color ramps, semantic table, and type specimen
  resolved live from the loaded tokens.css, so the spec can't drift.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant