--- /** * `/fees/` — build step 9. Spec: docs/01 §`/fees/`, docs/03 §Fees, * **docs/07-fees.md is the authority on every number here.** * * ⚠️ **EVERY FIGURE IS INTERPOLATED FROM `FEES`. NOT ONE IS TYPED.** This is the * page D8 commits to and the one where a hand-typed number would be an incorrect * price rather than an untidy fact. `docs/07` §All parameters confirmed sets the * publication rules the interpolation has to satisfy, and two of them are * wording rather than value: * * 1. **The preparation allowance is CAPPED and must READ as capped** — * *"including **up to** 2 hours of preparation"*. Never "including 2 hours", * which sells an entitlement, and never "preparation included", which sells * an uncapped one. `/for-parties/` shipped the flat form for one pass, on the * one page written for a reader with no counsel to catch it. * 2. **The session cap and the preparation allowance are DIFFERENT THINGS with * different nouns** — `hours` is time in the session, `prepIncluded` is * preparation bundled into the fee. Folding them into one figure is the * ambiguity Q58 was opened to fix, and it was an ambiguity in `docs/07` * itself rather than in any copy. * * ✅ **Q59 IS RULED AND THIS PAGE IS WHY IT MATTERED — Pouya, 2026-08-31.** * Overtime runs from the **session cap**: the fourth hour of a half day, the * seventh of a full day. Until that ruling this page could not publish the * $500 rate at all, because a rate printed beside "up to 3 hours" defines its * own trigger by adjacency and there was no other quantity for it to attach to. * * ⚠️ **AND THE RULING'S SECOND HALF IS NOT DECORATION — IT IS WHAT KEEPS THE * PAGE FROM READING AS AN ARITHMETIC MISTAKE.** `FEES.mediation.reservation`: * *a full day reserves the day; half-day overtime is subject to availability.* * Without it a reader adds up `2000 + 500 × 3 = 3500` against `4000` and * concludes the full-day rate is simply worse — which is a real feature of D14's * figures (§12 R5 carries it, with the table in `docs/07` §Recorded dissent) and * is answered by what the full-day fee actually buys. So the reservation * sentence ships **adjacent to the overtime row**, not in a footnote. Same * structural rule as `PROCESS_FRAMING` beside the five timings under Q43. * * ✅ **MED-ARB IS PRICED HERE AS OF 2026-09-03, AND IT CARRIES NO FIGURE.** * Pouya's ruling closing D20 finding 10: it is billed **by phase**, each phase * at the rates already on this page. The finding was that the hero promises * *"Every figure is on this page"* while §4 Offerings carries a Med-Arb row * that `docs/07` priced nowhere — a promise wider than the card. It is closed by * pricing the offering, not by narrowing the promise, so the hero sentence is * unchanged and is now true as written. **Do not give the section a rate row:** * a med-arb figure would be a fourth price for a process priced twice, and the * first thing it would do is disagree with one of them. `FEES.medArb` holds the * three sentences; `docs/07` §Med-arb holds the rule. INTERIM, reviewed at R5. * * ⚠️ **NO TRIBUNAL-SECRETARY RATE AND NO SETTLEMENT COUNSEL.** Both are struck * rows in §4 Offerings — the first removed by Pouya from D14, the second by him * as his own error in `docs/01`. **A rate on a fee page is an offer**, which is * exactly why they are struck here rather than merely unpriced. * * ⚠️ **ARBITRATION IS SCOPED COMMERCIAL, MEDIATION IS NOT.** The asymmetry is * designed (Q39, Q56): family arbitration in Ontario carries prescribed training * and is separately NOT OFFERED, so the scope on the arbitration rows is a legal * gate. Mediation has no equivalent gate and is unscoped on purpose. A later * editor tidying these into a matching pair would reintroduce the defect. */ import BaseLayout from '../layouts/BaseLayout.astro'; import Button from '../components/Button.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 { pageGraph } from '../data/schema'; import { FEES } from '../data/site'; const ldImage = await getImage({ src: ogDefault, format: 'jpeg', width: 1200, height: 630, }); /* No `Service` node, and no `Offer` node either. The Person alone — the `/practice/` and `/process/` shape. `/mediation/` and `/arbitration/` already carry the `Service` nodes for what is priced here, and a second one on this path would put a duplicate `@id` in the graph. An `Offer` with `price` would be the obvious addition and is deliberately not made: schema.org's `Offer` models a single price for a single item, and every row below is conditional on session length, party count and format — a machine-readable $2,000 with none of those conditions attached is a worse claim than no claim. ⚠️ AND `/`'s NODE CARRIES NO PRICE EITHER — this comment said `ProfessionalService.priceRange` "carries the range instead", and that field was removed the same day for mixing units and understating its own floor. Nothing on this site states a price in machine-readable form, deliberately: every figure here is conditional on session length, party count or format, and a number without those conditions is a worse claim than no number. Found by `adversarial-reviewer` round 2 — a justification resting on a field that no longer exists is how an `Offer` node gets added by the next reader. */ const graph = pageGraph(new URL(ldImage.src, Astro.site).href); const money = (amount: number) => new Intl.NumberFormat('en-CA', { style: 'currency', currency: FEES.currency, maximumFractionDigits: 0, }).format(amount); const { halfDay, fullDay } = FEES.mediation; /* The two mediation rows, built from the constants so the noun and the "up to" travel with the number rather than being retyped beside it. */ const MEDIATION_ROWS = [ { item: `Half day — up to ${halfDay.hours} hours of session`, detail: `Fee includes up to ${halfDay.prepIncluded} hours of preparation.`, fee: money(halfDay.amount), }, { item: `Full day — up to ${fullDay.hours} hours of session`, detail: `Fee includes up to ${fullDay.prepIncluded} hours of preparation.`, fee: money(fullDay.amount), }, { item: 'Each party beyond two', detail: 'Per party, added to the session fee.', fee: money(FEES.mediation.additionalParty), }, { item: 'Overtime, per hour', /* Q59: the trigger is the SESSION cap, and the reservation point ships in the same cell as the rate. See the header for why it is not a footnote. */ detail: `Charged beyond the ${halfDay.hours} or ${fullDay.hours} session hours the fee covers. ${FEES.mediation.reservation}`, fee: money(FEES.mediation.overtimePerHour), }, ]; const ARBITRATION_ROWS = [ { item: 'Hourly', detail: 'Procedural work, document review, award writing.', fee: money(FEES.arbitration.perHour), }, { item: 'Hearing day', detail: 'In person or by video, at the same rate.', fee: money(FEES.arbitration.hearingDay), }, { item: 'Documents-only or expedited — simple', detail: 'Flat fee.', fee: money(FEES.arbitration.documentsOnlySimple), }, { item: 'Documents-only or expedited — complex', detail: 'Flat fee.', fee: money(FEES.arbitration.documentsOnlyComplex), }, ]; --- {/* ---- 1. Hero -------------------------------------------------------- */}
Fees

Published in full, including what overruns cost.

{ /* ⚠️ THIS SENTENCE QUOTED A PHRASE THE SPEC BARS, AND THE QUOTATION WAS THE PROBLEM. It read: *No ranges, no "starting from", and nothing that has to be asked for.* Two defects in one clause. (1) It defines the page against an unnamed practice — an implied comparative, which Q41(b) answers: assert his capability, never the field's. (2) It plants the literal string `starting from` in `dist/`, where a future sweep for `docs/03`'s "no 'starting from' evasions" would hit it and read a negation as a breach — the `I aLSO practise` / `the pLEADINGs` shape, manufactured on purpose by the copy. Stating what the page DOES needs no comparison and leaves nothing to trip over. */ }

One rate for all mediation matters, whatever the subject. Every figure is on this page, and none of it has to be asked for. {FEES.taxNote}

{/* ---- 2. Mediation --------------------------------------------------- */}
Half day or full day.
{ MEDIATION_ROWS.map((row) => (
{row.item} {row.detail}
{row.fee}
)) }
{/* ---- 3. Arbitration ------------------------------------------------- */}
Hourly, by hearing day, or flat.
{ ARBITRATION_ROWS.map((row) => (
{row.item} {row.detail}
{row.fee}
)) }
{ /* The Q39 scope, stated on the page rather than left to the lede. §4 Offerings carries a NOT OFFERED row for family arbitration, and `/practice/shareholder/` makes the same exclusion in one sentence on Pouya's instruction — "one sentence, not a section", because a disclaimer that grows reads as defensive. */ }

Family arbitration under the Family Law Act is not offered, and family law matters are not accepted.

{/* ---- 4. Med-arb ------------------------------------------------------ */}
Billed by phase.
{ /* NO `
` HERE, AND THE ABSENCE IS THE POINT — see the header. Every other section on this page pairs an item with a figure; this one has no figure of its own, and giving it a row would mean inventing one. The three sentences come from `FEES.medArb` so the rule lives beside the numbers it points at rather than in this template. */ }
  • {FEES.medArb.rule}
  • {FEES.medArb.noSeparateFee}
  • {FEES.medArb.termsApply}
{/* ---- 5. Other services ---------------------------------------------- */}
Three things beside the two processes.
Early neutral evaluation { /* §4's ENE row and `docs/01` §`/practice/` both require this framing, and `docs/07` repeats it for this page in terms: "nothing on `/fees/` may read as a rate for advising one of them." ENE is the offering nearest §4's NOT-NEGOTIABLE boundary, because a neutral assessment of the merits sits closest to providing legal services. */ } A reasoned assessment of the merits, delivered to both parties together. Never advice to one of them.
{money(FEES.hourly)} / hour
Dispute-system design Advising an organisation on how its future disputes should be handled, before there are any.
{money(FEES.hourly)} / hour
Pre-dispute technical advisory { /* THE CONFLICT CAUTION IS NOT OPTIONAL. §4's row: "no copy may imply the offering is free of that tension", and it names `/practice/`'s strip as where the temptation would arise. A fee page is the second such place, because a priced line reads as a product. Advisory work for one organisation can conflict against a later appointment in the same matter. */ } Technical review before a dispute exists. Taking it on can rule me out of a later appointment in the same matter, and that is settled in writing before the work starts.
{money(FEES.hourly)} / hour
{/* ---- 6. Cancellation ------------------------------------------------ */}
If a date is cancelled.
{ FEES.cancellation.map((row) => (
{row.window}
{row.fee}
)) }
    {FEES.cancellationNotes.map((note) =>
  • {note}
  • )}
{/* ---- 7. Terms -------------------------------------------------------- */}
How the account works.
  • {FEES.taxNote}
  • {FEES.terms.map((term) =>
  • {term}
  • )}
  • Travel outside the Greater Toronto Area is billed separately, or bundled at a day rate stated in the terms of appointment.
  • Everything above is confirmed in the terms of appointment before an engagement begins. Nothing on this page is an appointment.