feat: build step 4 — /mediation/, /arbitration/, /med-arb/; source ADRIC's rules
Build and deploy / build-and-deploy (push) Failing after 4s

Three pages, five in the build, zero JavaScript. /arbitration/ carries §4's
paired-disclosure condition on four surfaces and Q39's struck universal appears
in no form. /med-arb/ meets the procedural-fairness objection at the level of
process design and ships deliberately without Pouya's own protocol commitments,
which are Q54.

docs/01 directed the mediation page to name the "ADRIC Model Mediation Rules".
No such document exists — 0 occurrences across all four of ADRIC's rules pages
against 10 for "National Mediation Rules"; "Model" belongs to the Model Dispute
Resolution Clause inside the rules. Caught only because R14 requires the source
before the claim. docs/reference/adric-rules.md + adric-extract/ carry it, with
the digest drift measured rather than assumed: the HTML changes per request, the
text extracts are byte-stable, so the extracts are the artefact.

Four review passes, 21 defects, and the pattern was mine: I wrote the Q54 gate
into the page and then breached it four times, then round 2 found two survivors
of round 1's own fixes and one defect round 1's fix created. Also removed a
<title> naming a practised role §4 does not grant, a habitual presupposing awards
issued, and a claim about what ADRIC's rules permit that my own reference doc
says is unsupported.

Two instrument failures caught before they became conclusions: touch targets
measured over file:// with no CSS loaded (uniform 18px, including on a .btn with
a 44px floor), and a schema.org validator call that parsed nothing and returned
0 warnings for everything. Both re-run with the instrument validated first.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0148NztQskLKKApP5SzAA78e
This commit is contained in:
Pouya Lajevardi
2026-08-28 17:06:27 -04:00
co-authored by Claude Opus 5
parent 2282183b4b
commit f3138a0a79
18 changed files with 2496 additions and 18 deletions
+63
View File
@@ -0,0 +1,63 @@
---
/**
* A `<dl>` of term/description pairs on an auto-fitting grid.
*
* EXTRACTED AT STEP 4 ON `adversarial-reviewer`'S FINDING, and the finding was
* that `/mediation/`'s `.formats` and `/arbitration/`'s `.cols` were the same
* component under two names — identical markup, near-identical CSS, and
* `.cols` was already serving two different content types on one page.
* `/practice/*` at step 5 wants it a fourth time. Same argument that extracted
* `ContactBand`: two call sites, one already divergent, pages to come.
*
* `<dl>` RATHER THAN A DIV GRID, for `CredentialRow`'s reason: each pair is a
* term and its description, so a screen reader gets them as an associated pair
* rather than as a visual arrangement. Wrapping each `<dt>`/`<dd>` in a `<div>`
* inside the `<dl>` is valid HTML and is what makes the grid tractable.
*
* A `<dt>` IS NOT A HEADING and must not become one. These sit under the
* section's `<h2>`; promoting them to `<h3>` would be a heading level that adds
* nothing to the outline, and `docs/02` forbids skipped levels either way.
*/
interface Props {
items: ReadonlyArray<{ name: string; body: string }>;
/** The grid's per-column floor, passed to `.grid-autofit` as `--grid-min`.
* The `min(N, 100%)` guard lives there, in one place. */
minColumn?: string;
}
const { items, minColumn = '17rem' } = Astro.props;
---
<dl class="grid-autofit defs" style={`--grid-min: ${minColumn}`}>
{
items.map((item) => (
<div class="def">
<dt class="def-name">{item.name}</dt>
<dd class="def-body">{item.body}</dd>
</div>
))
}
</dl>
<style>
/* Columns and the `min()` guard come from `.grid-autofit` (global.css); this
sets only the gap. It re-implemented them for one pass — a second copy of
the guard, inside the extraction made to remove copies of the guard.
`--grid-min` is passed inline by the caller because a parent cannot style
this component's root, and a custom property is the one mechanism that
crosses that boundary. */
.defs {
gap: var(--space-7);
}
.def-name {
font-family: var(--font-mono);
font-size: var(--text-xs);
font-weight: var(--weight-medium);
letter-spacing: var(--tracking-wide);
text-transform: uppercase;
color: var(--text-meta);
}
.def-body {
margin-block-start: var(--space-2);
line-height: var(--leading-body);
}
</style>
+124 -2
View File
@@ -179,7 +179,21 @@ export function personNode(
*
* No `priceRange`, no `aggregateRating`, no `review` — the last two have no
* underlying data and §4 Forbidden bars the fabricated testimonial that the
* previous site carried.
* previous site carried. And no `availableLanguage`: it is not in this type's
* domain either (see `serviceGraph`), and the `Person` beside it in the graph
* carries `knowsLanguage`.
*
* ⚠️ **`serviceType` AND `provider` ARE STILL OUT OF DOMAIN ON THIS TYPE, AND
* THAT IS UNRESOLVED.** Measured 2026-08-28 against `validator.schema.org`:
* `/` returns `UNKNOWN_FIELD` for `serviceType`, `availableLanguage` and
* `provider` on `ProfessionalService`, which is a `LocalBusiness` and takes
* none of the three. `availableLanguage` is removed above because nothing is
* lost. The other two carry real information — the commercial scoping and the
* link to the Person — so removing them costs more than the warning does, and
* the modelled fix is a `Service` node with the business as `provider`, which
* is a change to the home page's structured data rather than a tidy-up. **The
* other four pages now validate with 0 warnings**; this node is the last one.
* Raised for the step-7 SEO pass, not left as folklore.
*/
export function professionalServiceNode(imageUrl?: string) {
return {
@@ -202,7 +216,6 @@ export function professionalServiceNode(imageUrl?: string) {
'Commercial arbitration',
'Mediation-arbitration (med-arb)',
],
availableLanguage: ['en', 'fa'],
email: `mailto:${CONTACT.email}`,
...(imageUrl ? { image: imageUrl } : {}),
};
@@ -250,3 +263,112 @@ export function aboutGraph(imageUrl?: string) {
'@graph': [personNode(imageUrl, { memberships: true })],
};
}
/**
* `Service` for the three process pages — `/mediation/`, `/arbitration/`,
* `/med-arb/` (build step 4). docs/04's structured-data table.
*
* THE PERSON NODE TRAVELS WITH IT, for the reason `homeGraph` gives: a `@graph`
* makes `provider: {'@id': …}` resolve inside this document rather than relying
* on a crawler fetching `/about/` and joining two. Same `@id` either way, so a
* consumer that does fetch both merges rather than duplicates.
*
* NO `BreadcrumbList`. These are one hop from the root and show no visible
* breadcrumb; docs/04 requires the markup to MATCH visible breadcrumbs, so
* emitting one would assert navigation the page does not show. Breadcrumbs
* begin at `/practice/<area>/` and `/insights/<slug>/`.
*
* NO `offers` AND NO `priceRange` until `/fees/` exists (build step 9) — same
* gate docs/04 puts on `ProfessionalService`.
*
* NO `availableLanguage` EITHER, AND THAT IS NOT AN OVERSIGHT. schema.org's
* `domainIncludes` for it is `ContactPoint`, `Course`, `LodgingBusiness`,
* `ServiceChannel`, `TouristAttraction` — **not `Service`**. It shipped here for
* one pass and `validator.schema.org` returned `UNKNOWN_FIELD` twice per page on
* all three, against **0 warnings** on `/about/`. The `Person` in the same
* `@graph` already carries `knowsLanguage: ['en','fa']`, so nothing is lost. The
* modelled alternative is `availableChannel → ServiceChannel → availableLanguage`,
* which is more machinery than the fact is worth.
*
* ⚠️ `serviceType` IS A UNION, NOT A STRING, AND THAT IS THE POINT. An
* unscoped `"Arbitration"` is Q39's struck universal — false as a universal,
* swept four times, reached a public page once — so it is not a value this
* function will accept. A comment asking a caller not to pass it is a warning; a
* union is a build error. Widening the union requires a §4 Offerings row, and
* the row is the only thing that should ever widen it.
*/
/** `docs/04`'s ratified `serviceType` strings — **not** §4's row labels, which
* read "Arbitration — sole arbitrator (commercial)" and "Med-Arb —
* mediation-arbitration". Adding a member needs a §4 Offerings row, but do not
* copy the row's wording: doing that "verbatim" yields the unscoped
* `Arbitration` this union exists to bar. */
export type PublishableServiceType =
'Mediation' | 'Commercial arbitration' | 'Mediation-arbitration (med-arb)';
export function serviceGraph(opts: {
path: string;
name: string;
serviceType: PublishableServiceType;
description: string;
imageUrl?: string;
}) {
return {
'@context': 'https://schema.org',
'@graph': [
{
'@type': 'Service',
'@id': `${SITE.url}${opts.path}#service`,
name: opts.name,
serviceType: opts.serviceType,
description: opts.description,
url: `${SITE.url}${opts.path}`,
provider: { '@id': PERSON_ID },
areaServed: [
{ '@type': 'City', name: 'Toronto' },
{ '@type': 'AdministrativeArea', name: 'Ontario' },
],
},
personNode(opts.imageUrl),
],
};
}
/**
* `/med-arb/`'s graph — the Service, the Person, and a `FAQPage`.
*
* docs/04 lists `FAQPage` for this page and for `/for-parties/`, with the
* condition that matters: *"Only where the visible page genuinely is Q&A. Never
* fabricate questions to farm a rich result."* So the node is BUILT FROM THE
* SAME ARRAY THE PAGE RENDERS — a question cannot enter the structured data
* without appearing on the page, and the two cannot drift.
*/
export function medArbGraph(opts: {
faq: ReadonlyArray<{ q: string; a: string }>;
imageUrl?: string;
}) {
const base = serviceGraph({
path: '/med-arb/',
name: 'Med-arb (mediation-arbitration)',
serviceType: 'Mediation-arbitration (med-arb)',
description:
'Mediation that converts to binding arbitration if the mediation does ' +
'not resolve the dispute. One neutral, both phases, agreed in writing ' +
'in advance. Commercial matters.',
imageUrl: opts.imageUrl,
});
return {
...base,
'@graph': [
...base['@graph'],
{
'@type': 'FAQPage',
'@id': `${SITE.url}/med-arb/#faq`,
mainEntity: opts.faq.map((item) => ({
'@type': 'Question',
name: item.q,
acceptedAnswer: { '@type': 'Answer', text: item.a },
})),
},
],
};
}
+11 -9
View File
@@ -50,18 +50,20 @@ export const CREDENTIALS = {
designations: ['Q.Med (ADRIC / ADRIO)'],
inProgress: ['Q.Arb — commenced August 2026'], // [verified 2026-08-26]
/**
* "Chartered Med-Arbitrator" — ADRIO's own term
* (docs/reference/adrio-designations.md). This read "Chartered
* Mediator-Arbitrator" until 2026-08-28, which was wrong; Pouya caught it and
* it was his own error, carried from the strategy brief and never sourced.
* "Chartered Med-Arbitrator" — ADRIO's own term, and ADRIC's navigation label
* too (docs/reference/adrio-designations.md; docs/reference/adric-rules.md
* Finding 3, which corroborates it from a second body). Never
* "Mediator-Arbitrator".
*
* UNCONSUMED AS OF 2026-08-28 — nothing imports `CREDENTIALS.goal`. `/about/`'s
* credential arc hand-types all three designations instead, which is the drift
* shape this repo keeps paying for (see ContactBand's 52ch/46ch divergence).
* It is corrected rather than deleted because `/med-arb/` at build step 4 is
* its natural consumer: either that page uses it, or this line comes out.
* `GOAL_NAME` IS THE STRING TO RENDER. This designation's name was wrong on a
* public page for the life of the file, and the reason it survived four review
* passes is that it existed in several hand-typed copies rather than one
* constant. `/arbitration/` and `/med-arb/` (step 4) render `GOAL_NAME`;
* `/about/`'s arc still hand-types it, which is the remaining copy.
*/
goal: 'C.Med-Arb (Chartered Med-Arbitrator)',
/** Just the expansion, for prose. §11 Glossary is the authority for it. */
goalName: 'Chartered Med-Arbitrator',
education: ['JD, Bond University'],
certifications: [
'Kompass Arbitration Certificate Program',
+327
View File
@@ -0,0 +1,327 @@
---
/**
* `/arbitration/` — build step 4. Spec: docs/01 §`/arbitration/`, docs/03.
*
* ⚠️ THIS PAGE CARRIES §4's PAIRED-DISCLOSURE CONDITION, AND IT IS A CONDITION
* ON THE OFFERING ITSELF, NOT A DISCLAIMER BOLTED TO IT. Both halves ship or
* neither does:
*
* 1. All three forms are offered NOW — sole, party-appointed, co-arbitration
* — in commercial matters. §4 Offerings rows all three.
* 2. The Q.Arb PATHWAY commenced August 2026, with C.Med-Arb as the endpoint.
*
* "Pathway", never "designation": a designation that "commenced in August 2026"
* reads as held since then, which §4 Forbidden bars. Pouya's instruction is that
* being open about the stage is the differentiator — so it is stated plainly and
* high on the page, not hedged and not buried.
*
* ⚠️ AND NOTHING HERE MAY SAY OR IMPLY THAT ARBITRATION IS UNGATED IN ONTARIO.
* Q39's struck universal — "anyone may be appointed an arbitrator in Ontario;
* nothing in law gates the role behind a designation" — was FALSE as a
* universal, has been swept four times, and reached a public page once. The
* page states what is offered and where the credentialing stands. It makes no
* claim about what the law requires of anyone.
*/
import BaseLayout from '../layouts/BaseLayout.astro';
import Button from '../components/Button.astro';
import ContactBand from '../components/ContactBand.astro';
import DefinitionGrid from '../components/DefinitionGrid.astro';
import CredentialRow from '../components/CredentialRow.astro';
import Eyebrow from '../components/Eyebrow.astro';
import Pill from '../components/Pill.astro';
import SectionHeading from '../components/SectionHeading.astro';
import { getImage } from 'astro:assets';
import ogDefault from '../assets/og-portrait.jpg';
import { serviceGraph } from '../data/schema';
import { CREDENTIALS, CREDENTIAL_ROW, CREDENTIAL_ROW_ARB } from '../data/site';
const ldImage = await getImage({
src: ogDefault,
format: 'jpeg',
width: 1200,
height: 630,
});
const graph = serviceGraph({
path: '/arbitration/',
name: 'Commercial arbitration',
serviceType: 'Commercial arbitration',
description:
'Sole-arbitrator, party-appointed and co-arbitration appointments in ' +
'commercial matters. Documents-only, expedited and full hearing tracks.',
imageUrl: new URL(ldImage.src, Astro.site).href,
});
/* §4 Offerings rows all three, each `[verified 2026-08-26 — Pouya, Q33/Q36]`,
each scoped commercial. Do not add a fourth without a row. */
const APPOINTMENTS = [
{
name: 'Sole arbitrator',
body: 'One arbitrator, appointed by agreement or by the mechanism the contract names.',
},
{
name: 'Party-appointed',
body: 'Appointed by one side to a three-member tribunal, deciding with the other two.',
},
{
name: 'Co-arbitration',
body: 'Sitting with co-arbitrators, usually where the matter spans more than one discipline.',
},
];
/* Tracks are docs/01 §`/arbitration/` item 2. The flat fees behind the first
two are D14's card and live on `/fees/`; no figure appears here. */
const TRACKS = [
{
name: 'Documents only',
body: 'No hearing. Written submissions, the documentary record, and an award. The right track where the dispute is about what the contract says rather than about what happened.',
},
{
name: 'Expedited',
body: 'A compressed timetable fixed at the outset, with page limits and a short hearing. Chosen when the commercial cost of the dispute staying open exceeds the value of a full process.',
},
{
name: 'Full hearing',
body: 'Pleadings, disclosure, witnesses, experts, oral argument. Where the facts are genuinely contested and someone has to hear them tested.',
},
];
---
<BaseLayout
title="Commercial Arbitration · Pouya Lajevardi · Toronto"
description="Sole, party-appointed and co-arbitration appointments in commercial matters, Toronto. Tracks, rules and awards — and where the Q.Arb pathway stands."
jsonLd={graph}
>
{/* ---- 1. Hero — and the paired disclosure starts here ---------------- */}
<section class="section hero">
<div class="wrap">
<Eyebrow dot>Arbitration</Eyebrow>
<h1 class="display hero-h">Available now, and open about the stage.</h1>
<p class="hero-lede">
I accept sole, party-appointed and co-arbitration appointments in
commercial matters. The Q.Arb pathway commenced in August 2026;
C.Med-Arb is the endpoint. Both are true at once, and they belong
together rather than one of them surfacing later.
</p>
<div class="hero-creds">
<CredentialRow slots={[...CREDENTIAL_ROW, CREDENTIAL_ROW_ARB]} />
</div>
</div>
</section>
{/* ---- 2. The credentialing stage, on its own ------------------------- */}
{
/* §4 Offerings: "neither half may be dropped". The offering is in the hero;
this is the other half, given its own section rather than a footnote,
because Pouya's instruction is that the openness IS the differentiator. */
}
<section class="section section-inverse reveal">
<div class="wrap">
<div class="section-head">
<SectionHeading eyebrow="Where I am in the arc" level={2}>
<span slot="heading"
>Stated plainly rather than discovered later.</span
>
</SectionHeading>
</div>
<ol class="grid-autofit stage" role="list">
<li>
<Pill>Held</Pill>
<h3 class="stage-name">Q.Med</h3>
<p class="stage-body">
Qualified Mediator, through the ADR Institute of Canada and the ADR
Institute of Ontario.
</p>
</li>
<li>
<Pill>Commenced August 2026</Pill>
<h3 class="stage-name">Q.Arb</h3>
<p class="stage-body">
Qualified Arbitrator. Newly commenced — not held, and not nearing
completion.
</p>
</li>
<li>
<Pill>The endpoint</Pill>
<h3 class="stage-name">C.Med-Arb</h3>
<p class="stage-body">
{CREDENTIALS.goalName}. The designation this practice is built
toward.
</p>
</li>
</ol>
<p class="stage-note">
If the stage of the arc bears on an appointment decision, it should bear
on it before the appointment and not after.
</p>
</div>
</section>
{/* ---- 3. Appointments ------------------------------------------------ */}
<section class="section reveal">
<div class="wrap">
<div class="section-head">
<SectionHeading
eyebrow="Appointments"
level={2}
lede="Commercial matters. I do not accept family arbitration."
>
<span slot="heading">Three forms.</span>
</SectionHeading>
</div>
<DefinitionGrid items={APPOINTMENTS} />
</div>
</section>
{/* ---- 4. Tracks ------------------------------------------------------ */}
<section class="section section-alt reveal">
<div class="wrap">
<div class="section-head">
<SectionHeading
eyebrow="Tracks"
level={2}
lede="Settled with the parties before the first procedural order, not defaulted to."
>
<span slot="heading">How much process the dispute needs.</span>
</SectionHeading>
</div>
<DefinitionGrid items={TRACKS} />
</div>
</section>
{/* ---- 5. Rules ------------------------------------------------------- */}
<section class="section reveal">
<div class="wrap">
<div class="section-head">
<SectionHeading eyebrow="Rules" level={2}>
<span slot="heading">Under whose rules.</span>
</SectionHeading>
</div>
<div class="prose">
{
/* Sourced: docs/reference/adric-rules.md. ADR CHAMBERS IS DELIBERATELY
NOT NAMED — docs/01 item 3 lists it, and nothing in this repository
sources what rules it publishes. docs/07 cites it for published FEE
ranges, which is a different claim. Name it here once it is sourced;
do not name it from recall (R14). */
}
<p>
<strong>The ADRIC Arbitration Rules.</strong> The ADR Institute of Canada
adopted a new edition effective 1 March 2025, alongside an arbitrator appointment
protocol and a set of forms — notice to arbitrate, request to administer,
request for the appointment of an arbitrator, urgent interim measures, challenge
to an arbitrator, notice of appeal.
</p>
<p>
<strong>Or ad hoc, or whatever the contract names.</strong> Where a contract
names a rule set, a seat and a language and leaves the rest to the tribunal,
that works. What does not is a process whose shape nobody agreed to in advance.
</p>
</div>
</div>
</section>
{/* ---- 6. Awards ------------------------------------------------------ */}
<section class="section section-alt reveal">
<div class="wrap">
<div class="section-head">
<SectionHeading eyebrow="Awards" level={2}>
<span slot="heading">In writing, with reasons.</span>
</SectionHeading>
</div>
<div class="prose">
<p>
An award should be in writing and give reasons — what was in dispute,
what the record showed, and why the conclusion follows. An award that
announces a result without the reasoning is not much use to the party
that lost, and it is no use at all to the relationship that has to
survive it.
</p>
{
/* THE DATE IS A COMMITMENT ABOUT PROCESS, NOT A PUBLISHED TURNAROUND.
§4 Forbidden bars a time-to-award statistic outright; no figure
appears here and none may be added. */
}
<p>
The date an award is due belongs in the first procedural order, along
with everything else, rather than being left open. No number is
published here: a turnaround time advertised in advance of a record is
a guess dressed as a commitment.
</p>
</div>
</div>
</section>
{/* ---- 7. Fees --------------------------------------------------------- */}
<section class="section reveal">
<div class="wrap">
<div class="section-head">
<SectionHeading eyebrow="Fees" level={2}>
<span slot="heading">Published in full.</span>
</SectionHeading>
</div>
<div class="prose">
<p>
Hourly, hearing day, and flat fees for documents-only and expedited
matters at two levels of complexity. The cancellation schedule is on
the same page.
</p>
</div>
<div class="cta">
<Button href="/fees/" variant="ghost">The rate card &rarr;</Button>
</div>
</div>
</section>
<ContactBand />
</BaseLayout>
<style>
.hero {
padding-block-start: var(--space-9);
}
.hero-h {
margin-block: var(--space-4) var(--space-5);
font-size: var(--text-5xl);
max-inline-size: 20ch;
}
.hero-lede {
max-inline-size: 58ch;
font-size: var(--text-lg);
line-height: var(--leading-body);
color: var(--text-secondary);
}
.hero-creds {
margin-block-start: var(--space-8);
}
/* `.stage`, NOT `.arc`. `/about/` has an `.arc` block of its own with the
same class names and different rendering — serif at --text-2xl there, mono
at --text-lg here — and Astro's scoping means neither reaches the other. Two
meanings for one name across two pages is a rename waiting to go wrong.
`role="list"` on the <ol> and no local `list-style: none`: global.css does
both for `ol[role='list']`, and WebKit drops list semantics when the marker
goes, which is why the role is there. Columns come from `.grid-autofit`. */
.stage {
--grid-min: 17rem;
gap: var(--space-7);
}
.stage-name {
margin-block: var(--space-4) var(--space-2);
font-family: var(--font-mono);
font-size: var(--text-lg);
font-weight: var(--weight-medium);
}
.stage-body {
max-inline-size: 40ch;
line-height: var(--leading-body);
}
.stage-note {
margin-block-start: var(--space-8);
max-inline-size: 54ch;
line-height: var(--leading-body);
color: var(--text-inverse-2);
}
.cta {
margin-block-start: var(--space-6);
}
</style>
+274
View File
@@ -0,0 +1,274 @@
---
/**
* `/med-arb/` — build step 4. Spec: docs/01 §`/med-arb/`, docs/03 §Mediation /
* Arbitration / Med-Arb, docs/04 (FAQPage is specified for this page).
*
* docs/01 rates this the strongest candidate for the best-performing page on
* the site: real search demand, thin competition, and it maps to the practice's
* long-term arc. So it is written to be the page that actually explains the
* process, not a service blurb.
*
* THE FAIRNESS SECTION IS WRITTEN ABOUT THE PROCESS, NOT ABOUT POUYA, AND THAT
* IS DELIBERATE. docs/03 requires the procedural-fairness objection met head-on
* and the consent mechanics explained. What a med-arb AGREEMENT has to settle is
* process design and needs no §4 row. What POUYA will personally commit to —
* how he handles caucus information he cannot un-hear, and whether he would step
* out of the arbitral phase rather than decide on it — is a claim about his
* practice, has no §4 row, and is not invented here.
* TODO(pouya): AGENTS.md Q54 — confirm the six conduct commitments drafted
* there, or replace them. Three are this page's; two shipped here and on
* `/mediation/` for one pass before `claims-auditor` removed them.
*/
import BaseLayout from '../layouts/BaseLayout.astro';
import ContactBand from '../components/ContactBand.astro';
import Eyebrow from '../components/Eyebrow.astro';
import SectionHeading from '../components/SectionHeading.astro';
import { getImage } from 'astro:assets';
import ogDefault from '../assets/og-portrait.jpg';
import { medArbGraph } from '../data/schema';
import { CREDENTIALS } from '../data/site';
const ldImage = await getImage({
src: ogDefault,
format: 'jpeg',
width: 1200,
height: 630,
});
/* ONE SOURCE FOR THE Q&A, rendered visibly AND fed to the FAQPage node. docs/04
allows FAQPage here "only where the visible page genuinely is Q&A" — so the
node is built from the same array the section renders, and a question cannot
be added to the structured data without appearing on the page. */
const FAQ = [
{
q: 'The neutral who heard my client in caucus then decides the case. How is that fair?',
a: 'That is the objection, and it is the right one. A mediator learns things a decision-maker is not supposed to know — what a party would really take, what they are afraid of, what their own counsel thinks of their case. In med-arb the same person may go on to decide it. The answer is not that the concern is overstated. It is that med-arb is only defensible where the parties agree to it knowingly and in advance, in writing, with the switch and its consequences settled before the mediation phase begins — never improvised on the day because the room has run out of road.',
},
{
q: 'What happens to what we say in caucus?',
a: 'That is the question the agreement has to answer before anyone says anything. A med-arb agreement should settle three things in terms: what triggers the move from mediation to arbitration; what a party may say in caucus without it entering the arbitral record; and how a party flags, at the time, that something is being said for the mediation only. Vagueness on any of the three is what turns a procedural objection into a real one.',
},
{
q: 'When is med-arb the wrong process?',
a: 'When the parties are not equally informed or equally advised, because the caucus asymmetry compounds. When one side needs a finding on the record more than it needs a settlement. When the relationship is already so damaged that a joint session is unproductive and shuttle mediation would be the better tool on its own. And whenever a party agrees to it reluctantly: grudging consent at the outset is not the foundation a process like this one runs on.',
},
];
const graph = medArbGraph({
faq: FAQ,
imageUrl: new URL(ldImage.src, Astro.site).href,
});
---
<BaseLayout
title="Med-Arb · Pouya Lajevardi · What It Is and When It Fits"
description="Med-arb is mediation that converts to arbitration if it does not resolve. What it is, how it differs from arb-med, the fairness objection, and when it fits."
jsonLd={graph}
>
{/* ---- 1. Hero -------------------------------------------------------- */}
<section class="section hero">
<div class="wrap">
<Eyebrow dot>Med-Arb</Eyebrow>
<h1 class="display hero-h">
One neutral. Two processes. One agreement, written first.
</h1>
<p class="hero-lede">
Med-arb is mediation that converts to binding arbitration if the
mediation does not resolve the dispute. The parties get a real attempt
at settlement and a decision if one does not come, from a single
appointment — and they take on one real objection to get it. This page
is mostly about that objection.
</p>
</div>
</section>
{/* ---- 2. What it is, and how it is not arb-med ----------------------- */}
<section class="section section-alt reveal">
<div class="wrap">
<div class="section-head">
<SectionHeading eyebrow="The shape" level={2}>
<span slot="heading"
>Mediation first. Arbitration only if it is needed.</span
>
</SectionHeading>
</div>
<div class="prose">
<p>
The parties appoint one neutral for both phases. The matter is
mediated. Whatever settles, settles, and is recorded. Whatever does
not settle moves to arbitration in front of the same neutral, on the
terms the parties agreed before any of it began, and ends in an award.
</p>
<p>
The commercial case for it is time and cost. Without it, a mediation
that does not settle means starting again: a new neutral, a second
round of briefs, another set of dates months out. Med-arb removes that
gap, and whatever narrowing the mediation achieved carries into the
arbitration instead of being re-litigated.
</p>
{
/* ARB-MED IS NAMED AS A DIFFERENT PROCESS AND DELIBERATELY NOT DEFINED.
docs/01 asks for the contrast; nothing in `docs/reference/` sources a
definition of arb-med, and this repository does not publish a
definition of a third party's process from recall (R14). Flagging the
confusion is the useful half and it needs no source. Define it here
once a source is committed. */
}
<p>
<strong>It is not arb-med.</strong> The two names are one syllable apart
and the processes are not interchangeable. If a contract names one of them,
check which one before relying on it — against the rule set the contract
adopts, not against this page.
</p>
</div>
</div>
</section>
{/* ---- 3. The objection ----------------------------------------------- */}
<section class="section section-inverse reveal">
<div class="wrap">
<div class="section-head">
<SectionHeading
eyebrow="The objection"
level={2}
lede="Met here rather than further down, because it is the reason to read the page."
>
<span slot="heading">The fairness problem is real.</span>
</SectionHeading>
</div>
<div class="faq">
{
FAQ.map((item) => (
<div class="faq-item">
<h3 class="faq-q">{item.q}</h3>
<p class="faq-a">{item.a}</p>
</div>
))
}
</div>
</div>
</section>
{/* ---- 4. Rules ------------------------------------------------------- */}
<section class="section reveal">
<div class="wrap">
<div class="section-head">
<SectionHeading eyebrow="Rules" level={2}>
<span slot="heading">There is a published rule set for this.</span>
</SectionHeading>
</div>
<div class="prose">
{
/* Sourced: docs/reference/adric-rules.md. Both quotations are ADRIC's
own words. "integrating seamlessly" stays inside the quotation marks —
§4 Forbidden bars superlatives in this site's own voice. */
}
<p>
The ADR Institute of Canada publishes <strong
>ADRIC Med-Arb Rules</strong
>, developed by a task force and put to the membership in 2019, and
designed, in ADRIC's words, to <q
>work in tandem with ADRIC's existing Mediation Rules and
Arbitration Rules</q
>. They were drafted for domestic commercial disputes, and ADRIC notes
that parties may also apply them to international or non-commercial
ones.
</p>
<p>
ADRIC's own framing is worth quoting: med-arb is
<q
>not merely the merging of separate mediation and arbitration
processes, but a unique process designed to meet the needs of
particular disputants</q
>, one that <q
>requires a high level of practitioner competence to do successfully</q
>.
</p>
</div>
</div>
</section>
{/* ---- 5. The endpoint ------------------------------------------------- */}
<section class="section section-alt reveal">
<div class="wrap">
<div class="section-head">
<SectionHeading eyebrow="Why this practice" level={2}>
<span slot="heading"
>C.Med-Arb is the designation this practice is built toward.</span
>
</SectionHeading>
</div>
<div class="prose">
<p>
{CREDENTIALS.goalName}, the ADRIC and ADRIO designation for exactly
this hybrid, is the endpoint of the arc. Q.Med is held. The Q.Arb
pathway commenced in August 2026. C.Med-Arb comes after both, and it
is the reason the two halves of this practice are being built together
rather than one after the other.
</p>
<p>
I accept med-arb appointments now, in commercial matters. The section
above is the part to read before proposing one: the agreement does the
work, and it does it before the mediation starts.
</p>
<p class="onward">
<a href="/mediation/">Mediation &rarr;</a>
<a href="/arbitration/">Arbitration &rarr;</a>
<a href="/fees/">Fees &rarr;</a>
</p>
</div>
</div>
</section>
<ContactBand />
</BaseLayout>
<style>
.hero {
padding-block-start: var(--space-9);
}
.hero-h {
margin-block: var(--space-4) var(--space-5);
font-size: var(--text-5xl);
max-inline-size: 18ch;
}
.hero-lede {
max-inline-size: 58ch;
font-size: var(--text-lg);
line-height: var(--leading-body);
color: var(--text-secondary);
}
.faq {
display: grid;
gap: var(--space-8);
}
.faq-q {
max-inline-size: 46ch;
font-size: var(--text-2xl);
line-height: var(--leading-tight);
}
.faq-a {
margin-block-start: var(--space-4);
max-inline-size: var(--width-prose);
line-height: var(--leading-body);
color: var(--text-inverse-2);
}
/* A ROW OF STANDALONE CTAs, NOT PROSE, so WCAG 2.5.8's inline-link exception
does not cover it. Measured at 390px before the fix: three targets at
21px tall, against the 44px floor docs/02 sets and the 24px minimum 2.5.8
sets. `inline-flex` + `min-block-size` is what `.btn`, the nav and the
footer all use. The middot separators went with the fix — spacing does the
same job without an aria-hidden glyph between two links. */
.onward {
display: flex;
flex-wrap: wrap;
gap: var(--space-2) var(--space-6);
}
.onward a {
display: inline-flex;
align-items: center;
min-block-size: 44px;
}
</style>
+311
View File
@@ -0,0 +1,311 @@
---
/**
* `/mediation/` — build step 4. Spec: docs/01 §`/mediation/`, docs/03 §Mediation.
*
* Job (docs/01): convert counsel who have already decided on mediation and are
* choosing a neutral. So: procedural, specific, unembellished. No persuasion
* that the reader has already done for themselves.
*/
import BaseLayout from '../layouts/BaseLayout.astro';
import Button from '../components/Button.astro';
import ContactBand from '../components/ContactBand.astro';
import DefinitionGrid from '../components/DefinitionGrid.astro';
import CredentialRow from '../components/CredentialRow.astro';
import Eyebrow from '../components/Eyebrow.astro';
import PracticeCard from '../components/PracticeCard.astro';
import SectionHeading from '../components/SectionHeading.astro';
import { getImage } from 'astro:assets';
import ogDefault from '../assets/og-portrait.jpg';
import { serviceGraph } from '../data/schema';
import { CREDENTIAL_ROW, PRACTICE_AREAS } from '../data/site';
const ldImage = await getImage({
src: ogDefault,
format: 'jpeg',
width: 1200,
height: 630,
});
const graph = serviceGraph({
path: '/mediation/',
name: 'Commercial mediation',
serviceType: 'Mediation',
description:
'Sole-mediator appointments in commercial disputes. Half day or full ' +
'day, in person, by video, or shuttle.',
imageUrl: new URL(ldImage.src, Astro.site).href,
});
/* Formats are SERVICE PARAMETERS, not offerings — AGENTS.md Q43 put process
commitments of this class ("not facts about Pouya") on the publishable side.
The half day / full day / video / in-person set is D14's card; shuttle and
hybrid are docs/01 §`/mediation/` item 2. */
const FORMATS = [
{
name: 'Full day',
body: 'The default for a matter with more than two parties, or where the documents need working through in the room.',
},
{
name: 'Half day',
body: 'Enough for a two-party matter where the issues are narrow and both sides arrive ready.',
},
{
name: 'Shuttle',
body: 'The parties never sit in the same room. Useful where the relationship has broken down far enough that a joint session would cost more than it returns.',
},
{
name: 'By video',
body: 'Same preparation, same length, same rate. Remote is not a discount format.',
},
{
name: 'Hybrid',
body: 'Principals in the room, an expert or an insurer joining remotely for the part that concerns them.',
},
];
---
<BaseLayout
title="Commercial Mediation · Pouya Lajevardi · Q.Med · Toronto"
description="Sole mediator for commercial disputes in Toronto. Q.Med through ADRIC and ADRIO. Session formats, the ADRIC National Mediation Rules, and what to bring."
jsonLd={graph}
>
{/* ---- 1. Hero -------------------------------------------------------- */}
<section class="section hero">
<div class="wrap">
<Eyebrow dot>Mediation</Eyebrow>
<h1 class="display hero-h">A mediator decides nothing.</h1>
<p class="hero-lede">
That is the point of the role, and it is what makes the day work. I run
the process, test each side's case against the documents, and keep it
moving until there is an agreement or there plainly will not be one.
</p>
<div class="hero-creds">
<CredentialRow slots={CREDENTIAL_ROW} />
</div>
</div>
</section>
{/* ---- 2. The role ---------------------------------------------------- */}
<section class="section section-alt reveal">
<div class="wrap">
<div class="section-head">
<SectionHeading eyebrow="The role" level={2}>
<span slot="heading">What I am, and what I am not.</span>
</SectionHeading>
</div>
<div class="prose">
<p>
I act as a neutral. I do not act for a party in a matter I take, and
each party should have their own legal advice.
</p>
<p>
What I bring to a commercial file is that I read the contract and the
technical record underneath it — the change orders, the schedule, the
model card, the interconnection study — rather than either side's
summary of them.
</p>
</div>
</div>
</section>
{/* ---- 3. Formats ----------------------------------------------------- */}
<section class="section reveal">
<div class="wrap">
<div class="section-head">
<SectionHeading
eyebrow="Formats"
level={2}
lede="Chosen with the parties at engagement, not assumed."
>
<span slot="heading">How the session runs.</span>
</SectionHeading>
</div>
<DefinitionGrid items={FORMATS} minColumn="22rem" />
</div>
</section>
{/* ---- 4. Rules ------------------------------------------------------- */}
<section class="section section-inverse reveal">
<div class="wrap">
<div class="section-head">
<SectionHeading eyebrow="Rules" level={2}>
<span slot="heading">Under whose rules.</span>
</SectionHeading>
</div>
<div class="prose">
{
/* "ADRIC National Mediation Rules" — the document's own title, from
docs/reference/adric-rules.md. docs/01 said "Model Mediation Rules",
which is not the name of anything ADRIC publishes; "Model" belongs to
the Model Dispute Resolution Clause inside the rules. Finding 1. */
}
<p>
<strong>The ADRIC National Mediation Rules.</strong> The ADR Institute of
Canada publishes them. They cover initiating a mediation and appointing
a mediator where the parties cannot agree on one, and the document carries
a code of conduct, a standard form agreement to mediate, and a model dispute
resolution clause for contracts. If the agreement already names them, the
process is defined before anyone calls me.
</p>
<p>
<strong>Or a protocol the parties write.</strong> Where the contract is
silent, or where the matter needs something a standard rule set does not
contemplate, the protocol is settled in writing before the session.
</p>
</div>
</div>
</section>
{/* ---- 5. What to bring ----------------------------------------------- */}
<section class="section reveal">
<div class="wrap">
<div class="section-head">
<SectionHeading eyebrow="Preparation" level={2}>
<span slot="heading">What to bring.</span>
</SectionHeading>
</div>
<ul class="bring" role="list">
<li>
<strong>A brief.</strong> The issues, the position taken on each, and what
has already been offered and refused. Exchanged in advance, so the session
starts informed rather than spending the morning getting there.
</li>
<li>
<strong>The documents the case turns on</strong> — not the production. If
a clause, a change order, or a test result decides an issue, put it in front
of me before the day.
</li>
<li>
<strong>Authority to settle.</strong> In the room, or reachable in real
time and expecting the call. A mediation that reaches terms and then adjourns
for instructions is a mediation at risk.
</li>
</ul>
</div>
</section>
{/* ---- 6. Confidentiality --------------------------------------------- */}
<section class="section section-alt reveal">
<div class="wrap">
<div class="section-head">
<SectionHeading eyebrow="Confidentiality" level={2}>
<span slot="heading">What stays in the room.</span>
</SectionHeading>
</div>
<div class="prose">
<p>
Confidentiality is set by the agreement to mediate, and that is signed
before the session rather than described on a website. The part worth
settling in it explicitly is the caucus: what a mediator may carry
from one room to the other, and what a party has to say to hold
something back. An agreement that leaves that implicit is the one that
produces an argument on the day.
</p>
{
/* The without-prejudice question is answered by pointing, not by
characterising legal effect. AGENTS.md §4 bars this repository from
concluding a proposition of law, and docs/03's `[unestablished]`
pattern says to write around the capacity question. */
}
<p>
Mediation is conducted on a without-prejudice basis. What that means
for a particular file, and what survives it, is a question for each
party's own counsel rather than for the neutral.
</p>
</div>
</div>
</section>
{/* ---- 7. Practice areas ---------------------------------------------- */}
<section class="section reveal">
<div class="wrap">
<div class="section-head">
<SectionHeading
eyebrow="Subject matter"
level={2}
lede="Where a commercial mediation usually turns on something technical."
>
<span slot="heading">Six areas.</span>
</SectionHeading>
</div>
<div class="grid-autofit areas-grid">
{
PRACTICE_AREAS.map((area) => (
<PracticeCard
href={`/practice/${area.slug}/`}
chip={area.chip}
title={area.name}
level={3}
>
{area.blurb}
</PracticeCard>
))
}
</div>
</div>
</section>
{/* ---- 8. Fees --------------------------------------------------------- */}
<section class="section section-alt reveal">
<div class="wrap">
<div class="section-head">
<SectionHeading eyebrow="Fees" level={2}>
<span slot="heading">Published in full.</span>
</SectionHeading>
</div>
<div class="prose">
<p>
Half day and full day, with the preparation time bundled into each one
stated rather than folded into the hours. Additional parties, overtime
and the cancellation schedule are on the same page.
</p>
</div>
<div class="cta">
<Button href="/fees/" variant="ghost">The rate card &rarr;</Button>
</div>
</div>
</section>
<ContactBand />
</BaseLayout>
<style>
.hero {
padding-block-start: var(--space-9);
}
.hero-h {
margin-block: var(--space-4) var(--space-5);
font-size: var(--text-6xl);
}
.hero-lede {
max-inline-size: 58ch;
font-size: var(--text-lg);
line-height: var(--leading-body);
color: var(--text-secondary);
}
.hero-creds {
margin-block-start: var(--space-8);
}
.cta {
margin-block-start: var(--space-6);
}
.bring {
/* No `list-style: none` or `padding: 0` here — `global.css` applies both to
`ul[role='list']`, and a second copy is a second thing to keep true. */
display: grid;
gap: var(--space-5);
max-inline-size: var(--width-prose);
}
.bring li {
padding-inline-start: var(--space-5);
border-inline-start: 1px solid var(--rule);
line-height: var(--leading-body);
}
/* `.grid-autofit` (global.css) carries the columns and the `min()` guard;
this only sets the gap. One home for that reasoning, not five. */
.areas-grid {
gap: var(--space-5);
}
</style>
+36
View File
@@ -321,6 +321,42 @@ a:hover {
.section-head {
margin-block-end: var(--space-7);
}
/* THE AUTO-FIT GRID GUARD, IN ONE PLACE. `adversarial-reviewer` counted five
copies of the same five-line comment across three pages at step 4 — 25 lines
explaining 5 identical declarations — plus a sixth, differently worded copy on
`/about/`. That is this repo's own "a second copy is a second thing to keep
true", and D19's comment rule, both breached by a paragraph about a guard.
THE GUARD: `min(Nrem, 100%)`, never a bare rem. A bare rem floor is a HARD
minimum, so at a 200% default font size (root 32px — a real accessibility
setting, not page zoom) an 18rem floor becomes 576px and the track refuses to
shrink. Measured on `/`: 234px of document overflow at a 390px viewport, down
to 3px once the three grids took `min()`. docs/02 §Accessibility floor carries
the full table.
Set `--grid-min` on the element; default 18rem.
⚠️ NOT YET THE ONLY HOME, and the remaining copies are listed rather than
claimed swept. `git grep -n 'auto-fit' -- src`, 2026-08-28:
src/pages/index.astro:875 minmax(min(18rem, 100%), 1fr)
src/pages/index.astro:916 minmax(min(13rem, 100%), 1fr)
src/pages/about.astro:965 minmax(min(18rem, 100%), 1fr)
src/pages/about.astro:1007 minmax(min(16rem, 100%), 1fr)
Those four are on pages that already shipped; converting them after the
review cap would be an unreviewed change to live CSS. They move onto this
class at step 5, when `/practice/*` is in the same files. Until then a
correction here reaches three call sites, not seven — say that rather than
letting a reader believe the guard has one home. */
.grid-autofit {
display: grid;
grid-template-columns: repeat(
auto-fit,
minmax(min(var(--grid-min, 18rem), 100%), 1fr)
);
}
.section {
padding-block: var(--section-y);
}