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:
co-authored by
Claude Opus 5
parent
fce89d46eb
commit
ca1c2524e1
+123
-24
@@ -364,6 +364,32 @@ Then invalidate `/*`.
|
||||
|
||||
## Cutover checklist — D11 is a single shot, so run all of it
|
||||
|
||||
**Cutover prep — deferred maintenance, done BEFORE the checklist below**
|
||||
|
||||
This group exists because deferring a thing and forgetting it look identical
|
||||
three weeks later. Each item carries the date it was deferred and the reason, so
|
||||
the decision is re-readable rather than re-litigated.
|
||||
|
||||
- [ ] ⚠️ **TWO DEPENDENCY MAJORS ARE ONE BEHIND, DEFERRED 2026-09-01 BY RULING.**
|
||||
`@astrojs/mdx` **^7.0.8 → 8.0.0** and `typescript` **^6.0.3 → 7.0.2**.
|
||||
Pouya's reasoning: *"npm audit is clean and majors mid-walkthrough add churn
|
||||
without user value."* `npm audit` reports **0 vulnerabilities**
|
||||
`[verified 2026-09-01]`, so this is a churn decision and not a security one —
|
||||
and it would become a security decision the moment that stops being true.
|
||||
**Take both majors here, before cutover, and read the changelogs rather than
|
||||
the version numbers**: an MDX major can change how `docs/03`'s copy renders,
|
||||
and a TypeScript major can change what `astro check` accepts, which is a
|
||||
gate on both deploy paths. **`AGENTS.md` R11 keeps firing at every phase
|
||||
boundary as designed** — this item is the deferral, not a replacement for the
|
||||
reminder, and R11 is what will raise the next pin that drifts.
|
||||
**The sweep behind this item, `npm view <pkg> version` across all 19 pins
|
||||
`[verified 2026-09-01]`:** those two are the only majors behind. Four are a
|
||||
minor or patch behind and are already satisfied by their own carets, so they
|
||||
need no edit — `astro` 7.2.9 → **7.2.10**, `@astrojs/sitemap` 3.7.3 → 3.7.4,
|
||||
`globals` 17.11.0 → 17.12.0, `typescript-eslint` 8.68.0 → 8.69.0. The
|
||||
remaining 13 are current. Re-run the sweep here rather than trusting this
|
||||
list: it is dated for that reason
|
||||
|
||||
**Content and compliance**
|
||||
|
||||
> ⚠️ **THE FIRST TWO ITEMS ARE THE PROJECT'S ONLY FULL CLAIMS PASS — D20, Pouya,
|
||||
@@ -425,6 +451,15 @@ Then invalidate `/*`.
|
||||
- [ ] `/fees/` carries the rates confirmed in D14 and `docs/07-fees.md`, or the page does not ship. **And the reservation sentence sits adjacent to the overtime row** — Q59, ruled 2026-08-31: a reader who takes the $500 and skips *"a full day reserves the day; half-day overtime is subject to availability"* has read a different offer, and the arithmetic then makes the full-day rate look strictly worse
|
||||
- [ ] Privacy policy matches the backend as actually built. **Three of its statements are derived and cannot drift** — the collected-data list from `INTAKE_FIELDS`, the retention period from the handler's own figure, the analytics paragraph from `ANALYTICS.installed`. **If analytics are installed, that flag flips and the policy's last-updated date moves on the same build**; a policy naming a processor that processes nothing is a false disclosure
|
||||
- [ ] **`/insights/` — check which state it is in.** While no article is published the page emits `noindex` (derived from the collection) and `SiteHeader` keeps Insights out of the primary nav until **two** are live. Both clear themselves on publication. D9 means the flip is Pouya's: `src/content.config.ts` refuses `draft: false` without `reviewedByPouya: true`
|
||||
- [ ] ⚠️ **AND PUBLISHING THE SECOND ARTICLE IS GATED — `AGENTS.md` R20, ruled
|
||||
2026-09-01.** The flip that makes `/insights/` indexable is the same flip that
|
||||
adds the **seventh nav item**, and with seven items under fallback font
|
||||
metrics the masthead measures 141 px across 1056–1091 px: a 60 px layout shift
|
||||
on every page and 44 px of `#main` behind the sticky header after the skip
|
||||
link, both at the **default** text size. **No seventh nav item ships until
|
||||
that is fixed**, so the fix is a prerequisite of article #2 — not a follow-up
|
||||
to it. The measurements and the two candidate fixes are on the
|
||||
seventh-nav-item item under **Technical** below
|
||||
- [ ] **The five drafted articles are `draft: true` and therefore invisible to `check:claims`**, which reads `dist/`. They were checked once, on 2026-08-31, by temporarily publishing all five and running it — clean on 27 pages. **Re-run it that way before any of them publishes**, because a draft that changes in between is unchecked
|
||||
|
||||
**Technical**
|
||||
@@ -560,29 +595,77 @@ Then invalidate `/*`.
|
||||
roots 9–15 (70), roots 16–32 (300), the band seam (198), both thresholds
|
||||
(144) and all five default-font-size presets (50). Both findings by
|
||||
`adversarial-reviewer`; `docs/02` §Reflow carries all of it
|
||||
- [ ] ⚠️ **TWO REFLOW RESIDUALS SURVIVE, BOTH UNDER CHROME'S MINIMUM-FONT-SIZE
|
||||
SETTING ONLY, AND BOTH NEED A RULING RATHER THAN A RE-MEASUREMENT.**
|
||||
*(a) The footer, and it is OUT OF the scope Pouya set for the header step.*
|
||||
Document overflow of **14 px at 320, 38 px at 1024, 30 px at 1056 and 19 px
|
||||
at 1100 CSS px**, on all 22 pages, 0 from 1200 px up. Cause:
|
||||
`info@smlcompany.ca` has no break opportunity and needs 310 px inside a
|
||||
224–243 px footer-contact column; at 320 px the `.footer-col` box itself is
|
||||
310 px in a 272 px content area. **Pre-existing: the footer's OWN overflow is
|
||||
byte-identical before and after** (`div.footer-grid` 78 px at 1056, 67 px at
|
||||
1100). The 1056/1100 *document* figures did change, 414 → 30 and 370 → 19,
|
||||
because the header stopped contributing its own — a document figure and a
|
||||
footer contribution are different measurements.
|
||||
*(b) The skip link, and it CANNOT be fixed in CSS.* The header stays sticky
|
||||
at **164.58–270.56 px** under that setting, so "Skip to content" lands with
|
||||
**68–174 px of `#main` behind the header** on 22 of 22 pages from 1056 px
|
||||
up — it was 10–26 px before, so the header fix widened it, deliberately, to
|
||||
buy the removal of 830 px of horizontal overflow with four nav items and the
|
||||
CTA unreachable. **Nothing in CSS can detect that mechanism**: media queries,
|
||||
container queries AND length units all keep resolving `rem`/`em` at 16 px
|
||||
while `getComputedStyle` reports 32 px (measured; `docs/02` §Reflow). The
|
||||
remaining candidates are a fitted constant tied to the nav item count, or a
|
||||
behaviour change at normal settings. **Ticked by Pouya fixing (a) and ruling
|
||||
on (b) — not by re-measuring with a method that reports zero**
|
||||
- [x] ✅ **THE FOOTER REFLOW RESIDUAL IS FIXED, 2026-09-01.** Document overflow of
|
||||
**14 px at 320, 38 px at 1024, 30 px at 1056 and 19 px at 1100 CSS px** on all
|
||||
22 pages under Chrome's minimum-font-size setting, 0 from 1200 px up. One
|
||||
cause at all four: `info@smlcompany.ca` has no break opportunity, so its
|
||||
**min-content width is 310 px**. One declaration closes it —
|
||||
`.footer-contact a[href^='mailto:'] { overflow-wrap: anywhere }` — measured
|
||||
**88 of 352 → 0 of 352**, the other three enlargement methods unchanged at 0
|
||||
of 352, and the normal-settings identity check at **0 differences on 352
|
||||
page-widths across 8 metrics**. It also closed **57 cases of the link
|
||||
overrunning its own box** at root style 26–32 px that the document-level
|
||||
table reports as clean. ⚠️ **The earlier note here said the 320 px half "is a
|
||||
column-sizing question and is not the same fix" — that was wrong**; the
|
||||
column sizing at 320 px *is* that same 310 px min-content, arriving through
|
||||
`.footer-grid`'s `auto` track instead of through text spilling out of a
|
||||
`minmax(0, 1fr)` one. `docs/02` §Reflow carries both mechanisms, the negative
|
||||
control proving `break-word` would not have worked, and the candidates
|
||||
declined as broader than the cause
|
||||
|
||||
- [ ] 🛑 **THE MINIMUM-FONT-SIZE STICKY RESIDUAL — REOPENED THE SAME DAY IT WAS
|
||||
TICKED, AND IT IS A WCAG 2.2 SC 2.4.11 (AA) FAILURE RATHER THAN THE
|
||||
SKIP-LINK INCONVENIENCE IT WAS ACCEPTED AS. NEEDS A FRESH RULING.**
|
||||
It was ruled accepted on 2026-09-01 on the basis *"you proved no CSS
|
||||
mechanism can see minimum-font-size; the only fix is JS and zero-JS is a
|
||||
founding decision"*, and this checklist item was ticked accordingly. Both
|
||||
supporting facts are wrong, and `adversarial-reviewer` found it the same day.
|
||||
**(1) The premise.** The proof covered `rem`/`em` and queries written in them.
|
||||
The font-metric units **`ch`, `ex`, `cap`, `lh`, `rlh`** read the *used* font
|
||||
size and double under the setting — in property values, in `@media` **and** in
|
||||
`@container`. A pure-CSS detector exists, so "the only fix is JS" does not
|
||||
hold. **(2) The cost.** Not a short skip-link landing but **ordinary keyboard
|
||||
focus landing entirely behind an opaque sticky header**: a Shift+Tab walk over
|
||||
6 pages × 5 widths ≥ 1056 px gives **290 entirely-hidden focus stops of 1,455**
|
||||
under the setting — **254 in the footer and 36 inside `#main`** — against **0**
|
||||
at the default size. Hit-tested with `elementFromPoint`, not inferred from
|
||||
geometry: geometry alone said 43 at the default size and all 43 were the skip
|
||||
link, which is stacked *above* the header on purpose. **(3) And the header fix
|
||||
created it:** a build of `fce89d4~1` measures **0** under the same setting,
|
||||
because `flex-wrap: nowrap` kept the masthead one row and short. So the trade
|
||||
was **830 px of horizontal overflow (SC 1.4.10) for 290 obscured focus stops
|
||||
(SC 2.4.11)** — both Level AA, and the asymmetry that was the whole argument
|
||||
does not exist. **A candidate fix is measured but deliberately not
|
||||
implemented:** a third gate term in the shipping idiom, `calc((15px - 1ch) *
|
||||
100000)`, un-sticks the header under the setting and leaves
|
||||
`inset-block-start: 0px` at the default — but 15 px is fitted to Geist's `ch`
|
||||
and needs checking under fallback metrics and Chrome's other font presets.
|
||||
**This item is ticked only by a ruling from Pouya, not by a re-measurement.**
|
||||
The decision is `AGENTS.md` **Q61**; `docs/02` §Reflow carries the measurements
|
||||
|
||||
- [ ] ⚠️ **A FOOTER NAV LABEL OVERRUNS ITS COLUMN BY 24 px AT 640 px UNDER
|
||||
MINIMUM FONT SIZE, WITH 7.7 px OF CLEARANCE TO THE NEXT COLUMN.** No document
|
||||
overflow at any width, so it fails no success criterion and is cosmetic
|
||||
today — filed because **7.7 px is one label rename away from two columns
|
||||
colliding**, and nothing in the build measures it. `.footer-col a`
|
||||
"Construction & Infrastructure" overruns its 176 px box by **24 px** at
|
||||
640 px and by 4 px at 700 px (clearance 27.7 px); "Shareholder & Family
|
||||
Business" by 2 px at 640 px, and — at widths that 12-column grid steps over —
|
||||
**17 px at 660 px and 11 px at 680 px**. Clean at every other width sampled,
|
||||
including 768 and 834 px; `minimumFontSize=32`, 22 pages × 12 widths = 264
|
||||
rows. **A fourth case of the same family: `nav.crumbs > ol` on
|
||||
`/practice/construction/` @320 px overruns its own 272 px box by 7 px**, also
|
||||
with zero document overflow. **Rule on both together** — if
|
||||
`.footer-col a { overflow-wrap: anywhere }` is ruled in, the same call covers
|
||||
`.crumbs`; if it is declined, decline both and the record is complete.
|
||||
**`.footer-col a { overflow-wrap: anywhere }` is measured to close it and to
|
||||
be inert at normal settings**, and is not applied because it changes how six
|
||||
practice-area names break on a marketing surface under enlargement — a
|
||||
copy-adjacent call, not a technical one. ⚠️ **And it falsified the reason
|
||||
given for scoping the email fix to the address** (*"every other footer string
|
||||
has spaces"*): min-content is set by the longest **word**, not by whether a
|
||||
space exists. Corrected in `docs/02` §Reflow. Raised by
|
||||
`adversarial-reviewer`, 2026-09-01
|
||||
|
||||
- [ ] ⚠️ **THE SEVENTH NAV ITEM PLUS FALLBACK FONT METRICS — A LAYOUT SHIFT *AND*
|
||||
A SKIP-LINK FAILURE, AT THE DEFAULT TEXT SIZE, ARMING ITSELF WHEN THE SECOND
|
||||
@@ -602,7 +685,23 @@ Then invalidate `/*`.
|
||||
because both are outside "the header and its consumers": raise the desktop
|
||||
breakpoint past 1091 px, which changes the normal-settings layout in that
|
||||
band, or give Geist a metric-matched `size-adjust` fallback. Raised by
|
||||
`adversarial-reviewer`, 2026-09-01; `docs/02` §Reflow carries the measurements
|
||||
`adversarial-reviewer`, 2026-09-01; `docs/02` §Reflow carries the measurements.
|
||||
|
||||
⚠️ **THIS IS NOT A CUTOVER BLOCKER AND IT IS NOT TICKABLE HERE — IT IS A HARD
|
||||
PRE-PUBLICATION GATE. Pouya's ruling, 2026-09-01: no seventh nav item ships
|
||||
until the fallback-metrics defect is fixed**, which makes fixing it a
|
||||
**prerequisite of publishing the second Insights article**, since that is what
|
||||
adds the item. It is left unchecked on purpose: a checklist that fires once, at
|
||||
cutover, cannot discharge a defect that arms itself later on an editorial
|
||||
decision. ⚠️ **AND THE GATE IS A BUILD FAILURE, NOT THIS CHECKLIST AND NOT A
|
||||
COMMENT.** `SiteHeader.astro` throws when `published.length >= 2`, with the
|
||||
measurements and the instruction in the message, so it fires on both deploy
|
||||
paths on the machine of whoever publishes. **Proven rather than assumed:** two
|
||||
articles were temporarily flipped to `draft: false` and `npm run build` exited
|
||||
**1** naming R20; the files were restored and the restoration verified by
|
||||
`git diff --exit-code` and an unchanged `dist` digest. It was first written as
|
||||
three prose cross-references and **did not gate** — the build and all five
|
||||
checks passed while both defects shipped. **Owner: `AGENTS.md` R20**
|
||||
|
||||
**Infrastructure**
|
||||
- [ ] S3 versioning enabled
|
||||
|
||||
Reference in New Issue
Block a user