--- /** * `/` — Home. Build step 2 (docs/01 §Build order): "proves the design system * end to end." * * JOB (docs/01 §`/`): "establish the unusual stack in under ten seconds, and * route each of the four audiences to its surface." Leans in-house counsel. * * SECTIONS, against docs/01's outline: * 1 Hero · 2 Credential row · 3 The approach · 4 Two practices · * 5 Practice areas · 6 Process preview · 7 Latest insights · 8 Contact band * * SECTION 7 IS BUILT AS OF STEP 7b AND RENDERS NOTHING TODAY. The markup is * behind `latest.length > 0`, so with no published article no card, no heading * and no link is emitted. D9 means the flip is Pouya's — the schema refuses * `draft: false` without `reviewedByPouya: true` — and `SiteHeader` gates the * Insights NAV item on the same predicate at two pieces. Do not "finish" this by * hardcoding a placeholder card. * * ⚠️ **THE STEP-2 REASONING FOR DEFERRING THIS SECTION WAS THAT AN UNRENDERED * COMPONENT STILL SHIPS ITS CSS. THAT IS TRUE, AND IT IS NOW MEASURED RATHER * THAN ARGUED:** importing `ArticleCard` puts **10 rules, 1,496 bytes, 4.4% of * `dist/index.html`** into this page for a block that renders nothing. Astro * bundles a component's scoped styles on IMPORT, not on render, and * `inlineStylesheets: 'auto'` inlines them here. * * It is kept anyway, and the reason is also a measurement: `npm run lighthouse -- /` * returns **performance 99, LCP 2.03 s, CLS 0.000 — identical before and after * the 1,498-byte growth.** So the cost is real in bytes and absent in the metric, * on the one page already at `docs/04`'s LCP budget. The dead weight clears * itself the moment an article publishes, which is the same event that makes the * section visible. * * EVERY FACTUAL CLAIM ON THIS PAGE TRACES TO AGENTS.md §4, and the ones that * carry risk are constants from src/data/site.ts rather than typed here. * Notably: arbitration is scoped to COMMERCIAL matters throughout (§4 * Offerings, Q39 2026-08-27), the held designations come from `CREDENTIALS`, * and nothing claims or implies licensure (D13). */ import { Picture, getImage } from 'astro:assets'; import BaseLayout from '../layouts/BaseLayout.astro'; import Button from '../components/Button.astro'; import ContactBand from '../components/ContactBand.astro'; import CredentialRow from '../components/CredentialRow.astro'; import Eyebrow from '../components/Eyebrow.astro'; import InfinityMark from '../components/InfinityMark.astro'; import PracticeCard from '../components/PracticeCard.astro'; import ProcessStep from '../components/ProcessStep.astro'; import ArticleCard from '../components/ArticleCard.astro'; import SectionHeading from '../components/SectionHeading.astro'; import portrait from '../assets/pouya-lajevardi.jpg'; import ogDefault from '../assets/og-portrait.jpg'; import { getCollection } from 'astro:content'; import { homeGraph } from '../data/schema'; import { ASYMMETRY_LINE, CREDENTIAL_ROW, CREDENTIAL_ROW_ARB, PRACTICE_AREAS, PORTRAIT, PROCESS, PROCESS_FRAMING, SITE, } from '../data/site'; /** * FOUR SLOTS, NOT THREE, and it is now a §4 substitution-principle choice * rather than a condition. * * docs/01 §`/` item 2 says "Three slots"; §4's substitution principle * authorises `Q.Arb` as a fourth "where one exists", and this layout has one. * It was MANDATORY here until 2026-08-29 under §4's paired-disclosure * condition, because the page says *arbitrator* in its second sentence and the * stage had to appear beside the offering. Q.Arb is held and that condition is * dissolved; the slot stays because a fourth held credential earns its place, * not because anything requires it. */ const credentials = [...CREDENTIAL_ROW, CREDENTIAL_ROW_ARB]; /** * docs/04 lists `image` on the Person node. This generates it with EXACTLY the * transform SEO.astro already applies to the same source — jpeg, 1200 x 630 — * so Astro's asset cache returns the same hashed file rather than emitting a * second copy for the crawler's benefit. Verified by asset count: dist holds * one `og-portrait.*.jpeg` with this line present, not two. * * JPEG on purpose, for the same reason SEO.astro uses it: link-preview and * structured-data consumers are not browsers and several still do not decode * WebP, let alone AVIF. */ const ldImage = await getImage({ src: ogDefault, format: 'jpeg', width: 1200, height: 630, }); const graph = homeGraph(new URL(ldImage.src, Astro.site).href); /* THE THREE MOST RECENT, and the same `!data.draft` predicate the rest of the site uses — see the `draft` field in `src/content.config.ts`. Sorted here rather than trusting the loader's order: `glob()` returns files in directory order, which is alphabetical by filename and has nothing to do with date. */ const latest = (await getCollection('insights', ({ data }) => !data.draft)) .sort((a, b) => b.data.publishDate.getTime() - a.data.publishDate.getTime()) .slice(0, 3); --- {/* ---- 1. Hero ------------------------------------------------------- */}
{ /* docs/01 specifies this exact string as the hero eyebrow. The masthead no longer repeats it on this page — see SiteHeader. */ } {SITE.tagline} { /* docs/03 §Approved headline options, option 1 — the recommended one. Option 3 is struck there: "every side" asserts having acted as party, as counsel and as neutral, and §4 verifies one of the three. The italic is the single flourish docs/02 allows in a headline. */ }

A mediator who reads the contract, the code, and the room.

{ /* THREE CONSTRAINTS ON THIS PARAGRAPH. Trimmed to them under D19; the history is in the `AGENTS.md` Change Log. 1. ARBITRATION STAYS OFFERING-SHAPED. §4 verifies that he ACCEPTS arbitral appointments and separately verifies completed sole mediations; there is no completed-arbitration row. A present indicative beside "mediate" invites a track record §4 does not hold. 2. NO COMPARATIVE CLAIM ABOUT OTHER NEUTRALS — Q41(b), closed 2026-08-27, and struck from `docs/03`'s positioning statement too. 3. THE TAIL IS POUYA'S WORDING, VERBATIM: *"built for disputes that turn on the contract, the code, and the engineering documents"*. Its echo of the `

`'s triad is deliberate. */ }

I mediate from Toronto, and I accept commercial arbitration appointments. I also practise as a machine-learning and infrastructure engineer, so the matters I take are the ones that turn on the contract, the code, and the engineering documents: the change order, the model card, the System Impact Assessment, and the regulatory overlay around them.

{ /* `widths` + `sizes` rather than `densities`: the portrait is fluid, and a density ladder would size it from one assumed CSS width. ⚠️ THE OLD CEILING ARGUMENT WAS WRONG, AND IT WAS WRONG BY IGNORING THE RANGE WHERE THIS IMAGE IS WIDEST. It read: "The largest real render is ~476px (content 1280 - 96 gutter - 64 gap, x 0.425), so 960 is the 2x ceiling." That arithmetic describes the TWO-COLUMN layout, which only engages at 66rem. Below 66rem the hero is a single column and the portrait is the full content width. Measured, both pages: viewport slot DPR-2 needs picked result 640 592 1184 760/960 1.23-1.56x upscale 768 672 1344 960 1.40x 900 804 1608 960 1.68x 1024 928 1856 960 1.93x At 768/DPR-1 a 760w file EXISTS and is not chosen, so part of the loss was purely the wrong `sizes` (60vw declared against a ~88vw slot). Reconfirmed with the HTTP cache cleared — an earlier probe reported a 2.81x OVERSIZED fetch at 390/DPR-1 which was a cache artefact, not a defect. TWO FIXES, BOTH REQUIRED. (1) `.hero-portrait` is capped at 30rem in the single-column range, so the widest real slot is 480 CSS px everywhere — which makes 960 exactly right for DPR 2 rather than accidentally short. (2) A 1440 rung, because 480 x 3 = 1440 and the desktop slot at DPR 3 already needed 1287-1428; the ≥66rem range was upscaling ~1.34-1.49x at DPR 3 before this and nobody had measured it. The master is 1600, so 1440 exists. THE CAP CHANGES HOW THIS PAGE LOOKS between 640px and 1055px — the portrait was 592-928px wide there and is now 480. That is a visible design change to a reviewed page, made on payload grounds; raising the cap is a one-line change but the ladder has to grow with it. `width` AND `height` ARE PASSED ALONGSIDE `widths`, AND THAT IS NOT REDUNDANT. With `widths` alone, Astro emits the UNTOUCHED 1600px master as the fallback — measured 254,626 bytes sitting in dist as the declared fallback for a 476px slot. Passing width/height pins it to the 960 variant instead (78,665 B), and the 1600px file stops being generated at all. Same defect InfinityMark's comment records for a missing `width`, in the one shape that survives passing `widths`. Verified by reading the emitted `src` attribute and that file's real dimensions — not the build log, which reported "before: 349kB" for every variant either way. What a browser actually takes is the AVIF: 5.6 / 7.3 / 11.1 / 14.8 / 21.5 kB across the first five widths [measured 2026-08-27]; 1080 and 1440 are added 2026-08-28 for DPR 3 (26.6 / 48.8 kB). AND THE 1440 RUNG OVERSHOT, SO 1080 EXISTS TO CORRECT IT. Adding 1440 for DPR 3 removed a 1.07x upscale at 390/DPR3 and replaced it with a **48,799 B fetch where the old one was 21,526 B** — +27 KB on a phone, to fix a 7% softness nobody can see. A browser takes the smallest candidate at or above what it needs, and with no rung between 960 and 1440 the only choices were "slightly soft" or "+27 KB". 1080 makes 1026 (390 x DPR 3) exact and cheap. This was a defect in the fix for the defect above, found by measuring the fix rather than the source. AND 1080 ALONE MISSED THE TWO LARGEST CURRENT PHONES, WHICH MAKES THIS THE THIRD ITERATION OF THIS LADDER. 1080 was tuned to 390 CSS px x DPR 3 (= 1026), and `sizes` resolves to `calc(100vw - 3rem)` up to 528px, so every phone wider than 390 overshoots to the next rung: iPhone 14 Plus (428@3, needs 1140) and 15/16 Pro Max (430@3, needs 1146) both took **1440 — 48,799 B**, against 27,594 for the device the rung was tuned for. +21,205 B, 13% of page weight. A 1200 rung closes it at 1.05x. Measured after: no rung more than 1.06x oversized on the phone axis, and still no upscaling anywhere — 0 upscaling across 11 real device profiles on both pages. TWO RESIDUAL OVER-FETCHES, LEFT DELIBERATELY, so neither reads as an oversight later. **320@2** needs 544 and takes 640 (1.18x): there is no rung between 480 and 640, and 480 would be a 1.13x UPSCALE, so the oversize is the better half of that trade. **1056@2 needs 760.4 and takes 960 (1.26x, +6.8 KB)** — a knife-edge, and worth stating because it looks like a `sizes` error and is not: the declared `36vw` is accurate to the measured 36.0% track, and 380.2 x 2 = 760.4 misses the 760 rung by four tenths of a pixel. Declaring 35vw to duck under it would make `sizes` less truthful across the whole band in exchange for a 0.05% upscale at this width. The declaration stays honest and one viewport over-fetches. ⚠️ `fetchpriority="high"` IS GONE, AND THIS PAGE HAD IT WHILE `/about/` WITHHELD IT ON THE IDENTICAL MEASUREMENT. The old comment read "eager + fetchpriority=high because this is the LCP candidate on the page docs/04 budgets hardest" — true only from 768px up. Measured, cache cleared per device: 320x568 @2 portrait visible 0px LCP — 11,058 B 360x780 @3 portrait visible 0px LCP — 21,526 B 390x844 @3 portrait visible 0px LCP P.hero-lede 27,594 B 430x932 @3 portrait visible 30px LCP P.hero-lede 48,799 B 1280x900 @1 portrait visible 595px LCP IMG.portrait 7,257 B So on mobile — the axis the ≥95 budget is actually measured on — it promoted 27-49 KB of image the reader cannot see above the Geist face that paints the real LCP element. `/about/` already withheld it for exactly this reason and this page did the opposite; the inconsistency is the finding. `loading="eager"` STAYS: the portrait is the LCP element from 768px up, and eager costs nothing where it is off-screen. If the desktop LCP ever needs protecting explicitly, the right instrument is `` in , which honours `sizes` and therefore self-cancels on phones — not a blanket attribute that cannot. */ }
{/* ---- 2. Credential row --------------------------------------------- */}
{ /* NO `aria-labelledby` ON THE CONTENT SECTIONS, and that is the fix for an inconsistency rather than a removal of information. Four of them carried one and this one did not, which put five named regions plus header / nav / main / footer / footer-nav in a screen reader's region list — eleven entries for a marketing page — with the only unnamed content section being the odd one out. A `
` without an accessible name is not exposed as a region at all, and the visible `

`s already give heading navigation, which is how a reader moves through a page like this. THE ONE EXCEPTION IS THE CREDENTIAL BAND, which has no visible heading, so `aria-label` is the only thing that can name it. The rule is: name a region only where it has no heading of its own. */ } {/* ---- 3. The approach ----------------------------------------------- */}
Two directions at once. { /* THIS PARAGRAPH USED TO OPEN "Law and engineering are not blended here", and `claims-auditor` flagged it as Q37's struck parallel relocated from the credential label into prose — a degree and a practice under one noun, one day after Pouya struck exactly that construction. It is a fair reading and the fix is the same fix: make the two halves asymmetric. What a neutral does with a contract is read it; what an engineer does is engineering. Neither sentence now sets "Law" beside "engineering" as two instances of one thing. `docs/01` §`/` item 3 and `docs/03` §Home both specify this section as "the 'two directions at once' argument — law and engineering converging on the same dispute", so the ARGUMENT is unchanged and still delivered; only the construction that carried the implication is gone. **Q41(a) CLOSED 2026-08-27: Q37's reasoning DOES extend to prose, and prose has to do more than avoid the parallel.** Pouya: *"The implication test applies everywhere, not just to labels. Prose has more room, so it is easier to satisfy: state the asymmetry explicitly rather than relying on a parallel construction to carry it."* Avoiding the pair was therefore only half the fix — a reader can still supply the missing symmetry from silence. So the second paragraph now names both halves for what they are: training on one side, current work on the other. "Training I hold" is the opposite of a licence claim, which is the point of saying it out loud. `docs/01`'s and `docs/03`'s own phrase "law and engineering" is the struck construction; both now carry a note not to lift it into copy. The argument it names is Pouya's and stands. */ }

Any dispute I take gets read twice: once against the documents, and once as engineering. The two readings are not blended here. They run at the same time.

{ /* FROM A CONSTANT, NOT TYPED. It was typed here and then typed again on `/about/`, and the two copies had ALREADY diverged inside one session — a comma here, full stops there. Q41(a) makes this the sentence responsible for foreclosing the licence implication, so it is the worst string on the site to let drift. See ASYMMETRY_LINE in src/data/site.ts. */ }

{ASYMMETRY_LINE}

{ /* TWO COMPARATIVES CAME OUT OF THESE PARAGRAPHS ON 2026-08-28, and both had SURVIVED the sweep that closed Q41(b) the day before: "The second half of each pair usually arrives as a separate expert report." — an empirical claim about how disputes are usually run, i.e. about a population of other matters. "it is why the technical half is not something a party has to commission and wait for" — the same claim in counterfactual form, which is harder to spot and says more. Pouya's ruling on Q41(b) is the test: *"assert his capability, not the field's incapability."* Both worked by asserting the field's. What replaces them says only what he does, which is the stronger claim anyway — and it is shorter. */ }

A construction claim is a contract question and a scheduling question. A software dispute is a licence question and an architecture question. A grid connection is a regulatory question and a load question.

I read both halves of each pair myself. That is the whole of it.

My mark is an infinity loop, and it is the argument in one line: disputes are loops. The work is redrawing the loop into a line.

{ /* Decorative: the paragraph beside it says what it is, so an accessible name here would be read twice. Measured on this ground — the ribbon's champagne half carries the silhouette against ink, the maroon half against cream; it reads on both. */ }
{ /* width=232 and loading=lazy are both measured, not defaults. `size` caps at 9rem tall, so the mark renders at up to 144 x 225.5 CSS px — five times the header's 50.1px, and the component's default 64px ladder tops out at 192px. Measured upscale before this: 1.17x at DPR 1, 2.35x at DPR 2, 3.52x at DPR 3. 232 with densities [1,2,3] gives 232/464/696, and 696 covers the 676 device px a DPR-3 screen asks for. Lazy because this sits roughly a screen and a half down; the component defaults to eager for the masthead. */ }
{/* ---- 4. Two practices --------------------------------------------- */}
{ /* The id goes on a span INSIDE the h2 via the `heading` slot, so `aria-labelledby` names the visible heading. The first version passed `title=` and additionally rendered a `.visually-hidden` span carrying the id, which put the same words in the accessibility tree twice — found in the heading-outline dump, not by reading the source. */ } { /* THE WRAPPER IS THE FIX, NOT DECORATION. This was ``, and the page's rule compiled to `.section-head[data-astro-cid-]` while the rendered root carried SectionHeading's own cid — so it never matched. Measured: `margin-block-end: 0px` and a 0px gap to the cards on all three call sites, with `.display`'s 0.98 line-height putting the glyphs over the card's top edge. `astro check` 0 errors, `eslint` clean, and the source looked right. Fourth instance of this on the project; SectionHeading no longer accepts a `class` at all, and passing one is now a build error. */ }
Two processes.

Mediation

{ /* NO FEE CLAIM ON THIS CARD — a constraint, not an omission. There are two ways to get it wrong in one line and both have shipped once: "at one published rate" reads as ONE price where D14's card sets two, and an unqualified "preparation included" sells an uncapped allowance where `docs/07` caps it at stated hours. A card this size cannot state either properly. `/mediation/` and `/fees/` carry the card. */ }

Sole mediator, Q.Med through ADRIC and ADRIO, with multiple completed sole mediations. Half day or full day, in person or by video.

Arbitration

{ /* COMMERCIAL MATTERS ONLY (Q39) — family arbitration is not offered, and that scope is Pouya's own choice, not a conclusion this record draws about the law. */ }

I accept sole, party-appointed and co-arbitration appointments in commercial matters, on a documents-only, expedited or full-hearing track.

{ /* Med-Arb has its own §4 Offerings row (Q35, 2026-08-27), so it is named here as a present offering. docs/01 item 4 asked for it as "the long-term arc"; there is no arc, and that item is amended. */ }

Med-Arb combines the two: one neutral mediates, then arbitrates whatever has not settled. I accept those appointments in commercial matters. The page on it meets the procedural-fairness objection head on rather than around it — how med-arb works →

{/* ---- 5. Practice areas -------------------------------------------- */} { /* docs/01: "the most important block on the page for search, because it distributes authority to the pages that can actually rank." */ }
Where the work is.
{ /* reveal-stagger is capped at six children by design (docs/02) and there are exactly six. A seventh would land with the sixth, not break. */ }
{ PRACTICE_AREAS.map((area) => ( {area.blurb} )) }
{ /* THIS SAID "All six areas, and what else is offered", which asserted offerings beyond the six, none of which had a §4 row. **Q42 CLOSED 2026-08-27, and one of the four candidates came out.** Early neutral evaluation, dispute-system design and pre-dispute technical advisory now have Offerings rows. **Settlement counsel does not, and never will** — Pouya struck it as his own error in `docs/01`: *"Settlement counsel acts FOR a party in negotiation. That is a partisan role, and putting it on a site that (a) sells neutrality and (b) asserts no licensure under D13 is wrong twice over."* THIS LINE STILL READS "All six practice areas" and that is unchanged on purpose. The three rowed processes are `/practice/`'s "also offered" strip at step 5, not a claim `/` makes in a link label — a six-card grid followed by "and what else is offered" is the Med-Arb-in-the-footer shape whether or not the rows exist. */ }

All six practice areas →

{/* ---- 6. Process preview ------------------------------------------- */}
From first call to conclusion.
    { PROCESS.map((step, i) => ( {step.body} )) }
{ /* NOT OPTIONAL, AND NOT A DISCLAIMER — Q43, Pouya 2026-08-27. It is the condition on which the five timings may be published at all: *"Published as typical, they are honest and useful; published as commitments, the first matter that slips makes the page false."* It sits directly under the numbers rather than in the section lede above them, because a reader who scans the strip and skips the lede has read a commitment. `/process/` renders the same constant at step 6. */ }

{PROCESS_FRAMING}

What happens if the matter does not settle →

{/* ---- 7. Latest insights -------------------------------------------- */} { latest.length > 0 && (
Recently written.
{latest.map((entry) => ( ))}

Everything written →

) } {/* ---- 8. Contact band ---------------------------------------------- */} { /* A COMPONENT SINCE 2026-08-28. It was ~20 lines of markup plus ~20 of CSS here and the same again on `/about/`, and the two had already drifted (`.contact-body` at 52ch here, 46ch there) inside the session that wrote the second one. Seventeen pages remain. docs/01 item 8's missing booking link is documented in the component, once. */ }