feat: build step 2 — the home page; close Q35, Q37, Q39; Q39's answer corrected the register

Pouya's rulings and the page are one commit, not two, because they are not
separable: Q37 changed the credential label the page renders, Q39 scoped the
arbitration copy, and Q35 gave Med-Arb the row that lets the footer link stand.
Splitting them would produce a commit where the register says one thing and the
page says another.

RULINGS

Q39 — ANSWERED, and my assertion was FALSE as a universal. Pouya checked
rather than defended. Family arbitration in Ontario is gated: prescribed
training, 14h on screening for domestic violence and power imbalances, 30h of
Ontario family law for arbitrators outside the bar, 10h ongoing per two years.
claims-auditor produced that counter-example from inside the repo on 2026-08-26
and it was right. The source is now IN the repo per R14 —
docs/reference/ontario-family-arbitration-training.md, retrieved with its
provenance — and §4 states which half it establishes: the family gate directly,
the commercial half only by absence. So "commercial arbitration in Ontario
requires no licence and no designation" is recorded as Pouya's stated position,
unstamped. What disposes of the question is the scope exclusion: he does not do
family arbitration, so it is NOT OFFERED and the gate never bears on the
practice.

The false universal survived in three more live places, found by grep, not
recall: §4's NOT-NEGOTIABLE boundary bullet (the boundary paragraph breaching
its own boundary), §9's Q33 closure row, and a comment in SiteHeader.astro.

Q35 — ANSWERED, all four items, and the answer supplied a gate that was
missing. Med-Arb gets an Offerings row and stays in the footer sitemap. The six
subject-matter labels pass test 1. §4 gains "Subject-matter areas — the
publication gate": competence to accept an appointment, AND a page that frames
it as positioning without claiming history. Nothing in the nav or footer is
unrowed any more.

Q37 — ANSWERED. "Law and engineering" becomes "Legal training and engineering
practice". A degree is not a practice; the parallel was doing the implying.

Q38/R13 — the committed SVG does not close it; the walk-back went too far. It
renders faithfully BECAUSE it is the raster. R13 stays open.

R1 — surfaced and acknowledged; the interim licensure framing is now carried by
a shipped page rather than a spec, which raises the stakes.

BUILD STEP 2

Seven of docs/01's eight home sections, six new components, zero JavaScript.
Section 7 (Latest insights) ships at step 7 with the collection it lists —
recorded in docs/01 and in the page, not just here. Four credential slots, not
three: §4's paired-disclosure condition requires the Q.Arb stage on any page
that offers arbitration. No booking link (R6). The masthead tagline is
suppressed on / (it duplicated the hero eyebrow). The step-1 proof sheet is
deleted, and five live references to it were found by grep.

WHAT THE REVIEWS FOUND — 24 findings across the two passes

claims-auditor FAILED it on ten, every one implication or scope rather than
fabrication, which is where D13 says the risk lives. The four that mattered:
"I mediate and arbitrate" asserted a track record §4 does not hold for
arbitration; the JSON-LD asserted arbitration twice and stated the stage
nowhere (a crawler-only claim is still a claim); "at one published rate with
preparation time included" misdescribed money against docs/07's two day rates
and capped prep allowance; and "Law and engineering are not blended here" was
Q37's struck parallel relocated into prose one day after Pouya struck it.
It also found the Canadian Tax Foundation missing from §9 Q8 — a stale second
copy of a fact that would have bitten at step 3.

adversarial-reviewer found fourteen, three blocking. The first was
class="section-head" on <SectionHeading> never matching — the parent-cannot-
style-a-child defect for the FOURTH time, written into a diff where I had just
added fresh warnings about it to two other components. Measured: 0px margin,
0px gap, headings over the card edges, with astro check and eslint both clean.
I had looked at a screenshot of that section and passed over it. Fixed with a
page-owned wrapper (48px, measured) and the prop is deleted from six components
so it is now a build error. Also: the credential row was never "two up on a
phone" and its comment said it was; PROCESS was hardcoded in the page against
the reason written in site.ts; 83px of residual overflow at a 200% default font
size, now 3px.

Seven more I found myself first, including <Picture widths> declaring the
untouched 1600px master as the <img src> fallback (254,626 B for a 476px slot,
and the build log said "before: 349kB" either way), and a prop named `as`
silently turning off type-checking for a whole component.

VERIFICATION — run, not asserted. Full figures in AGENTS.md entry (w).

npx tsc 6.0.3 · check 0/0/0 · lint clean · build clean · audit 0
1 <script> and it is JSON-LD; non-JSON-LD scripts 0; no JS bundle; identical
page with script execution disabled (444 nodes, 6,578 chars)
Phase 5 minifier check: no `animation` shorthand beside animation-timeline
overflow 0 at 14 widths, AND every mark measured at 1.5654-1.5657 vs 1.5657
one h1, no heading skips, focus order == DOM order across 44 focusables
31 painted contrast pairs at 3 widths, 0 failures
72/72 hit-test points across 8 cards resolve to the card's link
print 0 hidden, reduced-motion 0 hidden
Lighthouse NOT RUN — tool unavailable until step 7 (R11)
HTML validator NOT RUN, and 4 of 12 srcsets carry a duplicate 1x descriptor

Opened for Pouya: Q40 (one OG image for nineteen pages), Q41 (does Q37 reach
prose; may the comparative be restored; what LAT pre-hearing mediation means),
Q42 (the four "also offered" processes have no row), Q43 (the process timings
are published commitments with no row).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0148NztQskLKKApP5SzAA78e
This commit is contained in:
Pouya Lajevardi
2026-08-27 16:31:56 -04:00
co-authored by Claude Opus 5
parent 8a2f513577
commit 165d259f5c
26 changed files with 2636 additions and 742 deletions
+23 -1
View File
@@ -141,7 +141,15 @@ four audiences to its surface.
block on the page for search, because it distributes authority to the pages
that can actually rank.
6. **Process preview.** Compressed five-step strip → `/process/`.
7. **Latest insights.** Three most recent → `/insights/`.
7. **Latest insights.** Three most recent → `/insights/`. **NOT BUILT AT STEP
2, and it arrives at STEP 7 with the collection it lists.** `ArticleCard` and
the drafted slate (D9) land in the same step; rendering the section against an
empty collection means shipping a component's scoped CSS to every visitor for
a block with nothing in it, plus a props surface with no call site.
`SiteHeader` already gates the Insights **nav** item on the same collection,
so the page section and the nav item appear together. Recorded here as well
as in the page source, because "eight sections specified, seven built" should
not be discoverable only by reading the file that deviates.
8. **Contact band.** Intake CTA and booking link.
### `/about/` — Biography and credentials
@@ -280,6 +288,20 @@ Shareholder and partnership disputes, co-founder breakdowns, family-business
succession, SME exits. The operator angle — running SML Company Ltd. alongside
the practice — is the differentiator here.
**"Family Business" means COMMERCIAL disputes among family shareholders, and the
page must say so.** Pouya's ruling of 2026-08-27 (`AGENTS.md` Q39): the label
covers shareholder and partnership disputes, co-founder breakdowns and business
succession — **not** family law. **Family arbitration under the *Family Law Act*
is not offered**, and that activity is separately gated by prescribed training
(`docs/reference/ontario-family-arbitration-training.md`), so the exclusion has
to be legible rather than left to be inferred from the surrounding nouns.
**One sentence, not a section.** His instruction, and the reason is also the test
for whether it belongs at all: *"The page should say plainly that family law
matters are not accepted. One sentence, not a section: it saves a wasted intake
call, which is the only reason it earns its place."* A disclaimer that grows into
a paragraph reads as defensive, which is the opposite of the point.
### `/practice/cross-cultural/`
**Search intent:** `Farsi speaking mediator Toronto`,
+41 -2
View File
@@ -183,7 +183,7 @@ except the reveal of the hero.
| Component | Notes |
|---|---|
| `InfinityMark` | ⚠️ **Currently a raster — a documented, temporary exception to this rule** (`AGENTS.md` Q38, R13). The mark is gradient-mesh artwork rather than flat vector paths. An SVG *is* held and it renders faithfully — but at 257,278 bytes against 3,063 for the AVIF a Retina browser takes, carrying seven embedded base64 PNGs that would breach `CLAUDE.md`'s no-base64-images rule. The exception is about payload and composition, not about fidelity. It renders AVIF/WebP with a PNG fallback; a Retina device takes 3,063 B of AVIF, `alt=""` when decorative, aspect ratio pinned to `667 / 426`. **Restore this rule the moment the commissioned vector master lands.** Until then the rule stands unchanged for every other mark or icon: inline SVG, `currentColor`, `aria-hidden` when decorative, never a PNG |
| `InfinityMark` | ⚠️ **Currently a raster — a documented, temporary exception to this rule** (`AGENTS.md` Q38, R13). The mark is gradient-mesh artwork rather than flat vector paths. An SVG *is* held and it renders faithfully — **and it renders faithfully because it IS the raster**: 257,278 bytes wrapping **seven embedded base64 PNGs**, against **3,063 B** for the AVIF a Retina browser takes in the header — **84×**. *Figures re-stated 2026-08-27 because a second, larger call site now exists and the single number had become misleading:* the mark ships at **two intrinsic widths**, 64 px (header, footer) and 232 px (the home page's approach section, which renders at 225.5 px). At 232 px a DPR-2 device takes **14,555 B** and DPR-3 **22,639 B**, so the ratio against the SVG there is ~11×, not 84×. The full ladders are in `docs/reference/brand-assets.md`; do not quote one number as if it covered both. Inlining it would breach `CLAUDE.md`'s no-base64-images rule. *Pouya settled the characterisation on 2026-08-27: a first draft called the file "a raster in a vector wrapper", a later draft withdrew that as unfair, and **the withdrawal went too far.** Both halves are true — the fidelity is real, and it is bought with embedded raster, which is exactly why fidelity was never the question.* The exception is about payload and composition. It renders AVIF/WebP with a PNG fallback; a Retina device takes 3,063 B of AVIF, `alt=""` when decorative, aspect ratio pinned to `667 / 426`. **Restore this rule the moment the commissioned vector master lands.** Until then the rule stands unchanged for every other mark or icon: inline SVG, `currentColor`, `aria-hidden` when decorative, never a PNG |
| `SiteHeader` | **Sticky from 66 rem (1056 px) up; static below it.** Practice dropdown as CSS-only `<details>`. **(a)** The one-row header holds the brand, **seven** nav items and the CTA — Insights is the seventh, arriving on its own at build step 7. Binary search on the built page puts the true fit at **1047 px**; 66 rem is the clean token above it. Below 66 rem the nav takes its own row and the header measures **141 px** at tablet widths and **189 px** at 320375 px. **(b)** "Condenses on scroll" is a hairline rule and a shadow, **not a size change** — a `position: sticky` header stays in normal flow, so shrinking its padding lifts every page below it, against the CLS < 0.05 budget. Longhands only; see the component on what the minifier does to the `animation` shorthand. *(This row has been wrong twice, instructively. It first said 60 rem / "~115 px", a height the header never took. It then said 64 rem "with 32 px of clearance" — that 32 px was `.header-inner`'s own `column-gap` mistaken for slack; the real figure at 1024 px with seven items was **21.6 px**, and nothing overflowed only because flexbox crushed the logo inside the brand block. **Measure slack, not gaps.**)* |
| `SiteFooter` | Three-column sitemap, contact block, designations, entity line |
| `Eyebrow` | Mono label with optional maroon dot |
@@ -216,5 +216,44 @@ Not a polish pass. A build requirement.
- Forms: real `<label>` elements, `aria-describedby` for hints, errors announced
with `role="alert"` and tied to their field.
- Touch targets ≥ 44 × 44 px.
- Test at 200% zoom and at 320 px width.
- Test at 200% zoom and at 320 px width. **Both measured 2026-08-27 on `/`:
document overflow 0 at 320, 360, 390, 414, 640, 768, 900, 1024, 1056, 1200,
1216, 1280, 1440 and 1920 CSS px, with zero elements extending past the
viewport.** Page zoom at 200% of 1280 is the 640 column and at 400% is the
320 column, so WCAG 1.4.4 and 1.4.10 are both covered by that sweep.
**A stricter case is not fully clean, and it is recorded rather than left to
be discovered.** With the reader's *default font size* at 200% — root at
32 px, a real accessibility setting and not page zoom — `/` measured **234 px**
of overflow at 390. Brought down in three measured steps:
| Fix | 390 px | 320 px |
|---|---|---|
| as first built | 234 px | 304 px |
| `minmax(min(Nrem, 100%), 1fr)` on three grids | 83 px | 153 px |
| `.credentials` made explicit `repeat(2, minmax(0, 1fr))`; `.feature` padding clamped and `overflow-wrap: anywhere` on its title; `.contact-action` `flex: 0 1 auto` + `min-inline-size: 0` | **3 px** | **65 px** |
Two things worth keeping. **`overflow-wrap: break-word` permits a break at
layout time but does not reduce min-content size** — `anywhere` does, and that
distinction was the whole of one of those fixes. And 1280 px stays **602 px**
over, from the header's deliberate `flex-wrap: nowrap` above 66 rem plus
`white-space: nowrap` on the brand name; the 320 px residual is the same header
plus the display headline's 104 px floor. Undoing either re-opens the measured
step-1 header decision, so they stand. All of this is beyond what this floor
requires — page zoom is clean — so it is a robustness margin rather than a
failure. Revisit if a real reader hits it.
- **Measure the elements, not only the page.** A document-level overflow check
passes while a flex child absorbs the deficit by being crushed — that is how
step 1 shipped a logo at aspect 0.891 under a green "0 overflow at every
width". Assert the rendered geometry of the thing you care about. On `/`
every infinity-mark instance measures 1.56541.5657 against the master's
1.5657.
- **A touch-target measurement of the wrong box is not a finding.** The eight
cards on `/` report 2639 px-tall `<a>` elements and are fine: each card's
whole box is the link's hit area via `::after { inset: 0 }`, verified by
hit-testing nine points per card at three widths (24 cards, 9/9). Hit-test
before enlarging anything. WCAG 2.5.8's inline exception also applies to a
link sitting mid-sentence, and one such link on `/` is deliberately left at
164 x 21.
- Every page must be readable and navigable with JavaScript disabled.
+17 -1
View File
@@ -113,13 +113,29 @@ Three slots, never counts:
| Slot | Value | Label |
|---|---|---|
| 1 | **Q.Med** | ADRIC / ADRIO designation |
| 2 | **JD + ML** | Law and engineering |
| 2 | **JD + ML** | Legal training and engineering practice |
| 3 | **EN · FA** | Bilingual practice |
**Slot 2's label changed on 2026-08-27 (Pouya, `AGENTS.md` Q37).** It read
*"Law and engineering"*. His reasoning: *"The parallel was doing the implying — a
degree and a practice under one noun. The asymmetry is the honest part."* A JD is
a degree; engineering is a practice, and a verified one. Setting them in parallel
invited the reader to supply the symmetry, and for "Law" the missing half is a
licence — which D13 bars by implication as hard as by assertion. The replacement
is longer and deliberately lopsided. Do not tidy it back into a parallel.
Fourth slot where the layout has one: **Q.Arb — commenced August 2026.** Use
that wording, not "in progress": §4 pins it, and the weaker form drifts toward
"nearly complete", which §4 Forbidden bars outright.
**On the home page the fourth slot IS used, and it is not optional there.**
`docs/01` §`/` says "Three slots"; §4's paired-disclosure condition is the higher
authority and requires that wherever the site offers arbitration it "states
plainly" the stage of the arc. `/` says *arbitrator* in its opening sentence, so
the stage belongs on the same page rather than only in the footer. Rendered as
value `Q.Arb` over label `Commenced August 2026` — the same wording, with the
em-dash carried by the layout instead of by the string.
The substitution principle (`AGENTS.md` §4): wherever the design wants a "how
many", substitute a longer-arc credential. These are all true at launch and stay
true; none grows by closing files.
+2 -1
View File
@@ -209,7 +209,8 @@ An embedded scheduler for the 3045 minute confidential intake call
> **Note added 2026-08-26 — `style-src` has acquired a dependency.** The site
> now ships inline `style="…"` attributes that are load-bearing rather than
> decorative: `InfinityMark.astro` sets its own `block-size` that way, and the
> proof sheet renders computed swatches with it. They are fine under
> step-1 proof sheet rendered computed swatches with it (that page was deleted
> at build step 2; the mechanism is what matters here). They are fine under
> `style-src 'self' 'unsafe-inline'` as specified below. They would **not**
> survive a move to hashed or nonce'd styles — the infinity mark would collapse.
> Price that before tightening `style-src`, and read the components first.
+38 -10
View File
@@ -42,8 +42,11 @@ of this file implied it was; that was wrong.
What rules it out is weight and composition:
- **257,278 bytes**, against **9,468 bytes** for the AVIF a browser actually
takes at the size the mark renders. **27×.**
- **257,278 bytes**, against **3,063 bytes** for the AVIF a Retina device
actually takes in the header. **84×.** *(This line said "9,468 bytes... 27×"
until 2026-08-27. 9,468 was the DPR-1 figure — the number for the devices the
performance budget does **not** target. Quote the figure for the device the
budget is written for.)*
- **7 embedded base64 PNGs** (`<image>` elements), so it is a hybrid rather than
pure vector — inlining it would breach `CLAUDE.md`'s rule against
base64-inlining images, which is one of the specific faults of the build this
@@ -55,8 +58,12 @@ What `AGENTS.md` Q38 asks for is a master that is faithful **and** light.
## What the browser actually downloads
`<Picture>` emits AVIF, WebP and a PNG fallback at 1× and 2× of a 320 px
intrinsic width:
`<Picture>` emits AVIF, WebP and a PNG fallback at `densities` 1×, 2× and 3× of
whatever intrinsic `width` the call site passes. **There are now TWO ladders,
because there are two sizes of call site** `[measured 2026-08-27 — every figure
below read from the file on disk]`.
**`width={64}` — the default. The header (50.1 px wide) and footer (56.4 px).**
| | 1× (64 px) | 2× (128 px) | 3× (192 px) |
|---|---|---|---|
@@ -64,12 +71,33 @@ intrinsic width:
| WebP | 2,368 B | 5,368 B | 8,664 B |
| PNG (fallback) | 6,137 B | 16,996 B | 29,780 B |
A Retina device takes **3,063 B**. The first attempt sized the ladder at 320 px
— justified by a 4 rem sample on the proof sheet, a page step 2 deletes — and
stacked `densities` on top, so every DPR-2 device pulled a 640 px image into a
56 px slot: **20,629 B**, and the docs claimed 9 KB because that is what DPR 1
takes. Size to the largest render that survives, and quote the figure for the
devices the budget targets.
**`width={232}` — the home page's approach section, which renders at 225.5 px.**
| | 1× (232 px) | 2× (464 px) | 3× (696 px) |
|---|---|---|---|
| AVIF | **6,017 B** | **14,555 B** | **22,639 B** |
That instance is `loading="lazy"`: it sits roughly a screen and a half down, so
it is not on the LCP path. The header and footer marks stay `eager`.
**THE LADDER HAS NOW BEEN WRONG IN BOTH DIRECTIONS, which is why `width` is a
prop rather than a constant.**
- *Too big, 2026-08-26.* Sized at 320 px, justified by a 4 rem sample on the
proof sheet (a page step 2 has since deleted), with `densities` stacked on
top — so the ladder double-counted its own headroom and every DPR-2 device
pulled a 640 px image into a 56 px slot: **20,629 B**, while the docs claimed
9 KB because that is what DPR 1 took.
- *Too small, 2026-08-27.* The home page added a 225.5 px call site and
inherited the 64 px ladder, whose largest file is 192 px: **3.52× upscale at
DPR 3.** Now 232/464/696, and 696 covers the 676 device px a DPR-3 screen
asks for. All three instances measure ≤1.0× upscale at DPR 1, 2 and 3.
**Do not measure this with `img.naturalWidth`.** For an image chosen from a
`srcset` with an `x` descriptor it is **density-corrected**: the 192 px file
selected at `3x` reports 64, so reading it at DPR 1, 2 and 3 returns 64 every
time — which looks exactly like the ladder not being generated at all. Read the
files on disk.
Passing an explicit `width` is load-bearing: without it Astro emits the
untouched 2668 px master as the `<img src>` fallback — **1,146,406 bytes**
@@ -0,0 +1,77 @@
# Reference — Ontario's training requirements for family arbitrators
**Why this file exists.** `AGENTS.md` §4 Offerings rests on a proposition about
what Ontario law does and does not gate. R14: *anything a spec makes a claim
about must be reachable from the repository* — a claim whose source lives only
at a URL is one a reviewer can be asked to trust rather than check. This is the
extract, with its provenance and the command that produced it.
It is **not** legal advice and it is not a substitute for the instruments
themselves. It records what one government page said on one day.
---
## Provenance
| | |
|---|---|
| Source | `https://www.ontario.ca/page/training-family-arbitrators` |
| Retrieved | **2026-08-27** |
| Method | `WebFetch` — page converted to markdown, then queried for verbatim requirements, hour figures, the lawyer / non-lawyer distinction, ongoing-training period, and every statute or regulation named |
| Retrieved by | Claude Code, on Pouya's instruction of 2026-08-27 (Q39) |
| Cited by Pouya | Yes — this is the source named in his Q39 ruling, with the same three hour figures |
**Re-derive it:** fetch the URL and read it. If the page has changed, record the
change here rather than editing the extract — a stale extract with a date is
useful; a silently updated one is not.
---
## What the page states
Quoted as retrieved. Where the page's own wording is reproduced it is in
quotation marks.
**Screening for domestic violence and power imbalances.** "at least 14 hours
(within one week) to learn about screening parties for domestic violence and
power imbalances".
**Ontario family law — non-lawyers only.** "All family law arbitrators who are
not a part of the Ontario Bar, or another Canadian bar, must complete 30 hours
of training about Ontario family law." The page adds that "You do not need to
complete this training all at once."
**Members of the Ontario Bar.** No hour figure. The page states instead that
"you should ensure you are familiar with family law to fulfil your professional
obligation to provide services competently."
**Ongoing training.** "10 hours over any two-year period. Five of these hours
must be related to domestic violence or power imbalance issues".
**Statute named on the page.** *Arbitration Act, 1991*. **No section number and
no regulation (`O. Reg.`) number appears on the page.**
---
## What the page does NOT state — and this half matters more
**It says nothing about commercial arbitration.** Commercial arbitration is
neither mentioned nor excluded. The page does not state which arbitrations the
requirements apply to beyond describing them as family arbitration.
So the source establishes the **family** half of §4's scoped proposition
directly, and the **commercial** half only by *absence* — a page about family
arbitrators is not authority for what commercial arbitrators need. §4 records
the commercial half as **Pouya's stated position**, attributed to him and
deliberately unstamped, for exactly that reason.
**Nothing on the site turns on the gated activity.** Pouya has confirmed he does
not accept family arbitration under the *Family Law Act* (§4 Offerings, scope
exclusion). The requirements above are recorded because the register reasoned
from a false universal for a day and must not do so again — not because the
practice sits anywhere near them.
**Do not upgrade this file into an authority it is not.** If a stronger source
is ever wanted — the *Family Law Act* provisions and the regulation made under
it — fetch and extract those, name them by number, and date them. Do not write
a section number from memory.