fix: footer email reflow to zero under all four methods; reopen the skip-link residual as Q61

The footer mailto was the last recorded overflow: `info@smlcompany.ca` demanded
310px of min-content in a 224-243px column. One declaration —
`overflow-wrap: anywhere` on `.footer-contact a[href^='mailto:']`. `anywhere`
and not `break-word`, established with a negative control rather than from the
rule: only `anywhere` reduces min-content, and `break-word` injected in its
place failed the same 88 rows as the unfixed baseline.

Minimum-font-size 32 goes 88/352 -> 0/352. All four methods now read 0 of 352
(22 pages x 16 widths). Normal-settings identity: 0 differences across 8
metrics, with a positive control proving the comparison can detect one. It also
closed 57 element-level cases the page-level table reports as clean, hidden
inside `.wrap`'s 96px gutter.

The item-2 ruling is NOT applied, and this is the deviation to read first. The
acceptance rested on "no CSS mechanism can see minimum-font-size", which is
false: the font-metric units — `ch`, `ex`, `cap`, `lh`, `rlh` — read the used
font size and double, in property values, in `@media` and in `@container`. Only
`rem`, `em`, `ic` and `px` are blind. And the cost is not a convenience loss:
keyboard focus lands entirely behind the opaque header on 290 of 1,455 stops,
36 of them inside `#main`, which is WCAG 2.2 SC 2.4.11 at AA — the same level as
the 1.4.10 failure it was traded against. A build of fce89d4~1 measures 0, so
the header fix created it. Opened as Q61 with a verified candidate; docs/06
restored to unticked.

R20's gate is now a build failure rather than three prose cross-references,
which demonstrably did not gate it: with two articles published the build and
all five checks passed while both header defects shipped. SiteHeader throws.

R11's two majors (@astrojs/mdx 7->8, typescript 6->7) move to a new cutover-prep
group in docs/06 with the 19-pin currency sweep.

Two review rounds, eight findings, all resolved; four of round 2's five were
defects in round 1's own fixes. Stopped at two per D19.

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 14:51:37 -04:00
co-authored by Claude Opus 5
parent fce89d46eb
commit ca1c2524e1
8 changed files with 960 additions and 98 deletions
+6
View File
@@ -244,6 +244,12 @@ const aboutLinks = [
color: var(--text-inverse-2);
text-decoration: underline;
}
/* `anywhere`, NOT `break-word` — only `anywhere` reduces min-content size, which
is the defect: the address has no break opportunity. `docs/02` §Reflow. */
.footer-contact a[href^='mailto:'] {
overflow-wrap: anywhere;
}
/* Not a link, so no target floor — but it shares a column with links and
should sit on the same rhythm. */
.footer-meta {
+17
View File
@@ -23,7 +23,24 @@ import InfinityMark from './InfinityMark.astro';
import Button from './Button.astro';
const published = await getCollection('insights', ({ data }) => !data.draft);
/* ⚠️ GATED BY A BUILD FAILURE, NOT BY THIS COMMENT — `AGENTS.md` R20 and Q61.
The seventh nav item arms two measured header defects under fallback font
metrics. Prose cross-references did not gate it: every check passed while it
fired. Delete the throw as part of the fix, not before it. */
const showInsights = published.length >= 2;
if (showInsights) {
throw new Error(
'AGENTS.md R20 — the seventh nav item is gated and this build would ship it.\n' +
`A second Insights article is published (${published.length} live), which puts ` +
'Insights in the primary nav. With seven items under FALLBACK font metrics — ' +
'the font-display: swap window, at the default text size, no reader setting ' +
'involved — the masthead measures 141px across 1056-1091px instead of 81px: a ' +
'60px shift on every page against the CLS < 0.05 budget, and 44px of #main ' +
'behind the sticky header after "Skip to content".\n' +
'Fix that first (docs/02 §Reflow lists the two candidate fixes), then delete ' +
'this guard. Do not work around it by unpublishing the article.',
);
}
const items = PRIMARY_NAV.filter(
(item) => item.href !== '/insights/' || showInsights,