feat: production run — Q61 ramp, /404/, CloudFront router, cutover runbook
Build and deploy / build-and-deploy (push) Failing after 4s

Five items of Pouya's production run, 2026-09-01.

Q61 — scroll-padding-top becomes a max() ramp on `10lh - 83px`, with the
plain calc() first as the fallback for engines without `lh`. Hidden focus
stops under minimumFontSize=32: 290 of 1,455 -> 0, control build still
290. Default settings byte-identical (0 differences over 352 page-widths x
17 fields). The 12 residual cells at minimumFontSize=16/20 are pre-existing
and unchanged-or-better; reported, not widened, per instruction.

Intake backend + CloudFront — docs/09-cutover-runbook.md is the
copy-paste sequence for admin execution: every command followed by its
verification and expected output, rollback per part, and Part 10 is Q60's
TTL test. infra/cloudfront/router.js is the trailing-slash function
(30-case suite; 8 fail against the pre-review version, incl. a
protocol-relative open redirect). infra/cloudfront/configure.mjs is
dry-run-by-default and idempotent. scripts/intake-env.mjs emits the six
Lambda env vars from src/data/site.ts.

Four launch blockers found by reading the running system:
  - handler.mjs wrote pk/sk; the live table's key is submissionId with no
    sort key, so every submission would have failed validation silently
  - the Lambda invoke permission is scoped to the old route path
  - 22 of 23 pages 403 without the router function
  - there was no 404 page; src/pages/404.astro adds it

Claims audit (D20 cutover pass) — five gloss over-reaches corrected on
/practice/energy/, /practice/insurance/ (x2), /practice/technology/ and
/med-arb/. Three findings left open for Pouya: Q62, the /med-arb/ gloss,
and Q60.

Q62 — one frozen-tripwire pattern added under the freeze's own breach
exception, with a probe and four negative fixtures. check:claims exits 1
until the false /legal/privacy/ sentence is corrected, so both deploy
paths are blocked by a mechanism rather than by memory.

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-02 06:52:20 -04:00
co-authored by Claude Opus 5
parent ca1c2524e1
commit bd282aa47d
30 changed files with 3256 additions and 143 deletions
+24 -9
View File
@@ -121,18 +121,33 @@ 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, 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 CASES DEFEAT THAT GATE and leave this offset short — one a reader
setting, one the webfont swap window. Under Chrome's minimum font size the
shortfall is an OPEN WCAG 2.2 SC 2.4.11 (AA) failure, not an accepted one:
`AGENTS.md` Q61. **CSS CAN detect that setting** — the font-metric units
(`ch`, `ex`, `cap`, `lh`) respond to it where `rem`/`em` do not — so a fix is
possible here and is awaiting a ruling. Measurements: `docs/02` §Reflow. */
`--header-h` is a FLOOR at the default text size, so the `max()` ramp is what
carries the cases where the masthead reflows taller (`AGENTS.md` Q61).
⚠️ THREE THINGS HERE ARE LOAD-BEARING AND EACH BREAKS SILENTLY.
1. `1lh` and not `1rem`/`1em`. Chrome's minimum-font-size setting enlarges
text while `rem` keeps resolving at 16px; the font-metric units read the
USED size and track it. `rem` here measures 97px against a 270.56px
header — no error, no warning, focus behind the header.
2. The plain declaration comes FIRST and is not redundant. An engine without
`lh` discards the whole `max()` as invalid, and the property then falls
back to `--space-4` = 16px, which is worse than no fix at all.
3. `1lh` on `<html>` is immune to the `font-display: swap` window ONLY
because `<html>` keeps the UA font family — `--font-sans` is set on
`body`. Moving the family up to `html` makes this offset depend on whether
a webfont has arrived. Do not.
One case is still short: fallback metrics with a seventh nav item, gated by a
build failure in `SiteHeader` (`AGENTS.md` R20). `docs/02` §Reflow has the
measurements. */
@media (min-width: 66rem) {
html {
scroll-padding-top: calc(var(--header-h) + var(--space-4));
scroll-padding-top: max(
calc(var(--header-h) + var(--space-4)),
calc(10lh - 83px)
);
}
}
+12 -5
View File
@@ -140,11 +140,18 @@
/* ⚠️ 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 cases where it is still short, one of them an OPEN SC 2.4.11 (AA)
failure (`AGENTS.md` Q61). If SiteHeader's padding or nav sizing changes,
re-measure and change this with it — one fact living in two files.
`scroll-padding-top` off it as the LOWER BOUND of a `max()` ramp — the ramp,
not this token, is what covers the settings where the masthead reflows taller
(`AGENTS.md` Q61, fixed 2026-09-01). One case remains short and is gated by a
build failure rather than by this value: `AGENTS.md` R20. If SiteHeader's
padding or nav sizing changes, re-measure and change this with it — one fact
living in two files.
⚠️ **AND THERE IS A THIRD FILE, WHICH IS THE ONE A READER MISSES.**
`global.css`'s ramp is `max(calc(var(--header-h) + var(--space-4)),
calc(10lh - 83px))`, and that `83px` is fitted so the second term equals the
first at the default text size — 97 px both ways, measured. **Change this
token and the 83 px moves with it**, or the ramp stops being a no-op at
normal settings and starts changing the shipped rendering.
[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