Build and deploy / build-and-deploy (push) Failing after 4s
Pouya's rulings of 2026-09-03 (the last two D20 findings) and 2026-09-04 (the spam observation and four mitigations), in one change set. D20 finding 10 — med-arb is billed BY PHASE, each phase at the rates already published, so /fees/'s "Every figure is on this page" is true as written rather than narrowed. FEES.medArb is the single source; docs/07 §Med-arb carries the rule INTERIM against R5, and R5 now carries it back, because a derived price moves silently when a rate moves. D20 finding 13 — conduct undertaking (g), attested 2026-09-03, published as his wording verbatim on /legal/privacy/ and /contact/. The clause that raised the finding promised to DISCLOSE a conflicts check's outcome, which the attestation does not cover; it is struck. D20 now partitions 17 fixed / 2 refuted / 1 owed. Spam, 2026-09-04 — recorded in docs/05 §Observed abuse with the date and signature. A second honeypot (a decoy checkbox, own class, `hidden`, a label that tells a human not to tick it) and scoring that LABELS and never rejects: nothing is dropped, nothing new is stored, and only the operator notification changes. Q65 opens the WAF cost call. The timing floor could not be built: there is no timing check and never has been. docs/05 carries it struck, and every mechanism that would give a real per-visitor clock breaks zero-JS, handler-and-form-only, or D1. Q66. configure.mjs gains section 5 — a custom origin request policy forwarding CloudFront-Viewer-Address on /api/*. Written, dry-run against the live distribution, NOT applied. It reads the handler's own header reads and refuses to run if the whitelist omits one. And reading the live account to do it found four AGENTS.md §7 rows saying the intake backend was undeployed, two days after it went live — corrected against get-function-configuration, get-routes, get-stage, get-policy and the deployed zip, which was downloaded and read. Review: adversarial-reviewer only (claims-auditor is D20's cutover pass and has run). Round 1 five lenses, 56 findings, 7 blocking, 4 refuted by an independent refuter; round 2 four lenses, 36 findings, 33 of them defects in round 1's own repairs. Stopped at two per D19. Gates, exit status read for each: check 0 · build 0 (23 pages) · check:claims 0 · check:intake 0 · og:proof 0 · lint 0 · spam-score.test 39/39 with 6/6 mutations killed · router.test 30/30 · minifier grep 1 (clean) · lighthouse 0, no category below 95 · configure.mjs dry run 0, nothing written. Nothing deployed and nothing applied. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Md3GndFqWPzK78xAoebsg5
515 lines
20 KiB
Plaintext
515 lines
20 KiB
Plaintext
---
|
||
/**
|
||
* `/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),
|
||
},
|
||
];
|
||
---
|
||
|
||
<BaseLayout
|
||
title="Fees · Mediation and Arbitration Rates · Pouya Lajevardi"
|
||
description="The full rate card: half-day and full-day mediation, arbitration, cancellation terms and what an overrun costs. Published in full, with no ranges."
|
||
jsonLd={graph}
|
||
>
|
||
{/* ---- 1. Hero -------------------------------------------------------- */}
|
||
<section class="section hero">
|
||
<div class="wrap">
|
||
<Eyebrow dot>Fees</Eyebrow>
|
||
<h1 class="display hero-h">
|
||
Published in full, including what overruns cost.
|
||
</h1>
|
||
{
|
||
/* ⚠️ 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. */
|
||
}
|
||
<p class="hero-lede">
|
||
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}
|
||
</p>
|
||
</div>
|
||
</section>
|
||
|
||
{/* ---- 2. Mediation --------------------------------------------------- */}
|
||
<section class="section section-alt reveal">
|
||
<div class="wrap">
|
||
<div class="section-head">
|
||
<SectionHeading
|
||
eyebrow="Mediation"
|
||
level={2}
|
||
lede="One rate for every matter. Preparation is bundled into the fee and is capped."
|
||
>
|
||
<span slot="heading">Half day or full day.</span>
|
||
</SectionHeading>
|
||
</div>
|
||
<dl class="rates">
|
||
{
|
||
MEDIATION_ROWS.map((row) => (
|
||
<div class="rate">
|
||
<dt>
|
||
<span class="rate-item">{row.item}</span>
|
||
<span class="rate-detail">{row.detail}</span>
|
||
</dt>
|
||
<dd>{row.fee}</dd>
|
||
</div>
|
||
))
|
||
}
|
||
</dl>
|
||
</div>
|
||
</section>
|
||
|
||
{/* ---- 3. Arbitration ------------------------------------------------- */}
|
||
<section class="section reveal">
|
||
<div class="wrap">
|
||
<div class="section-head">
|
||
<SectionHeading
|
||
eyebrow="Arbitration"
|
||
level={2}
|
||
lede="Sole, party-appointed and co-arbitration appointments, in commercial matters."
|
||
>
|
||
<span slot="heading">Hourly, by hearing day, or flat.</span>
|
||
</SectionHeading>
|
||
</div>
|
||
<dl class="rates">
|
||
{
|
||
ARBITRATION_ROWS.map((row) => (
|
||
<div class="rate">
|
||
<dt>
|
||
<span class="rate-item">{row.item}</span>
|
||
<span class="rate-detail">{row.detail}</span>
|
||
</dt>
|
||
<dd>{row.fee}</dd>
|
||
</div>
|
||
))
|
||
}
|
||
</dl>
|
||
{
|
||
/* 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. */
|
||
}
|
||
<p class="scope-note">
|
||
Family arbitration under the <em>Family Law Act</em> is not offered, and family
|
||
law matters are not accepted.
|
||
</p>
|
||
</div>
|
||
</section>
|
||
|
||
{/* ---- 4. Med-arb ------------------------------------------------------ */}
|
||
<section class="section section-alt reveal">
|
||
<div class="wrap">
|
||
<div class="section-head">
|
||
<SectionHeading
|
||
eyebrow="Med-arb"
|
||
level={2}
|
||
lede="One appointment, two processes. Each phase is charged at the rates for that process."
|
||
>
|
||
<span slot="heading">Billed by phase.</span>
|
||
</SectionHeading>
|
||
</div>
|
||
{
|
||
/* NO `<dl class="rates">` 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. */
|
||
}
|
||
<ul class="notes" role="list">
|
||
<li>{FEES.medArb.rule}</li>
|
||
<li>{FEES.medArb.noSeparateFee}</li>
|
||
<li>{FEES.medArb.termsApply}</li>
|
||
</ul>
|
||
</div>
|
||
</section>
|
||
|
||
{/* ---- 5. Other services ---------------------------------------------- */}
|
||
<section class="section reveal">
|
||
<div class="wrap">
|
||
<div class="section-head">
|
||
<SectionHeading
|
||
eyebrow="Also offered"
|
||
level={2}
|
||
lede="Charged hourly, with an estimate agreed in the terms of appointment."
|
||
>
|
||
<span slot="heading">Three things beside the two processes.</span>
|
||
</SectionHeading>
|
||
</div>
|
||
<dl class="rates">
|
||
<div class="rate">
|
||
<dt>
|
||
<span class="rate-item">Early neutral evaluation</span>
|
||
{
|
||
/* §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. */
|
||
}
|
||
<span class="rate-detail">
|
||
A reasoned assessment of the merits, delivered to both parties
|
||
together. Never advice to one of them.
|
||
</span>
|
||
</dt>
|
||
<dd>{money(FEES.hourly)}<span class="per"> / hour</span></dd>
|
||
</div>
|
||
<div class="rate">
|
||
<dt>
|
||
<span class="rate-item">Dispute-system design</span>
|
||
<span class="rate-detail">
|
||
Advising an organisation on how its future disputes should be
|
||
handled, before there are any.
|
||
</span>
|
||
</dt>
|
||
<dd>{money(FEES.hourly)}<span class="per"> / hour</span></dd>
|
||
</div>
|
||
<div class="rate">
|
||
<dt>
|
||
<span class="rate-item">Pre-dispute technical advisory</span>
|
||
{
|
||
/* 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. */
|
||
}
|
||
<span class="rate-detail">
|
||
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.
|
||
</span>
|
||
</dt>
|
||
<dd>{money(FEES.hourly)}<span class="per"> / hour</span></dd>
|
||
</div>
|
||
</dl>
|
||
</div>
|
||
</section>
|
||
|
||
{/* ---- 6. Cancellation ------------------------------------------------ */}
|
||
<section class="section section-alt reveal">
|
||
<div class="wrap">
|
||
<div class="section-head">
|
||
<SectionHeading
|
||
eyebrow="Cancellation"
|
||
level={2}
|
||
lede="A reserved date is time that cannot be given to another matter. The schedule is published so it is never a surprise."
|
||
>
|
||
<span slot="heading">If a date is cancelled.</span>
|
||
</SectionHeading>
|
||
</div>
|
||
<dl class="rates">
|
||
{
|
||
FEES.cancellation.map((row) => (
|
||
<div class="rate">
|
||
<dt>
|
||
<span class="rate-item">{row.window}</span>
|
||
</dt>
|
||
<dd class="dd-text">{row.fee}</dd>
|
||
</div>
|
||
))
|
||
}
|
||
</dl>
|
||
<ul class="notes" role="list">
|
||
{FEES.cancellationNotes.map((note) => <li>{note}</li>)}
|
||
</ul>
|
||
</div>
|
||
</section>
|
||
|
||
{/* ---- 7. Terms -------------------------------------------------------- */}
|
||
<section class="section section-inverse reveal">
|
||
<div class="wrap">
|
||
<div class="section-head">
|
||
<SectionHeading eyebrow="Terms" level={2}>
|
||
<span slot="heading">How the account works.</span>
|
||
</SectionHeading>
|
||
</div>
|
||
<ul class="notes" role="list">
|
||
<li>{FEES.taxNote}</li>
|
||
{FEES.terms.map((term) => <li>{term}</li>)}
|
||
<li>
|
||
Travel outside the Greater Toronto Area is billed separately, or
|
||
bundled at a day rate stated in the terms of appointment.
|
||
</li>
|
||
<li>
|
||
Everything above is confirmed in the terms of appointment before an
|
||
engagement begins. Nothing on this page is an appointment.
|
||
</li>
|
||
</ul>
|
||
<div class="cta">
|
||
<Button href="/contact/" variant="gold"
|
||
>Request a consultation →</Button
|
||
>
|
||
<Button href="/process/" variant="ghost"
|
||
>How an engagement runs →</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);
|
||
}
|
||
|
||
/* --- The rate rows ---------------------------------------------------- */
|
||
|
||
/* A `<dl>`, not a `<table>`. Each row is one item and its price — a
|
||
term-and-value pair — and a two-column table of eight rows reflows badly on
|
||
a phone, where the price ends up under a wrapped item name with no
|
||
alignment left to carry the association. The `<dt>`/`<dd>` pair keeps that
|
||
association semantically whatever the layout does. */
|
||
.rates {
|
||
display: grid;
|
||
gap: 0;
|
||
max-inline-size: 56rem;
|
||
border-block-start: 1px solid var(--border);
|
||
}
|
||
.rate {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
justify-content: space-between;
|
||
align-items: baseline;
|
||
gap: var(--space-3) var(--space-5);
|
||
padding-block: var(--space-5);
|
||
border-block-end: 1px solid var(--border);
|
||
}
|
||
.rate dt {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-2);
|
||
/* Leaves room for the fee on one line at tablet width and up, and wraps
|
||
under it below that. */
|
||
flex: 1 1 22rem;
|
||
}
|
||
.rate-item {
|
||
font-size: var(--text-lg);
|
||
line-height: var(--leading-snug);
|
||
}
|
||
.rate-detail {
|
||
font-size: var(--text-sm);
|
||
line-height: var(--leading-body);
|
||
color: var(--text-meta);
|
||
max-inline-size: 52ch;
|
||
}
|
||
.rate dd {
|
||
font-family: var(--font-serif);
|
||
font-size: var(--text-2xl);
|
||
line-height: var(--leading-tight);
|
||
white-space: nowrap;
|
||
}
|
||
/* The cancellation column is a sentence, not a figure, so it takes body type
|
||
and is allowed to wrap. */
|
||
.rate .dd-text {
|
||
flex: 1 1 16rem;
|
||
font-family: var(--font-sans);
|
||
font-size: var(--text-base);
|
||
line-height: var(--leading-body);
|
||
color: var(--text-secondary);
|
||
white-space: normal;
|
||
}
|
||
.per {
|
||
font-family: var(--font-sans);
|
||
font-size: var(--text-sm);
|
||
color: var(--text-meta);
|
||
}
|
||
|
||
.scope-note {
|
||
margin-block-start: var(--space-6);
|
||
max-inline-size: var(--width-prose);
|
||
font-size: var(--text-base);
|
||
line-height: var(--leading-body);
|
||
color: var(--text-secondary);
|
||
}
|
||
|
||
.notes {
|
||
/* No `list-style: none` or `padding: 0` — `global.css` applies both to
|
||
`ul[role='list']`, and a second copy is a second thing to keep true. */
|
||
display: grid;
|
||
gap: var(--space-4);
|
||
margin-block-start: var(--space-6);
|
||
max-inline-size: var(--width-prose);
|
||
}
|
||
.notes li {
|
||
padding-inline-start: var(--space-5);
|
||
border-inline-start: 1px solid var(--rule);
|
||
line-height: var(--leading-body);
|
||
}
|
||
|
||
.cta {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: var(--space-3) var(--space-4);
|
||
margin-block-start: var(--space-8);
|
||
}
|
||
</style>
|