Build and deploy / build-and-deploy (push) Failing after 5s
Step 5 ships /practice/ and the six practice-area pages (construction,
technology, energy, insurance, shareholder, cross-border) from one route, and
adds the mechanical §4 gate Pouya ruled for.
check:claims — §4 Forbidden becomes a build error
scripts/check-claims.mjs greps dist/**/*.html for 10 patterns, each carrying
the incident that put it there. It strips <style> and non-JSON-LD <script>
first (a bare sweep for "leading" returned 26 hits, 25 of them
var(--leading-body)), self-tests every pattern against fixtures before
sweeping, and refuses a missing, empty or stale dist/. Wired into /build
Phase 5 and both deploy paths.
Q54 — six conduct undertakings publish, and §4 gains a third class
Conduct undertakings sit apart from credentials and offerings: the gate is
that Pouya said it in terms. The strings live in CONDUCT_UNDERTAKINGS so a
softening is one visible diff. (e) and (f) replace the third-person sentences
already on /arbitration/ rather than joining them.
Q49, Q50 recorded as rulings. §7 records the SES us-east-1 stray identity's
deletion. R11 holds typescript at its current major, with the peer-range
reason recorded.
Three facts corrected, two of them already shipped
- The LAT gloss said mediation "before filing and continuing after filing";
the Tribunal names mediation for "Before you apply" only and its second
sentence is about negotiation. An ellipsis in docs/01 had deleted it.
- "Connection allocation" is not an Ontario term.
- "The 2026 privacy statute" does not exist — Bill C-27 died without royal
assent. Struck from docs/03 rather than corrected in place.
ADR Chambers struck from /arbitration/ and from docs/01 item 3 (Pouya,
2026-08-30): the source establishes what the firm publishes, not that an
outside neutral can be appointed under its rules.
claims-auditor gains a second lens — for every quoted source, whether the
sentence beneath stays inside what the quotation establishes. Four shipped
defects had that shape and none of them is greppable.
CLAUDE.md gains a convention: never truncate the output of a check you intend
to believe. `npm run check | tail -3` returns warnings, hints and a blank line
and drops the errors line; it was reported as passing four times while
astro check was exiting 1 with 10 type errors.
Gates, exit status read directly, not through a pipe:
npm run check exit=0
npm run lint exit=0
npm run build exit=0
npm run check:claims exit=0
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Md3GndFqWPzK78xAoebsg5
76 lines
3.2 KiB
Plaintext
76 lines
3.2 KiB
Plaintext
---
|
|
/**
|
|
* A `<dl>` of term/description pairs on an auto-fitting grid.
|
|
*
|
|
* EXTRACTED AT STEP 4 ON `adversarial-reviewer`'S FINDING, and the finding was
|
|
* that `/mediation/`'s `.formats` and `/arbitration/`'s `.cols` were the same
|
|
* component under two names — identical markup, near-identical CSS, and
|
|
* `.cols` was already serving two different content types on one page.
|
|
* `/practice/*` at step 5 wants it a fourth time. Same argument that extracted
|
|
* `ContactBand`: two call sites, one already divergent, pages to come.
|
|
*
|
|
* `<dl>` RATHER THAN A DIV GRID, for `CredentialRow`'s reason: each pair is a
|
|
* term and its description, so a screen reader gets them as an associated pair
|
|
* rather than as a visual arrangement. Wrapping each `<dt>`/`<dd>` in a `<div>`
|
|
* inside the `<dl>` is valid HTML and is what makes the grid tractable.
|
|
*
|
|
* A `<dt>` IS NOT A HEADING and must not become one. These sit under the
|
|
* section's `<h2>`; promoting them to `<h3>` would be a heading level that adds
|
|
* nothing to the outline, and `docs/02` forbids skipped levels either way.
|
|
*/
|
|
interface Props {
|
|
items: ReadonlyArray<{ name: string; body: string }>;
|
|
/** The grid's per-column floor, passed to `.grid-autofit` as `--grid-min`.
|
|
* The `min(N, 100%)` guard lives there, in one place. */
|
|
minColumn?: string;
|
|
}
|
|
const { items, minColumn = '17rem' } = Astro.props;
|
|
---
|
|
|
|
<dl class="grid-autofit defs" style={`--grid-min: ${minColumn}`}>
|
|
{
|
|
items.map((item) => (
|
|
<div class="def">
|
|
<dt class="def-name">{item.name}</dt>
|
|
<dd class="def-body">{item.body}</dd>
|
|
</div>
|
|
))
|
|
}
|
|
</dl>
|
|
|
|
<style>
|
|
/* Columns and the `min()` guard come from `.grid-autofit` (global.css); this
|
|
sets only the gap. It re-implemented them for one pass — a second copy of
|
|
the guard, inside the extraction made to remove copies of the guard.
|
|
`--grid-min` is passed inline by the caller because a parent cannot style
|
|
this component's root, and a custom property is the one mechanism that
|
|
crosses that boundary. */
|
|
.defs {
|
|
gap: var(--space-7);
|
|
}
|
|
/* ⚠️ `--def-name-fg`, NOT `--text-meta` DIRECTLY. `--text-meta` is `--muted`,
|
|
and `tokens.css` states the constraint on that token in terms: "metadata —
|
|
ON CREAM ONLY (3.07:1 on ink)". `/practice/` is the first page to put this
|
|
component on an inverse ground, and it shipped these labels at **3.07:1 at
|
|
12px** against a 4.5:1 AA floor — measured three ways by
|
|
`adversarial-reviewer` (token arithmetic, `getComputedStyle` against the
|
|
served build, and a screenshot), all agreeing.
|
|
|
|
A custom property is the fix rather than a `:global()` rule because it is
|
|
the one mechanism that crosses Astro's component-scope boundary — the same
|
|
route `Pill` already uses, and `global.css` sets this alongside `--pill-fg`
|
|
on `.section-inverse, .section-accent`. The fallback keeps cream correct. */
|
|
.def-name {
|
|
font-family: var(--font-mono);
|
|
font-size: var(--text-xs);
|
|
font-weight: var(--weight-medium);
|
|
letter-spacing: var(--tracking-wide);
|
|
text-transform: uppercase;
|
|
color: var(--def-name-fg, var(--text-meta));
|
|
}
|
|
.def-body {
|
|
margin-block-start: var(--space-2);
|
|
line-height: var(--leading-body);
|
|
}
|
|
</style>
|