fix: replace the traced infinity mark with the real artwork; add §4 Offerings
Q32 — the traced mark was a WRONG SHAPE and had shipped. Pouya compared it against the master and rejected it. Two grounds reproduce from the path and are verified here: all four cubic branches meet the origin at exactly 90 degrees, so the loops are tangent rather than crossing and at stroke-width 28 render as two kissing circles (signed crossing number 0; the strokes fuse across 61% of the mark's height at 2rem); and the master's ink bbox is 2668x1704 = 1.5657:1. The path is deleted, not kept as a fallback. Pouya's 1.23:1 figure is reconciled rather than left dangling: it is the bounding box of the path's COORDINATES, not the curve. Control points sit at y +/-160 where the curve reaches +/-120, so the hull is 400x320 and with stroke 428x348 = 1.2299. A trap rather than a slip — x is monotone, so the control points give the right width and a 33% inflated height, and the "does the width look right" check passes. The real artwork is now in the repo: master, tight crop (the render source, so the file's aspect ratio IS the mark's), full lockup, and the SVG. InfinityMark renders AVIF/WebP; a Retina device takes 3,063 B. Favicons regenerated; favicon.svg deleted. Q33/Q36 — Pouya accepts arbitration appointments now. §4 gains an Offerings category: competence for an offering, permission for a credential, with an explicit boundary so it cannot become a route around D13. The masthead tagline is restored, and the footer designation strip now carries "Q.Arb — commenced August 2026" so §4's paired-disclosure condition is actually met on every page rather than only asserted. Two conventions added to CLAUDE.md, both earned this session: anything a spec makes a claim about must be reachable from the repo (R14 — the traced mark survived two review passes because the artwork was not here to compare against); and a command that did not run is not evidence of absence (`timeout` is not installed on macOS, so four Drive reads never executed and were reported as an empty directory). Reviews: claims-auditor FAIL/13 and adversarial-reviewer 2 blocking, all resolved. The severe one was self-inflicted — `flex: none` landed on the <img> while <Picture>'s <picture> wrapper is the flex item, so the logo compressed to 28.5x32 at 1024px with seven nav items. The page-level overflow check passed throughout because the brand block absorbed the deficit by crushing the mark. Harness now asserts rendered aspect ratio. Opened: Q38, Q39. Closed: Q32, Q33, Q36. Narrowed: Q35. Added: R13, R14. AGENTS.md entry (v) carries a RESUME HERE section. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012XquaEq4BgWMCwUqLEyNkF
@@ -189,6 +189,140 @@ since May.
|
||||
| LinkedIn: `https://www.linkedin.com/in/pouyalajevardi/` | `[verified 2026-08-26 — Pouya]` |
|
||||
| ~~The boutique may be named on the site~~ | **STRUCK 2026-08-26 (Q25).** Superseded by **D16 — never named.** Pouya said it *could* be named, then reversed; the permission survived the reversal and sat in the Verified table authorising exactly what D16 bars. Refer to it only as *a Toronto litigation and ADR boutique* |
|
||||
|
||||
### Offerings — what the practice offers, as distinct from what Pouya holds
|
||||
|
||||
**Added 2026-08-26 on Pouya's ruling (Q33, Q36).** Everything above this point
|
||||
answers one question: *is this claim about Pouya true?* That is a question about
|
||||
**credentials**. It turns out the register also has to answer a second, different
|
||||
question: *does the practice offer this?* — and applying the credential test to
|
||||
an offering produced a wrong answer twice in one session.
|
||||
|
||||
**What went wrong, because it explains the rule — stated correctly on the second
|
||||
attempt.** `co-arbitration available now` was flagged across three specs on the
|
||||
reasoning that §4 records the Q.Arb pathway as merely *commenced* and therefore
|
||||
could not support an arbitration offering. **That** reasoning was wrong at the
|
||||
root: it silently treated a **designation** as though it were a **licence**.
|
||||
|
||||
*The masthead objection was a different one, and this paragraph originally
|
||||
misdescribed it.* Q33-orig did not say Pouya was not entitled to arbitrate. It
|
||||
said the line had been **promoted to a masthead under his name on every page,
|
||||
where nothing qualifies it and it reads as a designation strip** — an objection
|
||||
about **placement and implication**, not entitlement. Answering the entitlement
|
||||
objection does not answer the placement one, and the first version of this
|
||||
section quietly substituted the easier question. `claims-auditor` caught the
|
||||
substitution. The placement objection is answered by the paired-disclosure
|
||||
condition below, which is a **condition**, not a formality.
|
||||
|
||||
**Pouya's ruling, and the reasoning to keep.** His stated basis: ADRIC and ADRIO
|
||||
designations — Q.Med, Q.Arb, C.Med-Arb — are **voluntary credentials, not
|
||||
licences**, and **commercial arbitral appointment in Ontario is not gated behind
|
||||
a designation**. So the constraint on offering arbitration was never *may he
|
||||
act* — only *will parties appoint someone at this stage of the arc*, which is
|
||||
**positional** and his to answer. He answers it: **he accepts arbitration
|
||||
appointments now**, and that — his acceptance — is what the rows below record.
|
||||
|
||||
> ⚠️ **The legal proposition underneath is the architect's, not this register's,
|
||||
> and it is deliberately NOT stamped `[verified]`.** `[verified — Pouya]` means
|
||||
> *the subject reported it*, which can establish what he offers and cannot
|
||||
> establish a proposition of Ontario law. No statute or regulation is cited here
|
||||
> and none is in the repo, so **no reviewer can check it** — R14 again, in a
|
||||
> place that matters more than a logo.
|
||||
>
|
||||
> It is also **not a universal, and must never be restated as one.** An earlier
|
||||
> draft of this paragraph wrote "Anyone may be appointed an arbitrator in
|
||||
> Ontario. Nothing in law gates the role behind a designation." `claims-auditor`
|
||||
> produced a counter-example from inside this repo: the site ships a
|
||||
> **Shareholder & Family Business** practice area, and **family** arbitration in
|
||||
> Ontario is understood to be one of the places where arbitrator qualification
|
||||
> *is* prescribed. This record does not resolve that — it is **Q39** — but it
|
||||
> will not carry an unqualified universal that the site's own nav may already
|
||||
> contradict. The rows below are scoped to **commercial** arbitration for that
|
||||
> reason.
|
||||
|
||||
### The offering test
|
||||
|
||||
> **For an offering, ask about COMPETENCE. For a credential, ask about
|
||||
> PERMISSION.** A credential claim needs a row in the Verified table because it
|
||||
> asserts a fact about Pouya that is either true or false. An offering needs two
|
||||
> things, and they are answered by different people:
|
||||
>
|
||||
> 1. **Is the activity gated?** — *a question for THIS REGISTER, not for the
|
||||
> subject.* It needs a source that a reviewer can check, and it is answered
|
||||
> per activity and per jurisdiction, never as a class. Until it is answered,
|
||||
> the offering does not ship.
|
||||
> 2. **Is he competent to do it?** — *his call, and only his.* Not the
|
||||
> register's, not an implementer's, not a reviewer's.
|
||||
>
|
||||
> **Question 1 is not his to answer**, and an earlier draft of this test said it
|
||||
> was: it ended "That is his call, not the register's, and not an implementer's"
|
||||
> attached to the *whole* preceding question, gating included. That hands a
|
||||
> future writer the sentence *"he says this one is ungated, and §4 says that is
|
||||
> his call"* — which is the walk-through the boundary below exists to prevent.
|
||||
> Split, on `claims-auditor`'s finding, 2026-08-26.
|
||||
|
||||
### What counts as an offering, and the rule for publishing one
|
||||
|
||||
> **An offering may not be published until it has a row in "Offered now" below.**
|
||||
> Same force as the governing rule for the Verified table. The register created
|
||||
> this category; it has to gate it too, or it is a category that authorises
|
||||
> everything by saying nothing.
|
||||
|
||||
**Scope: an offering is a PROCESS the practice conducts** — mediation,
|
||||
arbitration, med-arb, early neutral evaluation, settlement counsel,
|
||||
dispute-system design, pre-dispute technical advisory. Each needs its own row.
|
||||
|
||||
**A subject-matter area is NOT an offering.** *Construction*, *technology*,
|
||||
*energy*, *insurance*, *shareholder*, *cross-cultural* are the contexts in which
|
||||
the processes are conducted, not additional things offered. They are governed by
|
||||
`docs/03`'s framing rule instead — *"Frame as positioning, not as history"* — and
|
||||
the open half of **Q35** asks whether a one-word nav label can carry even that.
|
||||
Do not read this scope note as clearing them; it says only which rule applies.
|
||||
|
||||
*Added 2026-08-26 on `claims-auditor`'s finding that the section had created a
|
||||
category without defining either its extent or its gate — so `Med-Arb` was
|
||||
sitting in the site-wide footer as an offering with no row, three sentences
|
||||
below a paragraph saying not to infer exactly that. It has been removed from the
|
||||
footer pending Q35(a).*
|
||||
|
||||
**THE BOUNDARY, AND IT IS NOT NEGOTIABLE.** This test applies **only where no
|
||||
licence gates the activity.** It is not a general licence-free zone, and it must
|
||||
never be read as one:
|
||||
|
||||
- **Mediation and arbitration are ungated.** No designation is required to be
|
||||
appointed. The offering test governs, and Pouya has answered it.
|
||||
- **Legal services are gated.** Providing legal services and practising law in
|
||||
Ontario are restricted activities. For anything on that side of the line the
|
||||
binding question is **permission**, the answer is **not established** (see the
|
||||
**Licence status — NOT ESTABLISHED** row above), and **D13 bars the claim
|
||||
outright.** "I offer legal representation — that is competence, not
|
||||
permission" is exactly the misreading this paragraph exists to foreclose.
|
||||
- **The test never converts a credential into an offering.** Q.Arb is still
|
||||
*commenced August 2026* and must still never read as held. Offering
|
||||
arbitration and holding Q.Arb are two different statements, and the site makes
|
||||
the first while stating the second plainly.
|
||||
|
||||
### Offered now — may be published
|
||||
|
||||
| Offering | Status |
|
||||
|---|---|
|
||||
| **Mediation** — sole mediator | `[verified 2026-08-26 — Pouya]`. Q.Med held; §4 also verifies multiple completed sole mediations |
|
||||
| **Arbitration — sole arbitrator** (commercial) | `[verified 2026-08-26 — Pouya, Q33/Q36]`. Offered **now**. Not gated by Q.Arb. **Commercial** — see Q39 on family arbitration |
|
||||
| **Arbitration — party-appointed** | `[verified 2026-08-26 — Pouya, Q33/Q36]`. Offered **now** |
|
||||
| **Arbitration — co-arbitration** | `[verified 2026-08-26 — Pouya, Q33/Q36]`. Offered **now**. This closes Q36, which had flagged the claim as asserted in three specs and resting on no §4 row — the row is here |
|
||||
| ~~Tribunal secretary~~ | **Not offered.** D14 removed the rate and bars offering it |
|
||||
|
||||
**How the arbitration page must read** (`docs/01` §`/arbitration/`, step 4):
|
||||
it offers all three today **and states plainly that the Q.Arb pathway commenced
|
||||
August 2026, with C.Med-Arb as the endpoint.** Pouya's instruction: *being open
|
||||
about the stage is the differentiator — do not hedge it into vagueness.* So
|
||||
neither half may be dropped. Naming the stage is not a disclaimer bolted onto an
|
||||
offering; it is the reason a sophisticated reader believes the offering.
|
||||
|
||||
**Still unanswered — do not infer from this section.** Whether **Med-Arb** is
|
||||
offered now is not recorded here; Pouya named the three arbitration forms and
|
||||
mediation, and nothing else. Med-Arb is ungated by the same reasoning, so the
|
||||
question is his competence call alone — but it is still a question. See Q35.
|
||||
|
||||
### Forbidden — must not appear on the site
|
||||
|
||||
**Scope, clarified 2026-08-26.** This table governs **published pages** — anything
|
||||
@@ -353,12 +487,18 @@ Nothing below can be invented. Each needs an answer from Pouya.
|
||||
| ~~Q29~~ | **ANSWERED 2026-08-26 by implementation.** Guard widened on both counts: the two secrets are checked (emptiness only, never echoed), and `INTAKE_ENDPOINT` is promoted to job-level `env:` and guarded. Every `vars.*` and `secrets.*` the workflow consumes is now covered except `BOOKING_URL`, empty by decision (R6) | — |
|
||||
| ~~Q30~~ | **ANSWERED 2026-08-26 — federally, under the CBCA**, and it does **not** appear in the footer. Recorded in §4 with the caution that it implies nothing about licensure or about where the practice may operate. The footer reads `© <year> SML Company Ltd` and stops there (Pouya's direction, given twice). `src/data/site.ts` un-nulled, `TODO(pouya)` removed. Note the spelling: §4 writes *SML Company Ltd.* with a terminal period; the rendered string has none, because that is how Pouya specified it | — |
|
||||
| ~~Q31~~ | **ANSWERED 2026-08-26 — Plausible**, and decided rather than defaulted. Pouya checked and found his own assumption wrong: Fathom is Canadian-owned but stores non-EU traffic on US servers, isolating in the EU only for EU visitors; Plausible holds everything in the EU. D15 amended with that reasoning. The value that was guessed and nulled is now the value that was chosen — which is not the same thing, and the difference is why it was nulled | — |
|
||||
| **Q35** | **May the header nav and footer sitemap name a service or practice area the register does not establish as a present capability, before the page that qualifies it exists?** This is the architecture-versus-register question that `claims-auditor` has now raised twice, and it is not one an implementer should settle. The nav and footer ship on all nineteen pages and today carry **`Arbitration`**, **`Med-Arb`**, **`Energy, Grid & Regulatory`** and **`Shareholder & Family Business`** — none of which trace to a §4 row. Every one of them is also **locked architecture**: D5 and §6 fix the sitemap, and `docs/01` specifies each page. The specs already anticipate the tension and answer it at page level — `docs/03`: *"Frame as positioning, not as history"*; `docs/01` on energy: *"Write it as a genuine position, not a claim of existing volume"* — so the question is precisely whether a **one-word nav label**, which has no room to frame anything, inherits that licence. Three ways out: accept the labels as taxonomy and rely on the pages to qualify (status quo), rename toward capability-neutral wording, or hold items out of the nav until their page ships. **Claude Code declined to act unilaterally on either audit pass**; recorded so the judgement is visible rather than missed | The header and footer on every page; sharpest at step 5 |
|
||||
| **Q36** | **Is co-arbitration work available now?** Asserted in three specs — `docs/01` §`/arbitration/`, `docs/03` §Voice as model copy, and `docs/07-fees.md`, which instructs *"The page must say so"* — and **it is in no §4 row.** §4 records the Q.Arb pathway as commenced August 2026 and nothing about what is available in the meantime. The sentence is offered under the heading *"Name the limits"*, so the unverified half travels inside advice about honesty, which is how it survived. All three files now cite this question; none has been deleted, because the *shape* of the sentence is right and only its second clause is unsourced. Raised by `claims-auditor`, 2026-08-26 | `/arbitration/` (step 4) and `/fees/` (step 9) |
|
||||
| **Q35** | **NARROWED 2026-08-26 — two of the four items are resolved; two are not.** `Arbitration` is answered (Q33) and is now a **§4 Offerings** row. What remains: **(a) Med-Arb** — ungated by the same reasoning, so it is purely a competence call, and Pouya named mediation and the three arbitration forms without naming it. Do not infer it. **(b) `Energy, Grid & Regulatory` and `Shareholder & Family Business`** — subject-matter areas rather than gated activities, so the offering test asks only whether he is competent to mediate or arbitrate in them, which is his answer to give. `docs/03` already fixes how the pages must read once answered — *"Frame as positioning, not as history"* — so this is not a blocker on writing them, only on claiming capability in a one-word nav label before the page exists. Original framing follows | Med-Arb (step 4); the practice pages (step 5) |
|
||||
| ~~Q35-orig~~ | **May the header nav and footer sitemap name a service or practice area the register does not establish as a present capability, before the page that qualifies it exists?** This is the architecture-versus-register question that `claims-auditor` has now raised twice, and it is not one an implementer should settle. The nav and footer ship on all nineteen pages and today carry **`Arbitration`**, **`Med-Arb`**, **`Energy, Grid & Regulatory`** and **`Shareholder & Family Business`** — none of which trace to a §4 row. Every one of them is also **locked architecture**: D5 and §6 fix the sitemap, and `docs/01` specifies each page. The specs already anticipate the tension and answer it at page level — `docs/03`: *"Frame as positioning, not as history"*; `docs/01` on energy: *"Write it as a genuine position, not a claim of existing volume"* — so the question is precisely whether a **one-word nav label**, which has no room to frame anything, inherits that licence. Three ways out: accept the labels as taxonomy and rely on the pages to qualify (status quo), rename toward capability-neutral wording, or hold items out of the nav until their page ships. **Claude Code declined to act unilaterally on either audit pass**; recorded so the judgement is visible rather than missed | The header and footer on every page; sharpest at step 5 |
|
||||
| ~~Q36~~ | **ANSWERED 2026-08-26 — yes, and so are sole-arbitrator and party-appointed appointments.** Now a row in **§4 Offerings** rather than an unsourced assertion in three specs. `docs/01`, `docs/03` and `docs/07-fees.md` no longer need to cite an open question against it. Original text follows | — |
|
||||
| ~~Q36-orig~~ | **Is co-arbitration work available now?** Asserted in three specs — `docs/01` §`/arbitration/`, `docs/03` §Voice as model copy, and `docs/07-fees.md`, which instructs *"The page must say so"* — and **it is in no §4 row.** §4 records the Q.Arb pathway as commenced August 2026 and nothing about what is available in the meantime. The sentence is offered under the heading *"Name the limits"*, so the unverified half travels inside advice about honesty, which is how it survived. All three files now cite this question; none has been deleted, because the *shape* of the sentence is right and only its second clause is unsourced. Raised by `claims-auditor`, 2026-08-26 | `/arbitration/` (step 4) and `/fees/` (step 9) |
|
||||
| **Q37** | **Is "Law and engineering" the right label under `JD + ML`?** §4's substitution principle supplies the three credential-row **values** (`Q.Med` / `JD + ML` / `EN · FA`); the labels come from `docs/03` and are not themselves registered. `claims-auditor` reads this one as a D13 implication risk: "engineering" is shorthand for a **verified practising** claim, so the parallel invites "Law" to be read the same way, and D13 bars implication as hard as assertion. Left as written — it is approved copy and changing approved copy is not an implementer's call — with a `TODO(pouya)` on it in `src/data/site.ts`. Nothing renders it yet. Raised by `claims-auditor`, 2026-08-26 | The credential row on `/` (step 2) and `/about/` (step 3) |
|
||||
| **Q33** | **How is arbitration described in site-wide copy before Q.Arb is conferred?** Not a wording question — a positioning one, and it recurs on every page. §4 records the Q.Arb pathway as **commenced August 2026**, "never as held or nearing completion". `SITE.tagline` reads `Mediation · Arbitration · Toronto`, and `docs/01` specifies that exact string as the **Home hero eyebrow** — where the hero copy beneath it can qualify it. Build step 1 promoted it to a masthead line under Pouya's name on every page, where nothing qualifies it and it reads as a designation strip; `claims-auditor` flagged it and **it has been removed from the header**. But the question it exposed is still open and lands at build step 2: does the hero eyebrow keep `Arbitration` as specified, qualify it, or hold it until designation? `/arbitration/` (step 4) is separately specced to state the position plainly, which is the honest model — the issue is the one-line forms that have no room to. **Second pass, same day:** the removal from the header did not sweep the proof sheet, where the same string was **hand-typed** as a type specimen and rendered ten times at up to 96px. Both defects fixed — the specimen is now a neutral pangram — and the lesson is the sweep rule again: a removal is a `grep`, not a memory. The nav item `Arbitration` also survives, deliberately; that is Q35. Raised by `claims-auditor`, 2026-08-26 | The Home hero (step 2); `docs/04`'s specified home `<title>`; any bio or one-line descriptor |
|
||||
| ~~Q33~~ | **ANSWERED 2026-08-26 — the question rested on a false premise.** It assumed the constraint on describing arbitration was about *entitlement*. ADR designations are voluntary credentials, not licences, and **anyone may be appointed an arbitrator in Ontario** — so the constraint was always positional, never legal, and it was Pouya's to answer. He accepts arbitration appointments now. `Mediation · Arbitration · Toronto` is **restored to the masthead one-liner**, and `docs/04`'s specified home `<title>` stands as written. See **§4 Offerings**, added for exactly this class of statement. The original question text follows for the record | — |
|
||||
| ~~Q33-orig~~ | **How is arbitration described in site-wide copy before Q.Arb is conferred?** Not a wording question — a positioning one, and it recurs on every page. §4 records the Q.Arb pathway as **commenced August 2026**, "never as held or nearing completion". `SITE.tagline` reads `Mediation · Arbitration · Toronto`, and `docs/01` specifies that exact string as the **Home hero eyebrow** — where the hero copy beneath it can qualify it. Build step 1 promoted it to a masthead line under Pouya's name on every page, where nothing qualifies it and it reads as a designation strip; `claims-auditor` flagged it and **it has been removed from the header**. But the question it exposed is still open and lands at build step 2: does the hero eyebrow keep `Arbitration` as specified, qualify it, or hold it until designation? `/arbitration/` (step 4) is separately specced to state the position plainly, which is the honest model — the issue is the one-line forms that have no room to. **Second pass, same day:** the removal from the header did not sweep the proof sheet, where the same string was **hand-typed** as a type specimen and rendered ten times at up to 96px. Both defects fixed — the specimen is now a neutral pangram — and the lesson is the sweep rule again: a removal is a `grep`, not a memory. The nav item `Arbitration` also survives, deliberately; that is Q35. Raised by `claims-auditor`, 2026-08-26 | The Home hero (step 2); `docs/04`'s specified home `<title>`; any bio or one-line descriptor |
|
||||
| **Q34** | **Do §2's measurements of the previous build still hold, and were they measured against the deployed file?** Two of `claims-auditor`'s findings were unverified old-site assertions published in copy, which sent Claude Code to measure the live URL on 2026-08-26. What came back does not straightforwardly match §2. **Reproduced:** the response is a single **2,206,032-byte** file, and `<title>` is still `SML Company · Dispute Resolution`. **Could not be reproduced from the served HTML:** there are **zero** `base64,` occurrences anywhere in it — §2 records "two logo PNGs ~1 MB, base64-inlined" — and no reference to `unpkg` or a React development build. **Why this is a question and not a correction:** the served document is a *bundler harness*. 2,210,921 bytes of it are inline `<script>`, the real `<head>` sits JSON-escaped inside a `<script type="__bundler/template">`, and the application is loaded from **nine UUID-named script files that were not fetched**. The logos and the CDN references may well be in those bundles. So §2 may be right, may be stale, or may have been measured against the local source rather than the deployment — this record cannot tell which. **Why it matters beyond tidiness:** `docs/02` and `CLAUDE.md` both cite the base64-logo figure as the *reason* for a standing convention, and §12 R8 exists because unverified premises propagate. Nobody should quote these numbers in public copy until the question closes. Raised by Claude Code, 2026-08-26 | Nothing structural. It governs whether §2's figures may be cited as fact |
|
||||
| **Q32** | **Is there a canonical vector file for the SML infinity mark?** `src/components/InfinityMark.astro` is built from geometry lifted verbatim from the deployed site's own loading-thumbnail SVG — the element it labels `smlMark`, fetched from `https://adr.smlcompany.ca/` on 2026-08-26. Path, both stroke widths (28 / 6) and the 0.7 inner opacity are the source's; the only change is folding a `translate(60 0)` into the coordinates. So it is SML's own artwork rather than a redrawing — but a loading placeholder is not necessarily the canonical file, and D7 says the mark carries over *unchanged*. If a master SVG or AI/EPS exists, supply it and the component gets replaced. Raised by Claude Code, 2026-08-26 | Nothing — the mark renders. This is about fidelity, not a blocker |
|
||||
| **Q39** | **Does the arbitration offering extend to FAMILY arbitration, and is that activity gated?** Raised by `claims-auditor` 2026-08-26 as a counter-example from inside this repo, and it is a good one. §4 Offerings rests on the proposition that arbitral appointment in Ontario is not gated behind a designation. The site ships a **`Shareholder & Family Business`** practice area — and **family** arbitration in Ontario is understood to be one of the places where arbitrator qualification *is* prescribed by statute and regulation. If so, the offering test's own boundary applies: where an activity is gated, the question is **permission**, and permission is not established. **This record does not resolve it** — Claude Code will not assert a proposition of Ontario law, and neither may a self-report. What is needed: (a) does the practice-area page contemplate family-law arbitration at all, or only shareholder, partnership and family-*business* disputes, which is a different thing; and (b) if it does, the gating question needs a checkable source in the repo, per R14. **Interim:** §4's arbitration rows are scoped to **commercial** arbitration and the universal has been removed from the reasoning. Nothing ships that turns on it | The `Shareholder & Family Business` page (step 5); `/arbitration/` (step 4) |
|
||||
| **Q38** | **A true vector master for the infinity mark.** The mark is a shaded ribbon — variable-width band, maroon flowing into champagne, twisting in three dimensions and passing over itself at the crossing. That is gradient-mesh artwork, and there is no honest way to express it as the flat vector paths `docs/02` assumes. An SVG **is** held — `src/assets/brand/sml-logo-source.svg` — and **it renders faithfully**: rasterised at 8333 px it reproduces the master exactly, at the same 1.566:1 `[verified 2026-08-26 — rendered and measured]`. *An earlier draft of this row called it "a raster in a vector wrapper", which was unfair and is corrected.* What rules it out is **payload and composition**: 257,278 bytes against **3,063** for the AVIF a Retina browser actually takes — 84× — plus **seven embedded base64 PNGs** and a 1,225-stop gradient mesh, so inlining it would breach `CLAUDE.md`'s rule against base64-inlining images. What is wanted is a master that is faithful **and** light. **Pouya is commissioning a proper vector master.** Until it lands, `InfinityMark.astro` renders an optimised raster and that is a **documented, temporary exception to `docs/02`'s inline-SVG rule** (R13 keeps it from becoming permanent). When the master arrives: replace the component's `<Picture>` with inline SVG, regenerate the favicons from it, and delete the exception from `docs/02` and this row. Raised by Claude Code 2026-08-26; scoped by Pouya the same day | Nothing — the mark renders correctly. This is fidelity and payload, not function |
|
||||
| ~~Q32~~ | **ANSWERED 2026-08-26 — and the answer was that the reconstruction was WRONG.** Pouya rendered the committed path against the master (`SML Company Just Logo Transparent.png`, 3000×3000) and rejected it on three counts. Two reproduce from the path alone: **(a) TANGENT, NOT CROSSING** — all four cubic branches meet the origin at exactly 90°, so the loops are mutually tangent on a vertical line and at stroke-width 28 render as *two kissing circles*, the one thing an infinity mark must not be `[verified 2026-08-26 — tangent vectors computed per segment, independently reproduced]`. Both lobes are strictly confined to their own half-plane (x is monotone on every segment), so the signed crossing number is **0** — they cannot cross anywhere, not merely at the node. Worse at the size actually shipped: the two strokes stay fused into one mass wherever the centreline separation `y²/192` is under 28, i.e. across **61% of the mark's height** — at 2rem that is a 16.8px blob out of a 27.4px-tall mark. No stroke-width, viewBox or scale change can produce a crossing from this centreline; **(b) WRONG PROPORTION** — the master's ink bounding box is **2668 × 1704 = 1.5657:1** `[verified 2026-08-26 — measured]`, and **(c)** the master is a shaded ribbon where the trace was two flat uniform strokes. ***1.23:1 — RECONCILED, and it was a real measurement, not a slip.*** It is the bounding box of the path's **coordinates** rather than of the **curve**. The control points sit at y = ±160 while the curve only reaches ±120 — the standard 3/4 pull-in of a cubic — so a coordinate-hull box is 400 × 320 = 1.2500, and with stroke-width 28 applied on all four sides it is **428 × 348 = 1.2299**. Pouya's figure to four significant figures, from one method applied consistently `[verified 2026-08-26 — derived]`. **It is a trap rather than a slip:** because x is monotone on every segment, the control points give the *correct* width (±200) and a 33% inflated height, so the obvious sanity check — "does the width look right?" — passes. Any tool that reads a bbox from parsed coordinates lands here; `getBBox()` would have returned 400 × 240. **And the direction is inverted from how it read:** measured from the curve, the traced path is 6.4% *wider and flatter* than the master, not squatter. **Consequence worth keeping:** the declared viewBox 440:280 = 1.5714 is within **0.35%** of the master's 1.566, so re-tuning the layout to the true ratio was ~0.18px of work at the shipped 2rem — and **re-tuning to 1.23 would have actively broken it** — at any given width 1.2299 allocates 1.5657/1.2299 = **27% more height** than the mark occupies, so the header would have been rebuilt around a box a quarter too tall. The ratio was never sufficient grounds on its own; **(a) tangency is, and it is exact.** **The traced path is deleted, not kept as a fallback**, on Pouya's instruction: *a wrong mark that renders is worse than a missing one, because it stops looking wrong.* Now closed by Q38 for the vector master | — |
|
||||
| ~~Q32-orig~~ | *(superseded — the original wording of this question is preserved in entry (v))* | `src/components/InfinityMark.astro` is built from geometry lifted verbatim from the deployed site's own loading-thumbnail SVG — the element it labels `smlMark`, fetched from `https://adr.smlcompany.ca/` on 2026-08-26. Path, both stroke widths (28 / 6) and the 0.7 inner opacity are the source's; the only change is folding a `translate(60 0)` into the coordinates. So it is SML's own artwork rather than a redrawing — but a loading placeholder is not necessarily the canonical file, and D7 says the mark carries over *unchanged*. If a master SVG or AI/EPS exists, supply it and the component gets replaced. Raised by Claude Code, 2026-08-26 | Nothing — the mark renders. This is about fidelity, not a blocker |
|
||||
| **Q23** | **Is a Gitea `act_runner` registered, and are Actions enabled in `app.ini`?** *The version half is closed:* the instance reports **1.27.2** `[verified 2026-08-26 — /api/v1/version]`, so the `vars` context is supported and the first-step guard is belt-and-braces rather than load-bearing. **What remains is not a fact to look up but a dependency on a person:** git.larsnolden.com is **jointly administered**, and both enabling Actions and registering a runner need the second administrator. Until then `npm run deploy` is the path, and it is documented rather than treated as a workaround | How deploys are triggered — not what they do |
|
||||
|
||||
## 10. Risks
|
||||
@@ -418,6 +558,8 @@ never being raised again.
|
||||
| R10 | **Annually-renewing memberships.** §4 verifies the **OBA sections** (Construction & Infrastructure, ADR, Civil Litigation) and the **Canadian Tax Foundation** as of 2026-08-26 — *for now*. Both renew yearly. *Widened 2026-08-26 when CTF was added; it was OBA-only before* | 2026-08-26 | A credential that lapses quietly is the failure mode §4 exists to prevent, and OCNI already did exactly this (§4 records it as "not current, do not publish"). Re-confirm at each renewal, and before any page listing memberships ships — `/about/` at build step 3 is the first one that will |
|
||||
| R11 | **Re-check dependency currency at every phase boundary in the build order** (`docs/01-architecture.md` §Build order, 11 steps). Run `npm view <pkg> version` across **every** pin in `package.json` and compare; do not wait for something to break. Verified does not mean latest — record the reason for any deliberate hold in §7. **Carries one specific re-add trigger: at step 7, put `@lhci/cli` back.** Check for a patched release — do not assume `0.15.1` is still the ceiling just because it was on 2026-08-26 — pin it against `npm view` that day, write a `lighthouserc` with the budgets from `docs/04-seo-spec.md`, and delete the UNAVAILABLE notices this repo now carries in six places (§7 lists them). If the advisories are still unfixed, that is a decision to take deliberately, not a reason to leave the gap unstated | 2026-08-26 | `astro: "^5.0.0"` was recalled rather than checked and was two majors stale the day it was written, which meant a framework carrying high-severity XSS advisories. Between phases is cheap; after a phase of pages is written is not. The build order has ten more boundaries |
|
||||
| R12 | **`compressHTML: true` is a deliberate deviation from the Astro 7 default (`'jsx'`).** Measured 2026-08-26: in an `.astro` template an inline pair split across two lines renders as `<em>a</em><strong>b</strong>` under the default — the space is silently deleted. MDX prose is unaffected | 2026-08-26 | It is a deviation, and undocumented deviations become folklore. Revisit **with a measurement**, not a preference — and re-measure after any Astro major, since the behaviour could change again |
|
||||
| R13 | **The infinity mark ships as a RASTER, and that is temporary.** `InfinityMark.astro` renders an optimised AVIF/WebP from `src/assets/brand/sml-infinity-mark.png` — a deliberate, documented exception to `docs/02`'s "inline SVG, never a PNG", because the mark is gradient-mesh artwork and no true vector master exists yet (Q38). **Removal trigger: the commissioned vector master lands.** Then replace the `<Picture>` with inline SVG, regenerate `favicon.ico` and `apple-touch-icon.png` from it, and delete the exception from `docs/02`, from the component, and from Q38 | 2026-08-26 | Pouya flagged this himself when he made the ruling: *an interim raster is exactly the kind of temporary measure that becomes permanent by never being raised.* It costs ~8 KB and works, which is precisely why nobody will notice it again. There is no build error to prompt anyone — only this row |
|
||||
| R14 | **Anything a spec makes a claim about must be reachable from the repository.** If the artefact lives only in Drive, in a console, or on someone's disk, no reviewer can check the claim and the claim is unverifiable by construction — see the rule now in `CLAUDE.md` | 2026-08-26 | **This has now cost twice.** Q24 was `AWS-Hosting-Guide.md`, the only record of how the infrastructure was hand-built, living outside the repo. Q32 was the infinity mark: Claude Code traced it from the old site's *loading placeholder*, wrote a scrupulous provenance comment recording exactly that doubt — and **two adversarial review passes still could not catch it**, because the artwork they would have had to compare against was not in the repo. The doubt was correctly stated and structurally uncheckable. That is the failure mode: not a missing warning, a missing artefact |
|
||||
| ~~R7~~ | **RATIFIED / SUPERSEDED 2026-08-26.** (a) Cache-policy table matching the pipeline — **accepted**; documenting what the pipeline does beats documenting an intention. (b) `s3:AbortMultipartUpload` omitted — **accepted, reasoning corrected**: the lifecycle rule does not exist and is therefore not the cover; the actual cover is that `aws s3 sync` only goes multipart above 8 MB and the largest asset is a 357 KB portrait. Recorded in `docs/06-deployment.md` with a revisit trigger. (c) The `aws s3 ls` pre-flight — **superseded** by the variable guard now running as the workflow's first step | 2026-08-26 | — |
|
||||
| ~~R8~~ | **PROMOTED TO A RULE 2026-08-26.** A reminder was too weak for a pattern that survived three entries. *A sweep is a command, not a claim* now sits in `CLAUDE.md` under Conventions, in `/build` Phase 6, and in `/wrap` step 3: any claim that a change was applied across files must cite the command and be written only after reading its output | 2026-08-26 | — |
|
||||
|
||||
@@ -425,6 +567,268 @@ never being raised again.
|
||||
|
||||
# Change Log
|
||||
|
||||
## 2026-08-26 (v) — The mark was wrong; §4 gains an Offerings category; and two of my own tools lied to me
|
||||
|
||||
**Who:** Pouya ruled on the mark (Q32), on arbitration (Q33, Q36), and on the
|
||||
asset convention. Claude Code implemented; `adversarial-reviewer` and
|
||||
`claims-auditor` ran on the result. **The claims audit returned FAIL with 13
|
||||
findings, and the sharpest of them were against text written an hour earlier in
|
||||
this same entry's work.** Most of what follows is those findings.
|
||||
|
||||
### Q32 — the infinity mark was a wrong shape, and it had shipped
|
||||
|
||||
Pouya rendered the committed path against the master and rejected it. Two of his
|
||||
three grounds reproduce from the path alone and are now verified here:
|
||||
|
||||
- **TANGENT, NOT CROSSING.** All four cubic branches meet the origin at exactly
|
||||
90°, so the loops are mutually tangent on a vertical line rather than crossing.
|
||||
At stroke-width 28 that renders as **two kissing circles** — the one thing an
|
||||
infinity mark must not be `[verified 2026-08-26 — tangent vector computed per
|
||||
segment]`. This alone disqualifies the shape.
|
||||
- **WRONG PROPORTION.** The master's ink bounding box is **2668 × 1704 =
|
||||
1.5657:1** `[verified 2026-08-26 — measured]`.
|
||||
- **FLAT.** Two uniform strokes standing in for a shaded ribbon: a band of
|
||||
variable width twisting in three dimensions, maroon into champagne, passing
|
||||
over itself at the crossing.
|
||||
|
||||
**The 1.23:1 figure is reconciled, and it was a real measurement.** It is the
|
||||
bounding box of the path's **coordinates**, not of the **curve**: control points
|
||||
sit at y = ±160 where the curve reaches only ±120, so the coordinate hull is
|
||||
400 × 320, and with stroke-width 28 on all four sides **428 × 348 = 1.2299**.
|
||||
Pouya's number exactly. It is a trap rather than a slip — x is monotone on every
|
||||
segment, so the control points give the *right* width and a 33% inflated height,
|
||||
and the usual "does the width look right?" check passes.
|
||||
|
||||
Two consequences worth keeping. **The direction was inverted:** measured from the
|
||||
curve, the traced path is 6.4% *wider* than the master, not squatter. And the
|
||||
declared viewBox 440:280 = 1.5714 sits within **0.35%** of 1.566 — so step 3 of
|
||||
the ruling, re-tune the layout to the true aspect, was **0.18px of work at the
|
||||
shipped 2rem**, and re-tuning to 1.23 would have *broken* it: for any
|
||||
given width, 1.2299 allocates 1.5657/1.2299 = **27% more height** than the mark
|
||||
actually occupies, so the header would have been rebuilt around a box a quarter
|
||||
too tall. Where 1.566 does matter is step 2: a tight crop to ink is
|
||||
exactly the measurement where 1.667 and 1.566 differ visibly, which is why the
|
||||
render source is cropped to the master's ink box and pinned at `667 / 426` rather
|
||||
than inheriting 11:7. **The ratio was never sufficient grounds on its own.
|
||||
Tangency was, and it is exact** — both lobes are confined to their own
|
||||
half-plane, so the signed crossing number is 0, and at 2rem the strokes fuse into
|
||||
a single mass across 61% of the mark's height.
|
||||
|
||||
**The traced path is deleted, not kept as a fallback**, on Pouya's instruction:
|
||||
*a wrong mark that renders is worse than a missing one, because it stops looking
|
||||
wrong.* `public/favicon.svg` deleted with it; the favicon chain is regenerated
|
||||
from the real artwork.
|
||||
|
||||
### Why two review passes could not catch it — and the rule that follows
|
||||
|
||||
`InfinityMark.astro` carried a scrupulous provenance comment stating that the
|
||||
path was traced from the **old site's loading placeholder** and that a
|
||||
placeholder is not necessarily canonical. It was correct, it was prominent, and
|
||||
**it did not help**, because the artwork it would have to be checked against was
|
||||
not in the repository. The doubt was stated and structurally uncheckable.
|
||||
|
||||
**New rule in `CLAUDE.md`, and R14:** *anything a spec makes a claim about must
|
||||
be reachable from the repository.* If the artefact lives only in Drive, in a
|
||||
console, or on a laptop, the claim is **unverifiable by construction**, not
|
||||
merely unverified. Second occurrence — Q24 was `AWS-Hosting-Guide.md`, the only
|
||||
record of how the infrastructure was built, living outside the repo.
|
||||
|
||||
### Two process failures of my own, both in the same shape
|
||||
|
||||
1. **I reported the brand assets unreachable. They never were.** Four commands of
|
||||
the form `timeout 60 ls "$DRIVE"` returned empty output; I read that as an
|
||||
empty directory and told Pouya the ruling could not be executed. **`timeout`
|
||||
is not installed on macOS** — the commands had never run. The Drive was fully
|
||||
readable the whole time and the masters were found within a minute of using a
|
||||
tool that exists.
|
||||
2. **I reported malformed HTML** — `<picture="true">` and
|
||||
`style="block-size:2rem"="true"` — and rewrote a component around it. It was
|
||||
**my own regex**, stripping an attribute's name and leaving its value. The
|
||||
markup was always valid. The rewrite was reverted.
|
||||
|
||||
Both are the same failure as *a sweep is a command, not a claim*: an assertion
|
||||
resting on output that was never produced, or was produced by my own filter.
|
||||
**New rule in `CLAUDE.md`:** *a command that did not run is not evidence of
|
||||
absence* — check the tool exists, read exit status, not just stdout.
|
||||
|
||||
### What the mark is now
|
||||
|
||||
`src/assets/brand/` holds the master (3000 × 3000, alpha), the tight crop that is
|
||||
the render source (2668 × 1704, so **the file's aspect ratio is the mark's**),
|
||||
the full lockup, and the SVG Pouya added. `InfinityMark.astro` renders it through
|
||||
Astro's `<Picture>`; a browser downloads **3,063 bytes** of AVIF on a Retina device.
|
||||
|
||||
**Correction inside this entry.** The SVG was first described here and in three
|
||||
files as "a raster in a vector wrapper". That was unfair: rasterised at 8333 px
|
||||
it **reproduces the master exactly, at the same 1.566:1** `[verified 2026-08-26]`.
|
||||
What rules it out is **payload and composition** — 257,278 bytes against 9,468,
|
||||
plus seven embedded base64 PNGs that would breach `CLAUDE.md`'s no-base64 rule.
|
||||
Corrected in the component, `docs/02`, Q38 and `docs/reference/brand-assets.md`.
|
||||
|
||||
**`width={320}` on `<Picture>` is load-bearing.** Without it Astro emits the
|
||||
untouched 2668 px master as the `<img src>` fallback — **1,146,406 bytes** — sitting
|
||||
in `dist` looking like an optimisation had happened.
|
||||
|
||||
**Documented, temporary exception to `docs/02`'s "inline SVG, never a PNG"**,
|
||||
tracked as **Q38** (a vector master that is faithful *and* light) with **R13** so
|
||||
it cannot become permanent by neglect — Pouya's own warning when he made the
|
||||
ruling.
|
||||
|
||||
### Q33 and Q36 — arbitration, and a new §4 category
|
||||
|
||||
**Both answered: Pouya accepts arbitration appointments now** — sole,
|
||||
party-appointed and co-arbitration. His reasoning: ADR designations are
|
||||
**voluntary credentials, not licences**, so the constraint was always
|
||||
**positional**, never legal. `Mediation · Arbitration · Toronto` is **restored to
|
||||
the masthead**; `docs/04`'s home `<title>` stands as specified.
|
||||
|
||||
**§4 gains an Offerings subsection** — a second category beside the credential
|
||||
register, with the test: **competence for an offering, permission for a
|
||||
credential.** Three specs that asserted the converse were swept
|
||||
(`docs/01`, `docs/03`, `docs/07-fees.md`) — and that sweep had been *claimed* in
|
||||
the Q36 closure before it was *run*, which `claims-auditor` caught. `docs/03`'s
|
||||
model sentence was wrong in **both** halves and in opposite directions, which is
|
||||
why it had survived two audits.
|
||||
|
||||
### What the claims audit found in the new section, and how it was resolved
|
||||
|
||||
Four structural defects in text written the same hour:
|
||||
|
||||
- **The masthead justification answered the wrong objection.** Q33-orig had
|
||||
objected to **placement** — a line under his name on every page *"where nothing
|
||||
qualifies it"* — not to entitlement. The section refuted an entitlement
|
||||
objection nobody raised. Corrected, and the substitution is recorded rather
|
||||
than tidied away.
|
||||
- **§4's own paired-disclosure condition was unmet by the shipped build.** The
|
||||
section says the site *"makes the first while stating the second plainly"* and
|
||||
*"neither half may be dropped"* — yet the masthead shipped on every page while
|
||||
the Q.Arb stage shipped on none, and `CREDENTIALS.inProgress` existed in
|
||||
`site.ts` rendered nowhere. **The footer designation strip now reads
|
||||
`Q.Med (ADRIC / ADRIO) · Q.Arb — commenced August 2026` on every page.**
|
||||
- **The offering test handed the gating question to the subject.** Its closing
|
||||
sentence, *"that is his call, not the register's"*, attached to the whole
|
||||
preceding question including *whether the activity is gated* — a clean
|
||||
walk-through for a future writer. Split in two: **gating is this register's
|
||||
question and needs a checkable source; competence is his and only his.**
|
||||
- **The category had no gate and no defined extent.** No rule said an offering
|
||||
needs a row before it may be published, and `Med-Arb` was sitting in the
|
||||
site-wide footer as an offering three sentences below a paragraph saying not to
|
||||
infer exactly that. Both fixed: the publication rule is stated, scope is
|
||||
defined (**an offering is a PROCESS; a subject-matter area is not**), and
|
||||
**Med-Arb is removed from the footer pending Q35(a)**.
|
||||
|
||||
**And the finding that matters most: four unsourced propositions of Ontario
|
||||
law.** *"Anyone may be appointed an arbitrator in Ontario. Nothing in law gates
|
||||
the role behind a designation."* `[verified — Pouya]` means *the subject reported
|
||||
it*, which can establish what he offers and **cannot establish a proposition of
|
||||
law**. The auditor produced a counter-example from inside the repo: the site
|
||||
ships a **Shareholder & Family Business** practice area, and **family**
|
||||
arbitration in Ontario is understood to be one of the places where arbitrator
|
||||
qualification *is* prescribed. §4 now carries the proposition as **the
|
||||
architect's stated basis, deliberately unstamped**, scoped to **commercial**
|
||||
arbitration, with the universal removed — and **Q39** opened. This record will
|
||||
not assert Ontario law, and neither will a self-report.
|
||||
|
||||
### Questions and reminders
|
||||
|
||||
**Closed:** Q32 (the reconstruction was wrong), Q33, Q36.
|
||||
**Narrowed:** Q35 — `Arbitration` resolved; **Med-Arb** and the two
|
||||
subject-matter labels remain, now under the scope note that says which rule
|
||||
governs them.
|
||||
**Opened:** **Q38** (vector master), **Q39** (family arbitration and gating).
|
||||
**§12:** **R13** (the raster is temporary), **R14** (assets must be in-repo).
|
||||
|
||||
### Verification — run, not asserted
|
||||
|
||||
`npm run check` 0/0/0 · `npm run lint` clean · `npm run build` 0 errors ·
|
||||
`npm audit` **0 vulnerabilities**.
|
||||
|
||||
Measured in headless Chrome at 320/375/640/768/1000/1023/1024/1100/1199/1200/1201/1279/1280/1281/1440/1600,
|
||||
**with a seventh nav item injected** for the step-7 state:
|
||||
|
||||
- **0 overflow, 0 focus-order inversions, 0 tap targets under 44 × 44** at every
|
||||
width; closed `<details>` panels contribute 0 hidden tab stops
|
||||
- Header a constant **81px** at every sticky width — 32 padding + 48 reserved
|
||||
brand block + **the 1px border I had forgotten**, which is why `--header-h` is
|
||||
measured rather than added up
|
||||
- Restoring the tagline **broke the 64rem fit** (84px past the content box at
|
||||
1024 with seven items) and was re-tuned: tagline gated at 75rem, nav gap moved
|
||||
to **80rem so two things do not grow at one breakpoint** — 4px of spill at
|
||||
exactly 1200px caught that
|
||||
- **0 `<script>` tags, 0 `.js` files**; both scroll-driven animations attach live
|
||||
- Print: all four revealed cards present · **760 words** with no JavaScript
|
||||
|
||||
### ⏸ RESUME HERE — session ended mid-flight, 2026-08-26
|
||||
|
||||
Pouya went mobile. The tree is committed and green; nothing is half-applied.
|
||||
**Pick up at the numbered list below.**
|
||||
|
||||
**State:** `npm run check` 0/0/0 · `npm run lint` clean · `npm run build` 0
|
||||
errors · `npm audit` 0 vulnerabilities. Both `adversarial-reviewer` blocking
|
||||
findings on the mark are fixed and re-measured. Build step 1 is complete; step 2
|
||||
is `/` (`docs/01` §Build order).
|
||||
|
||||
**Waiting on Pouya — nothing proceeds on these without a ruling:**
|
||||
|
||||
1. **Q35** — may the nav and footer name `Med-Arb`, `Energy, Grid & Regulatory`
|
||||
and `Shareholder & Family Business`? Both halves go to him **together**;
|
||||
`Med-Arb` was removed from the footer for a few hours and restored, because
|
||||
acting on one half unilaterally was wrong and orphaned the page.
|
||||
2. **Q39** — family arbitration. §4's arbitration rows are scoped to
|
||||
**commercial** pending an answer. This one has a legal dimension the register
|
||||
cannot resolve from a self-report.
|
||||
3. **Q37** — is `JD + ML → "Law and engineering"` the right label? Answer before
|
||||
step 2 renders the credential row.
|
||||
4. **Q38 / R13** — the commissioned vector master. Until it lands the mark ships
|
||||
as a raster under a documented exception.
|
||||
5. **R1** — the licensure framing is interim and now carried by shipped pages.
|
||||
|
||||
**Unresolved review findings, all non-blocking, none shipped-defect:**
|
||||
|
||||
- `adversarial-reviewer` #7: `gap: 2px` and `font-size: 0.6875rem` in
|
||||
`SiteHeader` are magic numbers; add `--text-2xs` / `--space-05` or record the
|
||||
deviation.
|
||||
- #8: Astro's `<Picture>` + `densities` emits a duplicate `1x` descriptor in
|
||||
`srcset` — an HTML conformance error, harmless in browsers. Do not claim
|
||||
"validator clean" on a page carrying it.
|
||||
- #9: `--header-h` has 0.81 px of headroom at ≥76 rem. A font-metric change
|
||||
pushes the brand past its 48 px reservation with no build error.
|
||||
- #10: the masthead tagline duplicates the home hero eyebrow, so `/` will open
|
||||
with the same words twice. Decide at step 2.
|
||||
- #11: ~3.16 MB of brand binaries; the 1.1 MB derived crop is reproducible from
|
||||
the committed master and could go if Astro could crop at build time.
|
||||
- #12: `InfinityMark`'s `label` and `class` props have no call site.
|
||||
|
||||
**One correction owed to the record.** Entry (v)'s verification section says
|
||||
"0 overflow at every width". That was true and **misleading** — the page-level
|
||||
check passed *because* the brand block absorbed the deficit by crushing the
|
||||
logo. The harness now asserts the rendered aspect ratio of every mark instance,
|
||||
not just document overflow. Measure the elements, not only the page.
|
||||
|
||||
### Declined and deferred
|
||||
|
||||
- **The remaining Q35 labels** — locked architecture; not an implementer's call.
|
||||
- **A verification workflow was run and half of it was wasted, which is worth
|
||||
recording rather than hiding.** It was launched while the artwork was believed
|
||||
unreachable, and briefed accordingly; the premise died four minutes later when
|
||||
the assets were found. Its *design* strand — three proposals for coping without
|
||||
the artwork — was answered by reality and discarded. Its *geometry* strand did
|
||||
not depend on that premise at all, and it is what **reconciled 1.23:1** above,
|
||||
proved the zero crossing number, and computed the fused-waist figure. The
|
||||
lesson is not "don't delegate" but "scope a brief to what cannot change under
|
||||
it": a premise about the environment goes stale, a question about the contents
|
||||
of a committed file does not.
|
||||
- **`Technology, AI & Data` and the other three practice labels**, raised as
|
||||
offering claims with no rows: answered structurally rather than individually —
|
||||
subject-matter areas are **not** offerings, so the Offerings table is not the
|
||||
rule that governs them. `docs/03`'s framing rule and Q35 are.
|
||||
- **`docs/reference/brand-assets.md` reproducing R14** — the auditor was right
|
||||
that every measurement derived from a master outside the repo. **Fixed, not
|
||||
declined:** the uncropped master is now committed, so the crop is re-derivable
|
||||
in-repo, and every figure carries a stamp.
|
||||
|
||||
---
|
||||
|
||||
## 2026-08-26 (u) — Build step 1. Zero JavaScript, and both review passes found defects in the first pass's fixes
|
||||
|
||||
**Who:** Pouya ruled on CTF, Q30, Q31 and the Lighthouse gap, and set the
|
||||
|
||||
@@ -152,6 +152,30 @@ interactive elements reachable by keyboard, `prefers-reduced-motion` honoured on
|
||||
every animation. Gold `#c9a876` never sits on cream — it fails contrast at
|
||||
2.10:1. See `docs/02-design-system.md`.
|
||||
|
||||
**Anything a spec makes a claim about must be reachable from the repository.**
|
||||
If the artefact lives only in Drive, in a console, or on someone's laptop, no
|
||||
reviewer can compare the claim against it and the claim is **unverifiable by
|
||||
construction** — not merely unverified. Commit the artefact, or commit a faithful
|
||||
extract with its provenance and the command that produced it.
|
||||
|
||||
This has cost twice. `AGENTS.md` Q24 was the AWS hosting guide, the only record
|
||||
of how the infrastructure was hand-built, living outside the repo. Q32 was the
|
||||
infinity mark: it was traced from the old site's *loading placeholder*, the
|
||||
source comment said so in as many words — and **two adversarial review passes
|
||||
still could not catch that the shape was wrong**, because the real artwork was
|
||||
not in the repo to compare against. Stating a doubt is not enough when the thing
|
||||
that would resolve it is unreachable. Tracked as R14.
|
||||
|
||||
**A command that did not run is not evidence of absence.** Check that a tool
|
||||
exists before trusting its silence, and read exit status, not just stdout. This
|
||||
project ran `timeout 60 ls "$DRIVE"` four times, got empty output each time, and
|
||||
reported the brand assets unreachable — `timeout` is not installed on macOS, so
|
||||
the command had never executed and the directory was fully readable all along.
|
||||
Empty output from a command that failed to start looks exactly like empty output
|
||||
from a command that found nothing. Same family as *a sweep is a command, not a
|
||||
claim*: the claim must rest on output you actually read, from a command that
|
||||
actually ran.
|
||||
|
||||
**A parent cannot style a child component's root element.** Astro does not pass
|
||||
a parent's scope attribute down, so `<Button class="header-cta" />` compiles the
|
||||
parent's rule to `.header-cta[data-astro-cid-<parent>]` while the rendered `<a>`
|
||||
|
||||
@@ -193,14 +193,17 @@ neutral.
|
||||
3. **Rules:** ADRIC, ADR Chambers, ad hoc.
|
||||
4. Awards — form, reasoning, timing.
|
||||
5. **Credentialing status, stated plainly.** The Q.Arb pathway is in progress;
|
||||
the page says so and describes what is available now versus what follows
|
||||
designation. Honesty here is a differentiator, not a weakness — and
|
||||
misstating it is a conduct problem. **What "available now" consists of is
|
||||
`AGENTS.md` Q36 and is NOT yet in §4** — this line, `03-content-spec.md`, and
|
||||
`07-fees.md` all assert co-arbitration availability off the same unverified
|
||||
premise. Do not write it onto the page until Q36 closes.
|
||||
the page says so. **What is available now is all three forms — sole,
|
||||
party-appointed and co-arbitration** — and `AGENTS.md` §4 Offerings carries a
|
||||
row for each `[verified 2026-08-26 — Pouya]`. The page states that alongside
|
||||
the credentialing stage: Q.Arb commenced August 2026, C.Med-Arb is the
|
||||
endpoint. §4 Offerings: **neither half may be dropped.** Honesty here is a
|
||||
differentiator, not a weakness — and misstating it in either direction is a
|
||||
conduct problem.
|
||||
*(This paragraph read "(co-arbitration, co-arbitration)" until 2026-08-26 —
|
||||
edited without being re-read, which is how the unverified half travelled.)*
|
||||
edited without being re-read — and then carried a caveat against Q36 for
|
||||
several hours after Q36 closed. Both are recorded because the pattern is the
|
||||
same one: an edit that was not re-read against the register.)*
|
||||
6. Fees, booking.
|
||||
|
||||
### `/med-arb/`
|
||||
|
||||
@@ -11,6 +11,12 @@ system that preserves it while fixing what the old build got wrong.
|
||||
- The **palette**: cream, ink, maroon, gold.
|
||||
- The **infinity mark** — SML Company Ltd.'s actual logo, and the metaphor holds:
|
||||
a dispute is a loop, and the work is redrawing the loop into a line.
|
||||
**It is a shaded ribbon, not a stroked curve**: a band of variable width that
|
||||
twists in three dimensions, maroon flowing into champagne, passing over itself
|
||||
at the crossing. Ink bounding box **2668 × 1704 = 1.5657:1**
|
||||
`[verified 2026-08-26 — measured against the master]`. Source of truth:
|
||||
`src/assets/brand/sml-infinity-mark.png`; provenance in
|
||||
`docs/reference/brand-assets.md`.
|
||||
- The **type pairing**: Instrument Serif for display, Geist for text, Geist Mono
|
||||
for eyebrows and labels.
|
||||
- The **editorial register** — generous whitespace, restrained colour, serif
|
||||
@@ -177,8 +183,8 @@ except the reveal of the hero.
|
||||
|
||||
| Component | Notes |
|
||||
|---|---|
|
||||
| `InfinityMark` | Inline SVG, `currentColor`, `aria-hidden` when decorative. Never a PNG |
|
||||
| `SiteHeader` | **Sticky from 64rem (1024 px) up; static below it.** Practice dropdown as CSS-only `<details>`. *Amended 2026-08-26, both halves by measurement:* **(a)** the one-row header has to hold the brand, **seven** nav items and the CTA — Insights is the seventh and arrives on its own at build step 7 — and it does that at 1024 px with 32 px of clearance, not below. Under 64 rem the nav takes its own row and the header measures **137 px** at tablet widths and **185 px** at 320–375 px, which is more of a small viewport than a sticky header is worth, so it scrolls away there. *(This row first said 60 rem and "~115 px". Both were wrong — the threshold moved when the seven-item case was measured, and 115 px was never a height the header took at any width. Corrected against headless-Chrome measurements at thirteen widths.)* **(b)** "Condenses on scroll" is now **a hairline rule and a shadow, not a size change.** A `position: sticky` header stays in normal flow, so its layout box sits at the top of the document whatever the viewport shows; shrinking its padding shortens that box and lifts every page below it — a scroll-linked layout shift on every page, against the CLS < 0.05 budget in `04-seo-spec.md`. Implemented with `animation-timeline: scroll()`, **longhands only** — see the note in the component about what the minifier does to the `animation` shorthand |
|
||||
| `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 |
|
||||
| `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 320–375 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 |
|
||||
| `SectionHeading` | Eyebrow + display heading + optional lede, one measure |
|
||||
|
||||
@@ -28,11 +28,21 @@ detect padding instantly and discount everything after it.
|
||||
practice". The old site's "we" implied a firm that does not exist.
|
||||
- Concrete nouns. *Lien claim. Change order. System Impact Assessment. Model
|
||||
card. Minutes of settlement.* Specificity is the credential.
|
||||
- Name the limits. "Sole-arbitrator appointments follow the Q.Arb designation;
|
||||
co-arbitration work is available now." **The first half traces to §4; the
|
||||
second does not — `AGENTS.md` Q36.** Keep the shape of the sentence, which is
|
||||
the point being made here, and do not publish the second clause until Q36
|
||||
closes. (**No tribunal-secretary work** — D14
|
||||
- Name the limits — but name the *right* ones. This bullet carried the model
|
||||
sentence *"Sole-arbitrator appointments follow the Q.Arb designation;
|
||||
co-arbitration work is available now"* until 2026-08-26. **Both halves were
|
||||
wrong and they were wrong in opposite directions**, which is why it survived
|
||||
two audits: the first half understated (sole-arbitrator appointments are
|
||||
offered **now** and are not gated by Q.Arb — §4 Offerings), and the second was
|
||||
unsourced when written. §4 now carries rows for all three forms.
|
||||
|
||||
The shape of the bullet still stands, so here is a sentence that fits it and
|
||||
clears the register: *"I accept sole, party-appointed and co-arbitration
|
||||
appointments. The Q.Arb designation commenced in August 2026; C.Med-Arb is the
|
||||
endpoint."* The limit being named is the **stage of the arc**, stated plainly —
|
||||
Pouya's instruction is that being open about it is the differentiator, so do
|
||||
not hedge it into vagueness and do not drop it. (**No tribunal-secretary
|
||||
work** — D14
|
||||
removed the rate and bars offering it; see `docs/07-fees.md`.) Precision about
|
||||
what you cannot yet do makes the rest believable.
|
||||
- Plain words over Latin. "Without prejudice" survives because it is a term of
|
||||
|
||||
@@ -104,10 +104,14 @@ All figures **plus HST**.
|
||||
|
||||
### Arbitration
|
||||
|
||||
Available now as co-arbitrator; sole appointments follow the Q.Arb designation
|
||||
— **the co-arbitrator half is `AGENTS.md` Q36 and is not in §4.** Do not publish
|
||||
it on `/fees/` until Q36 closes,
|
||||
commenced August 2026. The page must say so — see `03-content-spec.md`.
|
||||
Sole, party-appointed and co-arbitration appointments are all accepted now —
|
||||
`AGENTS.md` §4 Offerings carries a row for each `[verified 2026-08-26 — Pouya]`.
|
||||
*(This line previously read "sole appointments follow the Q.Arb designation",
|
||||
which understated the offering, and carried a caveat against a since-closed
|
||||
Q36.)* Whatever `/fees/` says about arbitration must state the Q.Arb stage
|
||||
plainly alongside it — §4 Offerings, "neither half may be dropped": the Q.Arb
|
||||
designation commenced August 2026, with C.Med-Arb as the endpoint. See
|
||||
`03-content-spec.md` for the wording.
|
||||
|
||||
| Item | Fee |
|
||||
|---|---|
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
# Brand assets — provenance
|
||||
|
||||
The repository holds the artwork it makes claims about. That is not tidiness: it
|
||||
is `CLAUDE.md`'s rule and `AGENTS.md` R14, and this file exists because the
|
||||
infinity mark was reconstructed wrongly and **two adversarial review passes could
|
||||
not catch it**, since the real artwork was not in the repo to compare against.
|
||||
|
||||
**Every measurement below is `[verified 2026-08-26]`** — computed with `sharp`
|
||||
against the files in this repository, and re-derivable by anyone from the
|
||||
commands given. Nothing here is quoted from an external source.
|
||||
|
||||
## Files
|
||||
|
||||
| File | What it is | Use |
|
||||
|---|---|---|
|
||||
| `src/assets/brand/sml-infinity-mark-master.png` | The mark as supplied: **3000 × 3000, alpha**, mark inset within the canvas | **The master.** Committed so the crop below can be re-derived and checked in-repo, not taken on trust |
|
||||
| `src/assets/brand/sml-infinity-mark.png` | The same mark tight-cropped to its ink bounding box: **2668 × 1704, alpha, 1.5657:1** | **The render source.** `InfinityMark.astro` feeds it to Astro's `<Picture>` |
|
||||
| `src/assets/brand/sml-logo-full.png` | Mark **plus** the "SML Company" wordmark, 3000 × 3000, alpha; ink bbox 2414 × 1440 = 1.676:1 | Not currently rendered. Held for the OG-image template (`docs/04`) and print |
|
||||
| `src/assets/brand/sml-logo-source.svg` | 1500 × 1500 viewBox, **257,278 bytes** | Reference. Faithful, but not what is served — see below |
|
||||
|
||||
## Reproducing the crop, in-repo
|
||||
|
||||
The crop is derived, so it is re-derivable — and now from a file that is here,
|
||||
which is the whole point of R14. Scan the master for the first and last pixel
|
||||
that is neither transparent (`alpha < 24`) nor near-white (`r,g,b > 243`):
|
||||
|
||||
```
|
||||
ink bbox of sml-infinity-mark-master.png -> 2668 x 1704 at (159, 646)
|
||||
sharp(master).extract({ left: 159, top: 646, width: 2668, height: 1704 })
|
||||
```
|
||||
|
||||
Crop to that box and the file's own aspect ratio becomes the mark's, so layout
|
||||
can be tuned against the asset directly rather than against a number written
|
||||
down beside it. `InfinityMark.astro` pins `aspect-ratio: 667 / 426`, which is
|
||||
`2668 / 1704` reduced — **1.56573**.
|
||||
|
||||
## Why the SVG is held but not served
|
||||
|
||||
It renders **faithfully**. Rasterised at 8333 px it reproduces the master
|
||||
exactly, at the same **1.566:1**. It is not bad artwork, and an earlier version
|
||||
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×.**
|
||||
- **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
|
||||
project replaces.
|
||||
- 10 `<linearGradient>` carrying **1,225 `<stop>`** elements, 64 `<path>`,
|
||||
59 `<clipPath>`, 23 `<mask>`, 1 `<filter>`. Expensive to rasterise.
|
||||
|
||||
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:
|
||||
|
||||
| | 1× (64 px) | 2× (128 px) | 3× (192 px) |
|
||||
|---|---|---|---|
|
||||
| AVIF | **1,720 B** | **3,063 B** | **4,843 B** |
|
||||
| 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.
|
||||
|
||||
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** —
|
||||
which any client without AVIF or WebP support would actually download.
|
||||
|
||||
## The colours are the artwork's, not the palette's
|
||||
|
||||
`tokens.css` is not involved. The ribbon carries its own gradient and it is
|
||||
close to but not identical with `--maroon` `#5a1a1c` and `--gold` `#c9a876`.
|
||||
Do not "correct" the artwork toward the tokens, and do not derive tokens from
|
||||
the artwork — D7 keeps the palette *and* the mark, as they are.
|
||||
|
||||
## Where these came from
|
||||
|
||||
Supplied by Pouya. `sml-logo-source.svg` was added by him directly to the repo;
|
||||
the PNGs were taken from the `smlcompany.ca` Google Drive, under `SML/Designs/`
|
||||
and `Research/Law/ADR Personal Branding Project/`. **The Drive copies are not the
|
||||
record — these files are.** That is the point of R14: an artefact that lives only
|
||||
in Drive cannot be compared against a claim by any reviewer, which is exactly how
|
||||
the traced mark survived two review passes.
|
||||
|
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 4.7 KiB |
@@ -1,17 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-232 -232 464 464">
|
||||
<!-- The SML infinity mark. Geometry and colours match
|
||||
src/components/InfinityMark.astro — see the provenance note there.
|
||||
Kept as its own file rather than imported: the browser requests a favicon
|
||||
at a fixed path before any stylesheet resolves.
|
||||
|
||||
SQUARE viewBox, deliberately. The mark is 11:7; browsers render an SVG
|
||||
favicon into a square slot with xMidYMid meet, so an 11:7 viewBox
|
||||
letterboxes — the cream ground becomes a floating stripe with transparent
|
||||
bars above and below, which on a dark tab strip reads as a graphical
|
||||
artefact rather than a logo. The square ground fills the slot. -->
|
||||
<rect x="-232" y="-232" width="464" height="464" fill="#faf7f2"/>
|
||||
<g fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M -200 0 C -200 -160, 0 -160, 0 0 C 0 160, 200 160, 200 0 C 200 -160, 0 -160, 0 0 C 0 160, -200 160, -200 0 Z" stroke="#5a1a1c" stroke-width="34"/>
|
||||
<path d="M -200 0 C -200 -160, 0 -160, 0 0 C 0 160, 200 160, 200 0 C 200 -160, 0 -160, 0 0 C 0 160, -200 160, -200 0 Z" stroke="#c9a876" stroke-width="7" opacity="0.7"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 586 KiB |
|
After Width: | Height: | Size: 251 KiB |
@@ -1,29 +1,53 @@
|
||||
---
|
||||
/**
|
||||
* The SML infinity mark. AGENTS.md D7 keeps it unchanged; docs/02 requires it
|
||||
* be inline SVG rather than a raster. (The "~470 KB PNG" this comment used to
|
||||
* cite had no source anywhere in the repo — see AGENTS.md Q34. The mark is
|
||||
* geometry, which is reason enough without a number.)
|
||||
* The SML infinity mark.
|
||||
*
|
||||
* PROVENANCE — read before editing the path. This geometry is lifted verbatim
|
||||
* from the deployed site's own loading-thumbnail SVG (the element it labels
|
||||
* `smlMark`), fetched from https://adr.smlcompany.ca/ on 2026-08-26. The only
|
||||
* change is arithmetic: the source drew the path offset by `translate(60 0)`
|
||||
* inside a 1200×800 frame, and that offset is folded into the coordinates here
|
||||
* so the curve is symmetric about the origin. Stroke widths (28 outer, 6 inner)
|
||||
* and the 0.7 inner opacity are the source's.
|
||||
* ⚠️ DELIBERATE, TEMPORARY EXCEPTION TO docs/02's "inline SVG, never a PNG".
|
||||
* Tracked as AGENTS.md Q38, with a standing reminder (R13) so it cannot become
|
||||
* permanent by neglect. Read both before changing this file.
|
||||
*
|
||||
* It is therefore SML's own artwork, not a redrawing — but it came from a
|
||||
* loading placeholder, which is not necessarily the canonical file. See
|
||||
* AGENTS.md Q32.
|
||||
* WHY A RASTER — and the reason is PAYLOAD, not fidelity. The mark is not a
|
||||
* stroked curve; it is a shaded ribbon of variable width that twists in three
|
||||
* dimensions, maroon flowing into champagne, passing over itself at the
|
||||
* crossing. That is gradient-mesh artwork, not the flat vector paths docs/02
|
||||
* assumes.
|
||||
*
|
||||
* Two-tone by design: the outer stroke takes `currentColor` so the mark sits
|
||||
* correctly on cream, ink, and maroon; the inner hairline is gold. Gold as an
|
||||
* icon stroke is explicitly allowed — the rule it must never break is gold as
|
||||
* TEXT on cream, which measures 2.10:1 (docs/02).
|
||||
* We do hold an SVG — src/assets/brand/sml-logo-source.svg — and **it renders
|
||||
* faithfully**: rasterised at 8333px it reproduces the master exactly, at the
|
||||
* same 1.566:1 [verified 2026-08-26]. An earlier version of this comment implied
|
||||
* it was inadequate artwork. It is not; that was unfair and is corrected here.
|
||||
* What rules it out is weight and composition: 257,278 bytes against 3,063 for
|
||||
* the AVIF a Retina browser takes — 84× — and SEVEN embedded base64 PNGs plus
|
||||
* a 1,225-stop gradient mesh, so inlining it would breach CLAUDE.md's rule
|
||||
* against base64-inlining images. The exception ends when a vector master lands
|
||||
* that is both faithful AND light.
|
||||
*
|
||||
* WHAT THIS REPLACES, and why it had to go. Until 2026-08-26 this component
|
||||
* drew a hand-traced cubic path lifted from the old site's loading thumbnail.
|
||||
* Pouya compared it against the master and it was wrong in three ways; two are
|
||||
* reproducible from the path itself:
|
||||
*
|
||||
* 1. TANGENT, NOT CROSSING. All four branches met the origin at exactly 90°,
|
||||
* so the loops were mutually tangent on a vertical line rather than
|
||||
* crossing. At stroke-width 28 that renders as two circles kissing — the
|
||||
* one thing an infinity mark must not be. Verified by computing the
|
||||
* tangent vector of every segment at the origin.
|
||||
* 2. WRONG PROPORTION. The real mark's ink bounding box is 2668 × 1704 =
|
||||
* 1.5657:1. The traced path measured 1.667:1 ink / 1.597:1 stroked.
|
||||
* 3. FLAT. Two uniform strokes standing in for a shaded ribbon.
|
||||
*
|
||||
* It is deleted rather than kept as a fallback, on Pouya's instruction: a wrong
|
||||
* mark that renders is worse than a missing one, because it stops looking wrong.
|
||||
*
|
||||
* SOURCE OF TRUTH. src/assets/brand/sml-infinity-mark.png is the master tight-
|
||||
* cropped to its ink bounding box, so the file's aspect ratio IS the mark's and
|
||||
* layout can be tuned to it directly. Provenance: docs/reference/brand-assets.md.
|
||||
*/
|
||||
import { Picture } from 'astro:assets';
|
||||
import mark from '../assets/brand/sml-infinity-mark.png';
|
||||
|
||||
interface Props {
|
||||
/** Rendered height. Width follows the 11:7 aspect ratio. */
|
||||
/** Rendered height. Width follows 1.5657:1. */
|
||||
size?: string;
|
||||
/** Accessible name. Omit for decorative use — the default. */
|
||||
label?: string;
|
||||
@@ -31,36 +55,64 @@ interface Props {
|
||||
}
|
||||
|
||||
const { size = '1.75rem', label, class: className } = Astro.props;
|
||||
const decorative = label === undefined;
|
||||
|
||||
const PATH = `M -200 0
|
||||
C -200 -160, 0 -160, 0 0
|
||||
C 0 160, 200 160, 200 0
|
||||
C 200 -160, 0 -160, 0 0
|
||||
C 0 160, -200 160, -200 0 Z`;
|
||||
// Sized to the largest render that SURVIVES, which is the footer at 2.25rem =
|
||||
// 56.4 CSS px wide. The first attempt used 320px, justified by the 4rem sample
|
||||
// on the proof sheet — a page step 2 deletes — and then stacked densities on
|
||||
// top, so the ladder double-counted its own headroom and every Retina device
|
||||
// pulled a 640px image into a 56px slot.
|
||||
//
|
||||
// PASSING A WIDTH EXPLICITLY IS STILL THE POINT. Without it Astro emits the
|
||||
// untouched 2668px master as the <img src> fallback: 1,146,406 bytes, which any
|
||||
// client without AVIF or WebP support would actually download, sitting in dist
|
||||
// looking like an optimisation had happened.
|
||||
const INTRINSIC_WIDTH = 64;
|
||||
---
|
||||
|
||||
<svg
|
||||
<Picture
|
||||
src={mark}
|
||||
width={INTRINSIC_WIDTH}
|
||||
densities={[1, 2, 3]}
|
||||
formats={['avif', 'webp']}
|
||||
fallbackFormat="png"
|
||||
alt={label ?? ''}
|
||||
loading="eager"
|
||||
decoding="async"
|
||||
class:list={['mark', className]}
|
||||
viewBox="-220 -140 440 280"
|
||||
fill="none"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
role={decorative ? undefined : 'img'}
|
||||
aria-hidden={decorative ? 'true' : undefined}
|
||||
aria-label={label}
|
||||
focusable="false"
|
||||
style={`block-size:${size}`}
|
||||
>
|
||||
<path d={PATH} stroke="currentColor" stroke-width="28"></path>
|
||||
<path d={PATH} stroke="var(--rule)" stroke-width="6" opacity="0.7"></path>
|
||||
</svg>
|
||||
pictureAttributes={{ style: `block-size:${size}` }}
|
||||
/>
|
||||
|
||||
<style>
|
||||
.mark {
|
||||
/* 440 : 280 — the viewBox. Height is set inline; width follows. */
|
||||
aspect-ratio: 11 / 7;
|
||||
inline-size: auto;
|
||||
/* THE FLEX ITEM IS THE <picture>, NOT THE <img>.
|
||||
`class:list` lands on the <img>, which Astro's <Picture> wraps in a
|
||||
<picture> — and that wrapper is what `.brand`'s flex layout actually sizes.
|
||||
So `flex: none` on .mark reached the wrong box entirely and the mark was
|
||||
free to be squeezed: measured 28.52 x 32 at 1024px with seven nav items,
|
||||
against a correct 50.09 x 32 — an aspect of 0.891 where it should be 1.5657.
|
||||
|
||||
This is the SAME defect CLAUDE.md already records for <Button> in
|
||||
SiteHeader — a parent cannot style a child component's root — reintroduced
|
||||
inside the fix for it, one round later. The bare `picture` selector below is
|
||||
scoped by Astro's cid, which the emitted markup does carry, and the height
|
||||
now goes on the wrapper via `pictureAttributes` rather than on the image.
|
||||
|
||||
Worse than the bug: the page-level overflow check passed throughout, because
|
||||
the brand block absorbed the deficit by crushing the logo. "0 overflow at
|
||||
every width" was true and misleading — it measured the document, not the
|
||||
elements inside it. The harness now asserts the rendered aspect ratio. */
|
||||
picture {
|
||||
display: block;
|
||||
flex: none;
|
||||
aspect-ratio: 667 / 426;
|
||||
inline-size: auto;
|
||||
}
|
||||
.mark {
|
||||
/* 2668 / 1704 reduced — the master's exact ink bounding box, so the box the
|
||||
layout reserves is the shape that fills it. */
|
||||
inline-size: 100%;
|
||||
block-size: 100%;
|
||||
/* Belt and braces: if anything ever squeezes the box again, the artwork
|
||||
letterboxes instead of distorting. */
|
||||
object-fit: contain;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -27,6 +27,17 @@ import InfinityMark from './InfinityMark.astro';
|
||||
// deployed, which is the same cadence everything else here updates on.
|
||||
const year = new Date().getFullYear();
|
||||
|
||||
// Med-Arb was filtered out of this column for a few hours on 2026-08-26 and is
|
||||
// RESTORED, because removing it was wrong on three counts and `adversarial-
|
||||
// reviewer` caught all three. (1) docs/01 specifies this footer as the FULL
|
||||
// sitemap and lists /med-arb/ as deliberately out of the primary nav, "linked
|
||||
// contextually" — so dropping it here left the page with no site-wide link at
|
||||
// all, on a project whose entire premise is crawlability. (2) The label names a
|
||||
// PAGE, and docs/01 frames that page around the C.Med-Arb arc rather than as a
|
||||
// present offering, so listing it is not the §4 inference it looked like.
|
||||
// (3) It settled half of Q35 unilaterally while the other half — Energy and
|
||||
// Shareholder — stayed in both nav and footer, and the record claimed no
|
||||
// unilateral action had been taken. Both halves of Q35 go to Pouya together.
|
||||
const processLinks = [
|
||||
{ href: '/mediation/', label: 'Mediation' },
|
||||
{ href: '/arbitration/', label: 'Arbitration' },
|
||||
@@ -48,8 +59,19 @@ const aboutLinks = [
|
||||
<InfinityMark size="2.25rem" />
|
||||
<span class="footer-brand-name">{SITE.name}</span>
|
||||
</a>
|
||||
{
|
||||
/* The designation strip carries the credentialing STAGE, not just the
|
||||
held designation, and that is a §4 Offerings condition rather than a
|
||||
flourish. The masthead says "Mediation · Arbitration · Toronto" on
|
||||
every page; §4 permits the arbitration half on the condition that the
|
||||
site "makes the first while stating the second plainly", and
|
||||
"neither half may be dropped". Before this line rendered
|
||||
CREDENTIALS.inProgress, that condition was unmet on every page that
|
||||
ships — the constant existed in site.ts and was rendered nowhere.
|
||||
Q.Arb reads as commenced, never as held (§4). */
|
||||
}
|
||||
<p class="footer-designation">
|
||||
{CREDENTIALS.designations.join(' · ')}
|
||||
{[...CREDENTIALS.designations, ...CREDENTIALS.inProgress].join(' · ')}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -38,7 +38,10 @@ const inSection = (href: string) => path === href || path.startsWith(href);
|
||||
<div class="wrap header-inner">
|
||||
<a class="brand" href="/">
|
||||
<InfinityMark size="2rem" />
|
||||
<span class="brand-name">{SITE.name}</span>
|
||||
<span class="brand-text">
|
||||
<span class="brand-name">{SITE.name}</span>
|
||||
<span class="eyebrow brand-tagline">{SITE.tagline}</span>
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="nav" aria-label="Primary">
|
||||
@@ -131,22 +134,44 @@ const inSection = (href: string) => path === href || path.startsWith(href);
|
||||
|
||||
/* --- Brand --------------------------------------------------------------- */
|
||||
|
||||
/* No tagline under the name. `SITE.tagline` reads "Mediation · Arbitration ·
|
||||
Toronto", and docs/01 specifies that string as the HOME HERO EYEBROW —
|
||||
nothing asks for a header tagline. Set under the name on every page it
|
||||
stops being page copy and becomes a designation strip, with `Arbitration`
|
||||
unqualified beside a name. AGENTS.md §4 records Q.Arb as commenced August
|
||||
2026 and requires it never read as held. See AGENTS.md Q33. */
|
||||
/* The tagline is BACK, and the reasoning is worth keeping rather than just
|
||||
the outcome. It was removed on 2026-08-26 because `Arbitration` under
|
||||
Pouya's name read as a held capability, and §4 records Q.Arb as merely
|
||||
commenced. Q33 answered that the same day, and the premise was wrong:
|
||||
ADR designations are voluntary credentials, not licences. Anyone may be
|
||||
appointed an arbitrator in Ontario, so the constraint was always
|
||||
positional, never legal — Pouya accepts sole, party-appointed and
|
||||
co-arbitration work today. See §4 Offerings, which is where the register
|
||||
now draws the line between a CREDENTIAL claim and an OFFERING. */
|
||||
.brand {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-3);
|
||||
/* 44px floor — this is the tap target that goes home. */
|
||||
min-block-size: 44px;
|
||||
/* 48px, not 44. Still clears the touch floor, and it reserves the height the
|
||||
two-line brand takes at >=76rem so the sticky header is one constant 81px
|
||||
across every width where it is sticky — which is what --header-h and
|
||||
scroll-padding-top are keyed to. One number instead of two bands. */
|
||||
min-block-size: 48px;
|
||||
color: var(--accent);
|
||||
text-decoration: none;
|
||||
margin-inline-end: auto;
|
||||
}
|
||||
.brand-text {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
}
|
||||
/* The tagline appears only where there is room for it — see the 76rem block.
|
||||
Measured: at 11px with 0.18em tracking the string is ~285px wide, and
|
||||
restoring it under the name pushed the one-row header past its content box
|
||||
by 18px at 1024 with six items and 84px with seven. The brand name carries
|
||||
the identity on its own; the tagline is a flourish, and `/` opens with the
|
||||
same words as the hero eyebrow (docs/01). */
|
||||
.brand-tagline {
|
||||
display: none;
|
||||
font-size: 0.6875rem; /* 11px — the eyebrow floor in docs/02 */
|
||||
white-space: nowrap;
|
||||
}
|
||||
.brand-name {
|
||||
font-family: var(--font-serif);
|
||||
font-size: var(--text-xl);
|
||||
@@ -255,7 +280,7 @@ const inSection = (href: string) => path === href || path.startsWith(href);
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
/* Nav takes its own row below 64rem. No `order` anywhere: reordering flex
|
||||
/* Nav takes its own row below 66rem. No `order` anywhere: reordering flex
|
||||
items moved the CTA onto row one visually while it stayed last in the DOM,
|
||||
so a keyboard user tabbed off the brand, down through all 13 nav links
|
||||
including the practice panel, and back UP to the CTA. WCAG 2.4.3, and
|
||||
@@ -267,17 +292,17 @@ const inSection = (href: string) => path === href || path.startsWith(href);
|
||||
/* `white-space` INHERITS into the Button, which is how a parent reaches a
|
||||
child component's root at all here — see the note on why this wrapper
|
||||
exists. Without it the label wrapped to two lines, standing the header up
|
||||
at 93px instead of 77px. `flex: none` stops the row squeezing it. */
|
||||
taller than it needed to be. `flex: none` stops the row squeezing it. */
|
||||
.header-cta {
|
||||
flex: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
/* Below 64rem the CTA is dropped, not shrunk — and that is the whole reason
|
||||
/* Below 66rem the CTA is dropped, not shrunk — and that is the whole reason
|
||||
no `order` is needed. Wherever the nav has its own row, `/contact/` is
|
||||
already on it, so the button is a duplicate link paying for itself in
|
||||
header height. It was previously dropped only below 40rem and reordered in
|
||||
between, which is what put focus order out of step with visual order. */
|
||||
@media (max-width: 63.999rem) {
|
||||
@media (max-width: 65.999rem) {
|
||||
.header-cta {
|
||||
display: none;
|
||||
}
|
||||
@@ -285,12 +310,19 @@ const inSection = (href: string) => path === href || path.startsWith(href);
|
||||
|
||||
/* --- Desktop ------------------------------------------------------------- */
|
||||
|
||||
/* --- Desktop: 64rem (1024px) ---------------------------------------------
|
||||
The threshold is measured, not conventional. The one-row header has to hold
|
||||
the brand, seven nav items and the CTA side by side, and **at 1024px it
|
||||
does, with 32px of clearance between the nav and the CTA — measured in
|
||||
headless Chrome with a seventh nav item injected.** Below that it does not,
|
||||
which is why the nav takes its own row there.
|
||||
/* --- Desktop: 66rem (1024px) ---------------------------------------------
|
||||
The threshold is measured, and the first measurement was WRONG — worth
|
||||
recording, because of how it was wrong. It read "32px of clearance at
|
||||
1024px". That 32px was `.header-inner`'s own `column-gap`, i.e. exactly
|
||||
zero slack, mistaken for headroom. The true max-content sum at seven items
|
||||
is 48 + 184.3 brand + 24 margin + 32 gap + 480.1 nav + 32 gap + 197.2 CTA
|
||||
+ 48 = **1045.6px — 21.6px OVER a 1024px viewport.** Nothing overflowed
|
||||
only because flexbox shrank the brand and crushed the mark inside it.
|
||||
|
||||
Binary search on the built page with a seventh item gives the real
|
||||
thresholds: the row fits from **1047px**, and the tagline from **1207px**.
|
||||
66rem (1056) and 76rem (1216) are the clean tokens above each. Below 66rem
|
||||
the nav takes its own row.
|
||||
|
||||
Insights is the seventh item and arrives by itself at build step 7
|
||||
(SiteHeader gates it on the collection), so a breakpoint verified only
|
||||
@@ -305,7 +337,7 @@ const inSection = (href: string) => path === href || path.startsWith(href);
|
||||
Sticky only from here up, too. Below this the nav takes a second row and
|
||||
the header stands at 137px, which is more of a small viewport than a
|
||||
sticky header is worth. Deviation from docs/02 "Sticky"; recorded there. */
|
||||
@media (min-width: 64rem) {
|
||||
@media (min-width: 66rem) {
|
||||
.site-header {
|
||||
position: sticky;
|
||||
inset-block-start: 0;
|
||||
@@ -321,11 +353,11 @@ const inSection = (href: string) => path === href || path.startsWith(href);
|
||||
}
|
||||
/* nowrap, and flex:none so the nav is never squeezed below its content
|
||||
width. Measured before this: at 960-1250px the seven-item nav broke to
|
||||
two rows and the header stood at 142px instead of 80px. */
|
||||
two rows and the header stood at 141px instead of 81px. */
|
||||
.nav-list {
|
||||
flex-wrap: nowrap;
|
||||
flex: none;
|
||||
/* 16px from 64rem, widening to 24px at 75rem where there is room for it.
|
||||
/* 16px from 66rem, widening to 24px at 76rem where there is room for it.
|
||||
Measured with seven items at every width from 1024px up. */
|
||||
column-gap: var(--space-4);
|
||||
}
|
||||
@@ -372,14 +404,24 @@ const inSection = (href: string) => path === href || path.startsWith(href);
|
||||
you scroll off the top. That is a smaller effect than docs/02's "condenses
|
||||
on scroll", and docs/02 has been amended to say so and why. */
|
||||
|
||||
@media (min-width: 75rem) {
|
||||
/* The tagline arrives at 76rem. The nav gap does NOT widen here as well:
|
||||
measured, doing both at one breakpoint put the row 4px past its content box
|
||||
at exactly 1200px with seven items. Two things growing at the same width is
|
||||
how a breakpoint gets over-subscribed. */
|
||||
@media (min-width: 76rem) {
|
||||
.brand-tagline {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 80rem) {
|
||||
.nav-list {
|
||||
column-gap: var(--space-5);
|
||||
}
|
||||
}
|
||||
|
||||
@supports (animation-timeline: scroll()) {
|
||||
@media (min-width: 64rem) and (prefers-reduced-motion: no-preference) {
|
||||
@media (min-width: 66rem) and (prefers-reduced-motion: no-preference) {
|
||||
.site-header {
|
||||
animation-name: header-lift;
|
||||
animation-duration: 1ms;
|
||||
|
||||
@@ -26,11 +26,12 @@ const lang = SITE.locale.replace('_', '-');
|
||||
<SEO {...Astro.props} />
|
||||
|
||||
{
|
||||
/* .ico first for clients that ignore the SVG, and because some crawlers
|
||||
request /favicon.ico at the root regardless of what is declared here. */
|
||||
/* No SVG favicon. The mark is a shaded ribbon, not flat vector paths, so
|
||||
there is no honest SVG of it to serve — see InfinityMark.astro and
|
||||
AGENTS.md Q38. The .ico carries 16/32/48, and is what crawlers request
|
||||
at the root regardless of what is declared here. */
|
||||
}
|
||||
<link rel="icon" href="/favicon.ico" sizes="48x48" />
|
||||
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
|
||||
<link rel="icon" href="/favicon.ico" sizes="16x16 32x32 48x48" />
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
||||
|
||||
{
|
||||
|
||||
@@ -113,16 +113,16 @@
|
||||
html {
|
||||
-webkit-text-size-adjust: 100%;
|
||||
scroll-behavior: smooth;
|
||||
/* No offset by default: below 64rem the header is not sticky, so nothing is
|
||||
/* No offset by default: below 66rem the header is not sticky, so nothing is
|
||||
covering the target. See the media query below. */
|
||||
scroll-padding-top: var(--space-4);
|
||||
}
|
||||
|
||||
/* The header is sticky from 64rem up, and `scroll-padding-top` has to clear it
|
||||
/* 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. */
|
||||
@media (min-width: 64rem) {
|
||||
@media (min-width: 66rem) {
|
||||
html {
|
||||
scroll-padding-top: calc(var(--header-h) + var(--space-4));
|
||||
}
|
||||
|
||||
@@ -112,13 +112,16 @@
|
||||
|
||||
/* --- Layout ------------------------------------------------------------ */
|
||||
|
||||
/* Sticky-header height at >= 64rem, where the header IS sticky. global.css
|
||||
/* Sticky-header height at >= 66rem, where the header IS sticky. global.css
|
||||
drives `scroll-padding-top` off this, so the skip link does not drop the
|
||||
reader behind the header. If SiteHeader's padding or nav sizing changes,
|
||||
re-measure and change this with it — one fact living in two files.
|
||||
[measured 2026-08-26 — headless Chrome at 1024/1100/1280/1440px, with six
|
||||
nav items and with a seventh injected: 77px at every one] */
|
||||
--header-h: 4.8125rem; /* 77 — measured, not chosen */
|
||||
nav items and with a seventh injected. 81px at every one: 32 padding + 48
|
||||
reserved brand block + the 1px bottom border, which is easy to forget and
|
||||
is why this is measured rather than added up. The brand reserves 48px so
|
||||
the height does not change when the tagline appears at 76rem] */
|
||||
--header-h: 5.0625rem; /* 81 — measured, not chosen */
|
||||
|
||||
--width-content: 80rem; /* 1280 */
|
||||
--width-wide: 90rem; /* 1440 */
|
||||
|
||||