fix: header reflows under enlarged text; reopen the step-1 nowrap decision

The step-1 header decision is formally reopened (AGENTS.md (ak)): its record
attributed the residual to the wrong cause and read a measured 944px functional
failure as a robustness margin.

Mechanism — wrapping, plus a gated sticky offset:
- `flex-wrap: nowrap` removed from `.header-inner` (measured necessary AND
  sufficient) and from `.nav-list` (measured inert; removed so the prohibition
  is not contradicted by a `nowrap` in the same file), with a dead `flex: none`.
- `inset-block-start` becomes a two-band, two-term saturating clamp() so the
  header is sticky only while the masthead is one row. A media query cannot
  express this: its `rem` resolves against the browser DEFAULT font size, a
  property's against the root element. The second term catches a root BELOW the
  default, where the 80rem content cap shrinks faster than the header's px
  minimums; without it 65px of `#main` sat behind the header at 9px.
- Wrapping is the only mechanism that reflows under all THREE enlargement paths,
  because Chrome's minimum-font-size setting is invisible to @media, to
  @container and to every length unit.

Measured, 22 pages x 16 widths = 352 page-widths per method:
  root-style 32px        175/352 -> 0/352   (1280px: 944px overflow -> 0)
  minimum-font-size 32   219/352 -> 88/352  (residual is the footer email)
  default-font-size 32     0/352 -> 0/352
  default (root 16)        0/352 -> 0/352
Nav items and CTA on-screen in 1408/1408. A further 762 points across roots
9-32, both thresholds, the band seam and all five Chrome presets: 0 failing.

Normal-settings identity: 0 differences on 352 page-widths across six metrics,
with six nav items and with a seventh injected. Header 81.00px at all eight
widths >= 1056, CTA gap 0.00px. Lighthouse: 22 pages, no category below 95,
CLS 0.000 on every page.

--header-h is reworded as a FLOOR, not a constant; value unchanged.

Also in this step, per ruling:
- /bio/ print `font-weight` frozen at 400 — the circulated PDF's typography
  changes only when its content is deliberately revised, never as a side effect
  of a screen refactor. Declaration byte-identical; the constraint is recorded.
- CLAUDE.md: the two-simulation rule for enlarged text, the zsh
  no-word-splitting rule, the third (minimum-font-size) mechanism, and
  "state the grid with the count".

Two rounds of adversarial-reviewer, eleven findings, all resolved; round 2's
blocking finding was a defect in round 1's own fix. Two suggested fixes declined
with reasons in (ak). claims-auditor deliberately not run — D20.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Md3GndFqWPzK78xAoebsg5
This commit is contained in:
Pouya Lajevardi
2026-09-01 12:34:50 -04:00
co-authored by Claude Opus 5
parent 0f7595b602
commit fce89d46eb
8 changed files with 731 additions and 125 deletions
+5 -1
View File
@@ -121,7 +121,11 @@ html {
/* The header is sticky from 66rem up, and `scroll-padding-top` has to clear it
or "Skip to content" drops the reader behind it — the one control that exists
specifically for keyboard users, landing them on content they cannot see.
--header-h is defined in tokens.css beside the value it has to match. */
`--header-h` is defined in tokens.css beside the value it has to match, and it
is a FLOOR — above the default text size the masthead reflows and is taller, and
`SiteHeader` gates stickiness so the offset is generous rather than short.
⚠️ TWO SETTINGS DEFEAT THAT GATE and leave this offset short; `docs/02` §Reflow
names them and shows why no CSS can detect either. */
@media (min-width: 66rem) {
html {
scroll-padding-top: calc(var(--header-h) + var(--space-4));
+14 -9
View File
@@ -137,15 +137,20 @@
/* --- Layout ------------------------------------------------------------ */
/* Sticky-header height at >= 66rem, where the header IS sticky. global.css
drives `scroll-padding-top` off this, so the skip link does not drop the
reader behind the header. If SiteHeader's padding or nav sizing changes,
re-measure and change this with it — one fact living in two files.
[measured 2026-08-26 — headless Chrome at 1024/1100/1280/1440px, with six
nav items and with a seventh injected. 81px at every one: 32 padding + 48
reserved brand block + the 1px bottom border, which is easy to forget and
is why this is measured rather than added up. The brand reserves 48px so
the height does not change when the tagline appears at 76rem] */
/* ⚠️ A FLOOR, NOT A CONSTANT: the sticky header's height AT THE DEFAULT TEXT
SIZE. Above the default the masthead reflows and is deliberately taller, which
is why the nav no longer runs off-screen. `global.css` drives
`scroll-padding-top` off it and `SiteHeader` gates stickiness so the offset is
generous rather than short — **but not in every case**: `docs/02` §Reflow lists
the two settings where it is still short and why no CSS can see them. If
SiteHeader's padding or nav sizing changes, re-measure and change this with
it — one fact living in two files.
[measured 2026-08-26, re-measured 2026-09-01 — headless Chrome, six nav items
and a seventh injected. 81.00px at all EIGHT widths from 1056 to 1920px
(1056/1100/1216/1240/1280/1440/1600/1920): 32 padding + 48 reserved brand
block + the 1px bottom border, which is easy to forget and is why this is
measured rather than added up. The brand reserves 48px so the height does not
change when the tagline appears at 76rem] */
--header-h: 5.0625rem; /* 81 — measured, not chosen */
--width-content: 80rem; /* 1280 */