/* ⚠ THIS FILE IS NO LONGER GENERATED, AND THE HEADER THAT SAID IT WAS IS A
   LOADED GUN. Kept and corrected rather than deleted, because the instruction
   it carried — "edit the prototype and re-run, or adopt this file and delete
   the tool, but do not edit both" — was sound, and both is exactly what has
   happened.

   Originally generated from Design/directions/audience.py by
   Web/theme/tools/port.py. Measured 28 August: **18 selectors exist here and
   not in the prototype** — the whole `.pullquote` block (0.4.8), `.social` and
   `.follow` (0.4.8), `.signature h2` (0.4.8), and the three sections added in
   0.4.17. Four exist in the prototype and not here.

   **So re-running port.py today would silently delete the pull-quote styling
   from five doors, the social links from the contact page, and this release.**
   Nothing would error; the CSS would simply be missing and the pages would
   render as unstyled versions of themselves.

   This file is the source of truth. The prototype is a historical record.
   port.py has not been deleted because that is RJ's call, not something to do
   inside an unrelated release — but it must not be run against this file.
   Flagged in _PROJECT-RECORD.md §13. */

/* The home page's h1 is two words — "Find yourself." — and is set at up to
   104px to carry that. An audience headline is a sentence, and at 104px a
   sentence stacks into a column of fragments. Smaller here, and only here. */
/* The home page's h1 is two words — "Find yourself." — at up to 104px. This
   one is a fourteen-word sentence, and at 66px it stacked into five lines and
   read as a column of fragments. Smaller, and the copy column takes more of
   the grid so the line count comes down further. */
/* ── THE TYPE SCALE ON A DOOR PAGE ────────────────────────────────────────────
   RJ, 26 August: *"The headlines all look similar sized and big. We need some
   typographic play for relief and editorial touch."*

   Measured on the live Individuals page before changing anything, and he was
   right in a way that was worse than it looked:

     · **every h2 rendered at 58px** — seven of them, identical
     · **the h1 rendered at 52px**, so the page's own title was the SMALLEST
       display size on the page. The hierarchy was inverted.
     · the challenge figure sat at 54px

   Seven display sizes inside a six-pixel band, and then a cliff straight down
   to the 21px lede with nothing between. That is why it read as flat: there was
   no scale, only one size used repeatedly.

   THE PRINCIPLE HERE IS THAT SIZE FOLLOWS THE JOB, NOT THE TAG. A heading that
   is an aphorism gets to be large because it is read in one glance. A heading
   that is a sentence gets smaller, because at 58px a 75-character sentence is
   not read, it is endured. So the scale is assigned per SECTION — a section's
   job does not change, which is what makes this deterministic rather than
   something to hand-tune per page.

   ⚠ THIS APPLIES TO EVERY DOOR, NOT ONLY INDIVIDUALS. Corporates had the same
   inverted hierarchy and gets the same correction. */

/* The page's own title, and now the largest thing on it. */
.hero h1{font-size:clamp(38px,5.2vw,74px);max-width:15ch}

/* Aphorisms — short, declarative, read in one glance. These are the moments:
   "The work is meant to end." · "What they felt."

   ⚠ `noticed` WAS IN HERE AND IS NOT ANY MORE — 0.4.19. RJ, on the page as
   shipped: *"the header sizes are not working"*, and then, decisively,
   *"'Typical wellbeing programmes have limitations' — this onwards the sizes
   are good."* Everything from `limits` down is 38px with `voices` at 50, and he
   is content with it. **So the fault is confined to what sits above `limits`**,
   and the only heading up there that is not 38px was this one.

   *"Have you noticed?"* is three words. At 50px it was the loudest thing on the
   page after the h1 — louder than the answer the page turns on — for a section
   that only asks the reader to pause. It drops to the body tier.

   ⚠ I HAD ALSO DRAFTED A FULL RE-TIERING BY ARGUMENTATIVE IMPORTANCE — `method`
   up to 52, `voices` and `clients` down to 30, `close` to 44. **It was discarded
   unshipped once RJ said everything from `limits` onward was right.** Recorded
   because the reasoning was seductive and wrong in a specific way: it would have
   restyled `voices`, `clients` and `close` on Corporates and Individuals to
   solve a complaint about the top of one page. Fix what was reported. */
.blocks h2,.voices h2,.outcomes-section h2{font-size:clamp(30px,3.6vw,50px);max-width:16ch}

/* ⚠ SUPERSEDED 0.4.18 — `argument` NOW SITS IN THE 26–38px TIER BELOW. The
   note that follows is kept because its reasoning was sound and the premise
   simply stopped being true.

   It capped `argument` at 33px on the grounds that the heading is *"always
   long"*. On 28 August RJ replaced the Institutions one with **"What most
   schools overlook."** — five words. The cap then made the smallest heading on
   the page sit above its longest section, with 38px headings under it: the
   inverted hierarchy this whole block exists to prevent, arrived at from the
   opposite direction.

   Lifted to 38px on all three doors rather than fixed with a per-page modifier.
   The longest surviving argument heading is Individuals' 92-character sentence,
   and 38px is a long way from the 58px the cap was written to protect it from —
   so the original concern does not bite at the new size. **A rule justified by
   the length of the copy needs revisiting when the copy changes.**

   The cap it replaced was already the second attempt at this. The first had
   `close` down here beside `argument`, and looking at two doors is what showed
   that to be wrong: the closing heading is a long sentence on Individuals but
   reads *"Begin here."* on Corporates — eleven characters. **Sizing by section
   works because a section's JOB is stable; it stops working the moment the same
   job is written at wildly different lengths.** That is exactly what has now
   happened to `argument`, which is why it has moved rather than been patched.

   The measure and leading survive the move, but the rule carrying them had to
   move WITH it. ⚠ `.argument h2{max-width:30ch}` sat above the tier rule at the
   same specificity — 0,1,1 either way — so the tier's `max-width:22ch` would
   have won on source order and quietly narrowed it. Caught by reading the cascade
   rather than by looking, because 22ch and 30ch differ by about one word a line.
   It now sits below the tier. */

/* Section headings that label rather than argue, and the closing ask.

   ⚠ `limits` AND `method` WERE ADDED IN 0.4.17 AND LEFT OUT OF THIS SCALE,
   WHICH IS THE FAULT THIS WHOLE BLOCK EXISTS TO PREVENT. Unsized, they fell
   through to main.css's bare `h2{font-size:clamp(34px,4.4vw,58px)}` and
   rendered at **58px** — the largest h2 on the site, on the two least important
   headings on the page, beside an `outcomes` heading at 38px. Measured at 1440,
   not noticed by eye, because a full-page screenshot scaled down hides a 20px
   difference.

   **A new section is not finished until it is in this list.** The note at the
   top of this stylesheet says size follows the section's job; a section that is
   in no size rule has no job assigned and silently takes the loudest one.

   They sit together and at the same size deliberately: they are a matched pair
   — three failings, three answers — and equal size is what lets a reader feel
   the pairing without being told about it. */
/* ⚠ `.practices h2` ADDED 0.4.67, AND ITS ABSENCE WAS A DEFECT SHIPPED IN
   0.4.66. A section not listed here falls through to main.css's bare
   `h2{clamp(34px,4.4vw,58px)}` — so the new Therapies section rendered at 58px
   and was the LOUDEST heading on Individuals, above sections that matter more.
   Nothing errored. This is the identical mistake as Home's closing heading,
   made in the same session that wrote it down. **A new section must be added to
   a size rule as well as a margin rule; the margin note below catches only
   half of it.**

   ⚠ `.outcomes-section h2` LEFT THIS TIER IN 0.4.67 — RJ: *"this header needs
   to be more prominent. Its a key section."* It joined `.blocks`/`.voices` at
   50px rather than taking a new size, so the page still has two heading tiers
   and not three. */
.session h2,.clients h2,.close h2,
.limits h2,.method h2,.practices h2,.argument h2,.noticed h2{
  font-size:clamp(26px,2.8vw,38px);max-width:22ch}
/* Below the tier on purpose — see the note above. */
.argument h2{max-width:30ch;line-height:1.3}

/* The one deliberate statement, kept below the h1 so it supports rather than
   competes. It carries its own two-tone treatment already. */
.challenge .figure{font-size:clamp(24px,2.9vw,42px)}

/* ── SVã SIGNATURE SESSIONS ────────────────────────────────────────────────────
   A named, priced session is a different object from anything else on the site:
   it has a heading, a paragraph, a number and an instruction, and a visitor
   compares two of them side by side. `.posts` is the nearest existing pattern
   and lives in journal.css, which this template does not load — so it is drawn
   here rather than borrowed, which is the whole reason the stylesheet map in
   functions.php exists.

   `auto-fit` rather than a fixed three columns: the page ships with TWO
   sessions because Oil Healing was pulled for want of a description, and it
   goes to three when that arrives. A hardcoded `1fr 1fr 1fr` would leave a hole
   today and need editing later. */
.signature{list-style:none;margin:0;padding:0;display:grid;
  grid-template-columns:repeat(auto-fit,minmax(280px,1fr));
  gap:clamp(28px,3.6vw,60px)}
.signature li{border-top:1px solid var(--line);padding-top:22px}
/* The picture sits ABOVE the hairline-topped block rather than inside it, so
   the rule still reads as the top edge of the written entry. A session without
   one simply starts at the rule — no gap, no placeholder. */
.signature figure{margin:0 0 20px}
.signature figure img{width:100%;display:block;
  /* ⚠ A FIXED RATIO, BECAUSE THE PICTURES WILL NOT ALL BE THE SAME SHAPE.
     Measured on the live page: two frames are 1600×1067 and the drum circle
     is a 600×600 square borrowed from the old site, so with `height:auto` the
     square column ran 297×297 against 297×198 and pushed its heading **99px
     lower than the other two**. Three columns, three headings, none of them
     level.

     `object-fit:cover` crops rather than distorts, and 3:2 is chosen because
     it is the shape of the two photographs that were shot for this. The cost
     is a little headroom off the top and bottom of any square picture, which
     is the right thing to lose. The alternative — asking every future picture
     to arrive pre-cropped — is a rule nobody will remember. */
  aspect-ratio:3/2;object-fit:cover}
/* ⚠ h2 SINCE 0.4.8, AND THE SIZE IS UNCHANGED BY DESIGN. These were h3 and the
   page outlined H1 H3 H3 H3 H2 — a level announced that was never opened. The
   selector is (0,1,1) either way, so it still beats main.css's bare
   `h2{font-size:clamp(34px,4.4vw,58px)}` and the size below still wins. Size
   follows the section's job on this site, not the tag; that is what makes
   fixing an outline free. */
.signature h2{font-family:'Cormorant Garamond',serif;font-weight:300;
  font-size:clamp(22px,2.2vw,29px);line-height:1.25;margin-bottom:12px}
.signature p{font-size:var(--t-detail);line-height:1.72;color:var(--soft);margin-bottom:14px}
/* The price is the thing a visitor came to this page for, so it is set in the
   display face rather than in the body size the write-up uses. */
.signature .meta{font-family:'Cormorant Garamond',serif;font-size:19px;
  color:var(--ink);margin-bottom:14px}
.signature .book{font-size:11px;letter-spacing:.13em;text-transform:uppercase;
  color:var(--sage);line-height:1.6;margin:0}
.signature .book a{color:inherit}
/* ── THE BOOKING CALL-OUT, 0.4.96 ────────────────────────────────────────────
   ⚠⚠ SWITCHED OFF ON THE LIVE PAGE SINCE 6 SEPTEMBER AND THE CODE IS KEPT ON
   PURPOSE. RJ, an hour after asking for it to be resized: *"Lets drop this
   line. Makes no sense. Contact is already there in footer."* **It is off by an
   empty `cta` field, not by deleted code** — `svaflo_section_sessions_list()`
   renders no panel when both `cta` and `book_note` are empty, so switching it
   back on is one field in the admin and no release. **Do not "tidy" this rule
   away**; deleting it makes the return of one sentence a theme build.

   The styling below is the corrected version, not the one that shipped in
   0.4.96 — smaller and vertically centred, per the instruction that immediately
   preceded the decision to drop it. If the panel ever comes back it comes back
   right.

   One panel where four identical booking lines used to sit, one under each
   therapy. It takes the two cells the last row leaves empty — measured live at
   1710px, three columns of 297px and a 60px gap, so 654 × 283px of blank paper
   beside the fourth card.

   ⚠ IT KEEPS THE HAIRLINE AND TAKES NO GROUND OF ITS OWN, and both of those
   were the second answer. The first draft gave it `background:var(--paper-2)`
   and 28px of padding and called the hairline wrong in a comment — then the
   layout was injected into the live page and photographed, which showed two
   faults at once. **The panel was invisible**: `.sessions` already sits on
   paper-2, so the fill matched the ground exactly. And the padding pushed the
   text 30px in from the column edge, so the booking line no longer lined up
   with the therapy heading directly above it.

   ⚠ A FILL WOULD HAVE BEEN WRONG EVEN IF IT HAD SHOWN. The grounds alternate by
   rendered index — that is what moved this section onto paper-2 when the
   pullquote went below the list in 0.4.61 — so a hardcoded ground is a colour
   that is right until someone reorders a section.

   So: no fill, no padding, and the `border-top` and `padding-top` inherited
   from `.signature li` are left alone. The panel reads as part of the row it
   sits in, which is what it is.

   ⚠ IT STRETCHES AND CENTRES, AND THIS IS THE SECOND ANSWER TOO. 0.4.96 shipped
   `align-self:start` on the argument that centring one line in 283px would read
   as a rendering fault. RJ, 6 September: *"Line is too big. Should be smaller
   and centered vertically to Art Therapy block."* **He is right, and the
   argument was wrong because it assumed the 26px line** — at that size the panel
   was a second heading competing with the therapy beside it. Smaller, the
   centred line reads as a caption to the whole row rather than as a card with
   its content missing.

   ⚠ `padding-top:0`, AND WITHOUT IT THE CENTRING IS 12px OUT. `.signature li`
   opens with 22px of padding under its hairline, which pushes the flex box down
   and takes the optical centre with it. Zeroing it puts the line on the row's
   true middle. Measured live: the booking line centres at y=510 against Art
   Therapy's 509. */
.signature .book-callout{grid-column:span 2;align-self:stretch;padding-top:0;
  display:flex;flex-direction:column;justify-content:center}
.signature .book-callout .note{font-size:var(--t-detail);line-height:1.72;
  color:var(--soft);margin:0 0 14px;max-width:34rem}
/* 19px Cormorant — deliberately the same size as `.signature .meta`, the price
   and duration line inside the cards. It is the other piece of transactional
   detail on this page, so it is set at the same weight rather than at a size of
   its own. Not the 11px micro-label it was when there were four of it, and not
   the 26px statement 0.4.96 tried. */
.signature .book-callout .book{font-family:'Cormorant Garamond',serif;
  font-size:19px;letter-spacing:0;text-transform:none;line-height:1.4}
/* A 2:3 frame is the tallest thing in the hero, so the columns start on
   the same line rather than floating against each other's middles —
   the same decision as the home page's hero. */
.hero .wrap{align-items:start;grid-template-columns:7fr 5fr}
.hero-figure{max-width:400px;margin-left:auto}

/* ⚠ A HERO WITH NO PICTURE, 0.4.17 — AND OMITTING THE FIGURE IS NOT THE FIX.
   The columns above are declared unconditionally, so a hero whose figure has
   been dropped keeps its 5fr track and simply leaves it empty. Measured on live
   `/institutions/` before this release: `639.328px 456.672px` on an 1180px
   wrap, with 457px of nothing beside 639px of squeezed copy.

   Signature Sessions guarded its figure in 0.4.16 and was reported fixed on
   that basis. It was not — the column was still standing. This rule is the part
   that was missing, and it is why the guard and the class always ship together.

   `!important` is deliberate and narrow. main.css declares `.hero .wrap` at the
   same specificity as this file and load order between them is set in build.py,
   which is exactly the collision documented at the foot of this stylesheet. A
   modifier that loses to the rule it exists to override is worse than no
   modifier. */
.hero--nopic .wrap{grid-template-columns:1fr !important}
.hero--nopic .hero-copy{max-width:52rem}
/* The size is shared — `p.lede` in build.py — but the measure is not, and
   should not be: the home hero's 34ch sits under a two-word headline in a
   narrow column, while this page's copy column is wider and the same measure
   left the text filling a little over half of it. That is what RJ meant by
   chunky. Wider here, size untouched. */
.hero-copy .lede{max-width:46ch}

/* `p.person-note` carries a hairline above it, which is right on the home page
   where it separates a claim from the condition under it. Here the same class
   is used four times as a plain note beside full-width tables, and the short
   52ch rule floating above each one reads as a mistake rather than as
   structure. Hairline off, measure opened. */
.argument .person-note,.session .person-note,
.voices .person-note,.clients .person-note{border-top:0;padding-top:0;max-width:62ch}
.outcomes + .person-note{margin-top:24px}
/* The home lede sits under a two-word headline in a narrow column. On these
   pages it introduces a full-width table, and 32ch beside that looks starved. */
.argument .lede,.session .lede,.voices .lede,.blocks .lede,
.limits .lede,.method .lede,.practices .lede,.outcomes-section .lede{max-width:48ch}
/* The outcomes heading already carries a bottom margin sized for a list
   starting directly under it; with a lede between them that gap lands in the
   wrong place. Pulled up, and the lede carries the space instead. */
.outcomes-section .lede{margin:-14px 0 4px}

/* ── THE SECTIONS ADDED FOR SCHOOLS & INSTITUTIONS, 0.4.17 ────────────────────

   ⚠ ALL THREE NEED THEIR HEADING MARGIN SET EXPLICITLY, AND THIS IS THE FOURTH
   TIME. main.css resets `h1,h2,h3,p,ul,figure,blockquote{margin:0}`, so a new
   section's heading sits flush against whatever follows it — measured at 0px on
   `.team`, on `.blocks`, and it would have happened here three more times. The
   note above `.session h2` says so and was written after the second occurrence.

   The lists themselves need nothing: `limits` and `method` both render
   `dl.outcomes`, which is already styled above. That is the whole reason the
   pair was built on that class rather than on `.facts`. */
/* ⚠ `.practices` JOINS THESE TWO, AND IT IS THE FIFTH TIME THIS FILE HAS HAD
   TO SAY IT: main.css resets h2 margins to 0, so a new section's heading sits
   flush against whatever follows unless it is listed here. Measured at 0px on
   `.team`, on `.blocks`, and it would have happened again on `.practices`.
   The list itself needs nothing — it renders `dl.outcomes`, already styled. */
.limits h2,.method h2,.practices h2{margin:12px 0 22px;max-width:24ch}
.limits .lede,.method .lede,.practices .lede{margin-bottom:4px}

/* ── THE PRACTICE GROUPS — 0.4.78 ─────────────────────────────────────────────
   Angira's revised master list arrives in two named groups: the sessions she
   offers, and the one practice she offers as a TEACHER of it. `.tgroup` is the
   existing group wrapper, used by About's training register and by the FAQ.

   ⚠ ITS STYLING DOES NOT REACH THIS PAGE, AND THAT IS WHY THIS BLOCK EXISTS.
   `.tgroup` is declared in `about.css`, which `functions.php` loads for the
   `about` and `faq` templates only; an audience door loads `audience.css`. The
   class was reused for the markup, not inherited for the look — reusing the
   name without shipping the rules would have rendered two 16.5px paragraphs
   where two tracked sage headings belong.

   The h3 treatment is copied deliberately rather than invented: the same
   content — HER PRACTICES, in named groups — already renders this way on About,
   under ENERGY AND SUBTLE-BODY PRACTICE. Two pages, one voice.

   ⚠ `.outcomes` LOSES ONLY ITS TOP MARGIN, NOT ITS BOTTOM ONE. It ships
   `margin:34px 0 30px`; the 34px is what separated the list from the lede, and
   inside a group that job belongs to the h3 instead — leaving it would set the
   list 34px below its own heading. The 30px stays.

   ⚠ THE 24px IS RESTORED BECAUSE THE WRAPPER BREAKS THE SELECTOR.
   `.outcomes + .person-note` at line 240 is an ADJACENT-SIBLING rule, so a
   `.tgroup` between the list and the note stops it matching and the note
   silently loses its space. `svaflo_section_audience_practices()` carries the
   same warning: the single-untitled-group case emits NO wrapper at all and
   keeps the 0.4.77 markup byte for byte, so only the grouped case needs this.

   ⚠ AND THE RESULTING GAP IS 30px, NOT 54px — THIS COMMENT SAID `30+24` UNTIL
   IT WAS MEASURED ON THE LIVE PAGE. The two margins are ADJACENT SIBLINGS and
   collapse to max(30,24). `.tgroup` has no padding or border, so the list's
   30px collapses straight through it. **The rhythm is therefore identical to
   0.4.77, which is the right outcome — but it was right for a reason the
   comment had wrong**, and at these values the rule below changes nothing it
   is not protecting against: it only starts to matter if the note's margin
   ever goes above 30. Measured 30px at 1710 and at 375. */
.practices .tgroup{margin-top:34px}
.practices .tgroup + .tgroup{margin-top:clamp(38px,4.5vw,64px)}
.practices .tgroup h3{font-size:13px;letter-spacing:.16em;text-transform:uppercase;
  font-family:Mulish,sans-serif;font-weight:400;color:var(--sage);margin-bottom:14px}
.practices .tgroup .outcomes{margin-top:0}
.practices .tgroup + .person-note{margin-top:24px}

/* ── HAVE YOU NOTICED?, RELAID 0.4.19 ─────────────────────────────────────────
   RJ: *"Have you noticed? section looks sparse and bad."* It was. A three-word
   heading and four questions in a 46ch column, left-aligned in an 1180px band —
   **about 40% of the width carrying content and the rest empty**, between two
   full-width sections. Nothing was wrong with it in isolation; it was wrong
   beside its neighbours.

   Two columns fixes it without adding anything: the question goes left, the four
   answers-to-oneself go right, and the band is used. It is the same 5fr/7fr
   relationship as the hero, which is where a reader has just come from.

   ⚠ `.wrap` IS SHARED AND CARRIES THE PAGE GUTTERS. Overriding `display` on it
   is safe — `.hero .wrap` already does exactly this — but the columns must
   collapse in the phone block at the foot of this file, or the questions get a
   170px column and set one word a line. */
.noticed .wrap{display:grid;grid-template-columns:4fr 7fr;
  gap:clamp(28px,4.5vw,64px);align-items:start}
/* ⚠ NO `max-width` HERE, AND THE FIRST VERSION HAD 11ch. The column is already
   the constraint; a ch-cap on top of it broke "Have you noticed?" onto two
   ragged lines inside a column wide enough for one, and put the emptiness the
   two-column layout was meant to remove straight back — this time inside the
   heading's own cell. Let the grid do the measuring. */
.noticed h2{margin:0;max-width:none;text-wrap:balance}
.noticed .eyebrow{grid-column:1/-1;margin-bottom:0}

/* THE QUESTIONS. A run of questions the reader answers to themselves, so they
   are set as statements of their own rather than as a bulleted list: a bullet
   makes four questions look like four items on an inventory, and the section
   works by sounding like someone asking.

   ⚠ NO `list-style`, BUT STILL A `<ul>`. The markup is a list because it is one
   — four sibling items in no particular order — and a screen reader announcing
   "list, four items" is accurate and useful. Only the marker is dropped. Setting
   them as four `<p>`s instead would have read identically on the page and told
   an assistive reader nothing.

   ⚠ AND NO HAIRLINES, WHICH THE FIRST VERSION HAD. Rendered at 1440 it read as
   a stub of a data table — four bordered rows 476px wide, floating in an 1180px
   band next to two full-width lists. Hairlines say "these are records". Space
   says "these are questions". The checks passed on that version; only the
   screenshot showed it.

   The margin-top is gone with the two-column layout of 0.4.19: the questions no
   longer sit under the heading, they sit beside it, and they start on the same
   line. */
.questions{list-style:none;padding:0;margin:0;
  max-width:none;display:grid;gap:clamp(18px,2vw,26px)}
.questions li{font-family:'Cormorant Garamond',serif;font-size:clamp(23px,2vw,25px);
  line-height:1.4;color:var(--ink);text-wrap:balance}

/* The pair's closing notes carry the argument, so they are not set as the small
   grey asides `p.person-note` gives everywhere else on these pages. Same class,
   because the renderer uses `svaflo_note()`; different treatment, because on
   `method` this sentence is where the three limitations above are answered. */
.limits .person-note,.method .person-note{border-top:0;padding-top:0;
  max-width:60ch;margin-top:26px;font-size:var(--t-detail);line-height:1.75;color:var(--ink)}

.arg-head{margin-bottom:clamp(30px,4vw,52px)}
.argument .arg-body{max-width:780px}

/* ── THE ARGUMENT BODY, 0.4.19 ────────────────────────────────────────────────
   RJ: *"body text is suddenly too big."*

   `p.person-lead` is 22px, set in main.css for the HOME page's person section —
   three short paragraphs beside a photograph, where 22px is a lead-in. The
   argument section borrowed the class and inherited the size, and on this page
   it carries **four paragraphs, two of them long**. At 22px that is the largest
   body text on the site set over the longest passage on it, three pixels under
   the sub-heads that are supposed to sit above it.

   ⚠ SCOPED TO `.arg-body`, NOT CHANGED ON `p.person-lead`. The home page's use
   is the one the 22px was measured for — that block is sized so it ends level
   with the bottom of the photograph beside it, and the note in main.css says in
   terms to re-measure rather than nudge. Changing the shared class to fix this
   page would have moved a rule that was arrived at by measuring a box tree.

   Leading opens as the size comes down: a long passage at a tighter measure
   needs more line spacing, not less. */
.arg-body .person-lead{font-size:var(--t-detail-c);line-height:1.72;max-width:60ch}

/* ── THE SESSION BODY, 0.4.83 ─────────────────────────────────────────────────
   ⚠ SHIPPED IN 0.4.82 WITH NO CLASS AND NO SPACING, AND IT LOOKED FINE IN THE
   DOM. `svaflo_paras( …, 'session', 'body' )` emitted bare `<p>`, which inside
   `.session .wrap` inherits `margin:0` — so Individuals' three paragraphs
   rendered as ONE SOLID BLOCK of 17px text. The DOM check said "3 paragraphs"
   and was right; only the screenshot showed the problem.

   This is the Journal bug again, recorded in CLAUDE.md: *16 of 17 articles had
   body text in `.prose` as bare text nodes, so `.prose > * + *` could not space
   them.* Markup present, spacing rule out of reach. **The class is not
   decoration — it is what carries the margin.**

   `person-lead` brings `margin-bottom:30px` from main.css, and the size is
   scoped here exactly as `.arg-body` scopes it, for the same reason: the
   unscoped 22px was measured for the HOME page's person block and must not be
   touched. 62ch matches the body measure used by `.session .person-note`. */
.session .person-lead{font-size:var(--t-detail-c);line-height:1.72;max-width:62ch}

/* ── A SUB-HEAD INSIDE THE ARGUMENT, 0.4.18 ───────────────────────────────────
   RJ: *"These two are not running text: they are section starters."* He was
   right, and the reason is worth writing down because it is invisible in the
   markup.

   ⚠ THE `<strong>` WAS THERE ALL ALONG AND DID NOTHING. Measured live:
   `<strong>` inside `.arg-body` rendered at **font-weight 400 against a body of
   300** — one step, in Cormorant Garamond, at 22px. Technically bold, visually
   nothing. **Every other place on the site that uses `<strong>` sets it
   explicitly** — `.prose strong`, `.by strong`, `.person strong`,
   `.name-copy strong` are all `600` and `var(--ink)`. This section had no rule
   at all, so it inherited and disappeared. A missing rule, not a design.

   Two rules, because the two cases are different:

     · **anywhere in the body** — 600 and ink, matching the rest of the site
     · **first thing in a paragraph** — a section starter, so it takes its own
       line at the display size below the h2

   ⚠ AND THE SECOND RULE IS A CONVENTION, WHICH MAKES IT A TRAP. A paragraph
   that merely OPENS with a bolded phrase for emphasis will be promoted to a
   sub-head. That is the price of driving it from the copy rather than adding a
   field: an editor writes `<strong>Label.</strong> Body…` and gets a sub-head,
   with nothing in the form to tell them so. Documented in the field help.

   Cormorant Garamond 500 is a real cut — `fonts/cormorant-garamond-500-normal-*`
   — so this is not synthesised. Checked before choosing the weight; 600 would
   have been faux-bolded, which in a serif at this size looks like a mistake. */
.arg-body strong{font-weight:600;color:var(--ink)}
.arg-body p > strong:first-child{
  display:block;font-weight:500;color:var(--ink);
  font-size:clamp(19px,1.95vw,25px);line-height:1.3;
  margin:0 0 9px;letter-spacing:.005em}
.outcomes{margin:34px 0 30px;border-top:1px solid var(--line)}
.outcomes > div{display:grid;grid-template-columns:minmax(140px,1fr) 2fr;gap:clamp(16px,2.5vw,40px);
  padding:17px 0;border-bottom:1px solid var(--line)}
.outcomes dt{font-family:'Cormorant Garamond',serif;font-size:21px;color:var(--ink)}
.outcomes dd{margin:0;font-size:var(--t-detail);line-height:1.65;color:var(--soft);
  max-width:56ch}

.session h2{margin:12px 0 22px;max-width:24ch}

/* ⚠ A NEW SECTION WITH A LEDE UNDER ITS HEADING NEEDS BOTH OF THESE, and this
   is the second time that has been learnt the hard way. `.team` on About hit it
   first; `.blocks` hit it again the same evening, in exactly the same shape:

     · main.css resets `h1,h2,h3,p,ul,figure,blockquote{margin:0}`, so a new
       section's h2 sits flush against whatever follows it. Measured here at
       **0px**, against 22px on `.session` directly above.
     · `p.lede`'s default measure is tuned for the HOME hero, which sits in a
       narrow column under a two-word headline. Measured here at **252px** —
       six words a line — against 356px on `.session`.

   Neither rule is wrong. The combination simply does not exist until somebody
   adds a section, and nothing errors when it is missed: the page renders, it
   just reads as though the heading and the sentence are one paragraph.

   The price is the one thing §06 of *The Audiences* says has to be above the
   fold, so it is the worst section on the site to have crushed. */
.blocks h2{margin:12px 0 22px;max-width:26ch}
/* A sequence is the point here, so it is numbered — the only numbered list on
   the site. The numeral is set in the accent, small, as a marker rather than
   as an ornament. */
/* Five across, so the arc has the shape of an arc. `auto-fit` with a 210px
   minimum gave four columns and left the fifth movement orphaned on a second
   row, which reads as four steps and an afterthought. Five explicit columns,
   collapsing to a stack below the breakpoint. */
.movements{counter-reset:mv;display:grid;grid-template-columns:repeat(5,1fr);
  gap:clamp(24px,3vw,44px);margin-top:clamp(34px,4.5vw,60px);list-style:none;padding:0}
@media (max-width:900px){.movements{grid-template-columns:1fr 1fr}}
.movements li{counter-increment:mv;border-top:1px solid var(--line);padding-top:16px}
.movements li::before{content:counter(mv,decimal-leading-zero);display:block;
  font:400 11px/1 Mulish,sans-serif;letter-spacing:.2em;color:var(--sage);margin-bottom:12px}
.movements h3{margin-bottom:7px}
.movements p{font-size:var(--t-detail);line-height:1.7;color:var(--soft)}

.facts{margin:clamp(30px,4vw,52px) 0 0;border-top:1px solid var(--line)}
.facts > div{display:grid;grid-template-columns:minmax(190px,1fr) 2fr;gap:clamp(16px,2.5vw,44px);
  padding:24px 0;border-bottom:1px solid var(--line)}
.facts dt{font-family:'Cormorant Garamond',serif;font-size:clamp(21px,2.2vw,27px);
  line-height:1.25;color:var(--ink)}
.facts dd{margin:0;font-size:var(--t-detail);line-height:1.7;color:var(--soft);max-width:56ch}


/* Two notes and a link stack under the movements now that the formats
   section is gone and the group-size line moved here. */
.session .person-note + .person-note{margin-top:14px}
.session .more{margin-top:30px}

/* ── THE VOICES LINK, 0.4.85 ─────────────────────────────────────────────────
   `p.more` carries no margin of its own, so `Read all reviews` shipped in
   0.4.84 sitting FLUSH against the quote grid — measured gap 0px — and read as
   part of the last quote's attribution rather than as a link out. RJ: *"Read
   all reviews is too close to the text above."*

   ⚠ 44px, NOT the 30px `.session .more` uses, and the difference is the thing
   above it. In `session` the link follows a paragraph; here it follows a
   two-column grid of quotes, each with a name and a context line under it. A
   grid needs more air beneath it than a paragraph does before a single line
   reads as separate. Both values were rendered and compared before choosing. */
.voices .more{margin-top:44px}

/* The Impact treatment, borrowed for the challenge statement. `.figure`
   itself is in the shared stylesheet; only the measure changes here,
   because this sentence is longer than the 10,000 one. */
/* ── 30ch → 38ch, 0.4.89, AND THE BALANCER IS WHY IT IS SAFE ────────────────
   RJ reported bad breaks on Corporates, Institutions and Circles. Measured at
   1440px, counting line ends on function words ("hangs") and the pixel spread
   between shortest and longest line ("rag"):

                  chars   TODAY 30ch          38ch + balance
     Corporates    231    7 lines · 4 hangs   5 lines · 0 hangs · rag  48px
                          rag 287px
     Institutions  105    4 lines · 3 hangs   4 lines · 2 hangs · rag  26px
                          ONE-WORD LAST LINE
     Circles       167    5 lines · 0 hangs   4 lines · 0 hangs · rag  80px
     Individuals   126    4 lines · 1 hang    3 lines · 1 hang  · rag 108px

   ⚠⚠ THE TWO CHANGES ARE A PAIR AND SHIPPING EITHER ALONE MAKES A PAGE WORSE.
   `balance` alone cannot touch Corporates — seven lines is past Chromium's
   limit. And 38ch ALONE BREAKS CIRCLES: it goes from 0 hangs and a 126px rag to
   TWO hangs and 242px, because a wider measure gives the greedy breaker new
   ways to end a line badly. With the balancer on, the same width gives 0 hangs
   and 80px. **Widening a measure without a balancer is a coin toss.**

   ⚠ ON A PHONE NOTHING MOVES. At 375px the measure is viewport-bound long
   before 38ch, so this rule does not apply; Institutions still improves there,
   from the balancer alone (rag 223 → 26).

   🔴 AND THE COPY QUESTION IS NOT CLOSED BY THIS. The note below records the
   device as sized for a short statement — Home 106 characters, Corporates 125 —
   and Institutions at 190 was judged to have outgrown it. **Corporates is now
   231.** The CSS makes it break cleanly at five lines instead of seven; it does
   not make it short. The rule that note leaves behind still stands: when a
   device stops working, check whether the content has outgrown it. **Flagged to
   RJ on 4 September as a copy decision, not fixed here.** */
.challenge .figure{max-width:38ch}

/* ── 0.4.22 PUT THE CLAIM ON ITS OWN LINE. 0.4.23 TOOK IT BACK OFF. ───────────
   RJ: *"Are The Claim and The Qualification supposed to read as one para or 2
   with different sizes?"*

   **One.** And it is written down in two places, neither of which I read before
   changing it:

     · the field help — *"Set in sage. The qualification after it is set in ink,
       and the two are one sentence."*
     · the note above `.figure` in main.css — *"One sentence, set as a statement.
       The number inside it takes the sage; the rest stays in ink, so the figure
       carries without being a separate object."*

   **`display:block` made it a separate object**, which is the one thing that
   note exists to prevent. It shipped in 0.4.22 and is removed here.

   ⚠ THE REPORT WAS ACCURATE AND MY DIAGNOSIS WAS NOT. *"Displaying run on"* was
   real — but the cause was length, not layout. The treatment is sized for a
   short statement: the home page's figure is **106 characters**, Corporates
   **125**. Institutions had reached **190**, six lines at 42px, and a six-line
   two-tone statement stops reading as a statement and becomes a paragraph that
   happens to start in green. `.figure`'s measure had already been widened from
   24ch to 30ch for this page, which was the first sign the copy was outgrowing
   the device and was read as a licence rather than a warning.

   **RJ fixed it in the copy** — down to 104 characters, back in range with the
   other two — and the treatment works as designed again with no CSS at all.

   **The rule this leaves behind: when a device stops working, check whether the
   content has outgrown it before changing the device.** */

/* ── THE SECTIONS ADDED FOR CORPORATES ─────────────────────────────────── */
.outcomes-section h2,.voices h2,.clients h2{
  margin:12px 0 clamp(28px,3.4vw,44px);max-width:22ch}
.voices .lede{max-width:48ch;margin-bottom:clamp(30px,3.6vw,48px)}

/* THE VOICES. Four quotes in a grid rather than a scroller — a scroller hides
   three of them, and on the page where proof is scarcest nothing should be
   behind a swipe. */
/* Two explicit columns, not auto-fit. `repeat(auto-fit,minmax())` is not
   implemented by the engine these pages are checked in, so all four quotes
   stacked into one column and the render showed a page nobody would build.
   Two is also the right number: a quote needs a measure, and four across gives
   it twenty-two characters a line. */
.vgrid{display:grid;grid-template-columns:1fr 1fr;gap:clamp(22px,3vw,46px)}
.vquote{margin:0;border-top:1px solid var(--line);padding-top:20px}
.vquote blockquote p{font-family:'Cormorant Garamond',serif;font-style:italic;
  font-weight:300;font-size:var(--t-body-c);line-height:1.5;color:var(--ink)}
.vquote figcaption{margin-top:16px;font-size:12px;letter-spacing:.11em;
  text-transform:uppercase;color:var(--soft)}
.vquote figcaption span{display:block;letter-spacing:.02em;text-transform:none;
  font-size:12.5px;margin-top:5px}

/* The rooms those words were said about. */
.egrid{display:grid;grid-template-columns:repeat(4,1fr);gap:clamp(14px,1.8vw,26px);
  margin-top:clamp(40px,4.6vw,68px)}
.egrid figure{margin:0}
.egrid figcaption{border-top:1px solid var(--line);margin-top:12px;padding-top:10px;
  font-size:13px;line-height:1.55;color:var(--soft)}

.roster{margin:0 0 clamp(34px,4vw,56px);border-top:1px solid var(--line)}
.roster > div{display:grid;grid-template-columns:minmax(160px,1fr) 3fr;
  gap:clamp(16px,2.6vw,44px);padding:20px 0;border-bottom:1px solid var(--line);
  align-items:baseline}
.roster dt{font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--sage);line-height:1.6}
.roster dd{margin:0;font-family:'Cormorant Garamond',serif;
  font-size:var(--t-body-c);line-height:1.5;color:var(--ink);max-width:60ch}
.clients .person-note{margin-top:28px;max-width:56ch}
.clients .facts{margin-top:0}
/* ⚠ TWO HAIRLINES WITH NOTHING BETWEEN THEM. `.roster` closes on a row with a
   bottom border, then clears 34–56px, then `.facts` opens with a top border —
   so the join rendered as an empty table row. Only visible once the page was
   put in a browser. The gap between the two lists is meaningful and stays;
   the duplicate rule at the join goes. */
.clients .roster > div:last-child{border-bottom:0}


@media (max-width:900px){
  .egrid{grid-template-columns:1fr 1fr}
  .vgrid,.roster > div{grid-template-columns:1fr}
}

/* A sentence and a link. Architecture §3.1 is explicit that pro bono must not
   be a section on this page — "a section starts to look like it is being
   traded." */
p.probono{margin-top:clamp(48px,6vw,80px);padding-top:26px;border-top:1px solid var(--line);
  max-width:56ch;font-size:var(--t-detail);line-height:1.75;color:var(--soft)}
/* ── `p.person-note` LINKS, 0.4.84 ───────────────────────────────────────────
   ⚠ QUEUED SINCE 2 SEPTEMBER AND SLIPPED TWO RELEASES. The cross-links added to
   Groups & Circles sit inside `p.person-note`, which had no link rule at all —
   making them **the only links on the site that do not look like the site's
   links**. The idiom already existed twice, on `.more a` and `p.probono a`;
   this is the same declaration, not a new one. Riding with 0.4.84 because RJ
   said to ride it with the next zip and the next zip kept being about
   something else. */
.person-note a{color:var(--sage);border-bottom:1px solid var(--line);text-decoration:none;
  padding-bottom:2px}

p.probono a{color:var(--sage);border-bottom:1px solid var(--line);text-decoration:none;
  padding-bottom:2px;margin-left:6px}


/* ════ THE PHONE ═══════════════════════════════════════════════════════════
   The shared block in `build.py` stacks `.hero .wrap` for every page — and it
   did not work here, because line 217 of THIS stylesheet sets
   `.hero .wrap{grid-template-columns:7fr 5fr}` at the same specificity and
   this file is appended after the shared one. The Corporates headline
   therefore came out at 390px in a 170px column: "SVã / flo / begins / where /
   office pep / talks…", six lines of two words.

   Which is the same cascade trap this project has hit four times before, in a
   new place: **the shared phone rules cannot reach a page that redefines the
   same selector later.** Every page stylesheet that overrides a shared grid
   needs its own phone block, and this is Corporates'. */
/* ⚠ `.pullquote` MOVED TO main.css IN 0.4.102. It is used by the five
   audience pages, by About's `voice` section and by Home's, and Home loads
   main.css alone. The 760px override moved with it. Do not re-add it here.
   ⚠ The measure is still governed by main.css `p{max-width:34rem}`, not by
   the component — see the note there. */

/* ═══ ELSEWHERE — the social accounts, 0.4.8 ═════════════════════════════════
   Absent entirely until an account has an address; see svaflo_socials().

   ⚠ WORDS, NOT ICONS, AND THAT IS NOT A SHORTCUT. An icon set means either a
   webfont or nine more files in assets/img, and every glyph then needs a label
   underneath for anyone who does not recognise it — at which point the label is
   doing the work and the icon is decoration. The site sets its links as text
   everywhere else; four platform names in the same treatment as every other
   link is consistent, weighs nothing, and reads identically to a screen reader
   and to a person. */
.follow h2{margin-bottom:26px}
.social{display:flex;flex-wrap:wrap;gap:14px 34px;margin:0;padding:0;list-style:none}
.social a{color:var(--sage);text-decoration:none;border-bottom:1px solid var(--line);
  padding-bottom:3px;font-size:15px;transition:border-color .18s}
.social a:hover,.social a:focus-visible{border-bottom-color:var(--sage)}
.follow .person-note{margin-top:28px;border-top:0;padding-top:0;max-width:56ch}

@media (max-width:760px){
  /* ── STACK THE TERM ABOVE ITS DESCRIPTION - 0.4.70 ──────────────────────────
     Measured at 360x800 on the live site: `minmax(140px,1fr) 2fr` cannot hold
     two columns in a 308px wrap, so the floor wins and the columns resolve to
     140px / 152px. The description then sets at TWENTY CHARACTERS PER LINE at
     15px, and the first `practices` entry runs to fifteen lines in the sliver.
     SEVEN lists did this across Individuals, Corporates and Institutions -
     about 9.3 screens of the site's central argument. Stacked, the description
     takes the full 312px and 41 characters.

     ⚠⚠ THIS RULE SHIPPED DEAD IN 0.4.69 AND THAT IS THE POINT OF THIS COMMENT.
     It was written as its own `@media (max-width:760px)` block placed FIVE LINES
     ABOVE `.outcomes > div` - the rule it exists to override. Identical
     specificity, and A MEDIA QUERY ADDS NONE, so the later rule won and nothing
     changed on any page. check.php passed, the zip verified, the archive
     contained the rule, and the site was untouched. **It was caught only by
     re-measuring the live pages after install**, which found all seven lists
     still at 20 characters.

     ⚠ AN OVERRIDE PLACED BEFORE THE RULE IT OVERRIDES IS NOT A WEAK OVERRIDE,
     IT IS NO OVERRIDE. And it fails silently in both directions: the DOM-injected
     test that proved the rule worked appended a <style> to the end of head,
     which is exactly the position the shipped rule did not have.

     ⚠ AND IT BELONGS IN THIS BLOCK, NOT IN A SECOND ONE. main.css already
     records that two `@media` blocks in one stylesheet contradict each other
     silently; 0.4.69 created precisely that. One block per breakpoint per file.

     ⚠ LEGIBILITY, NOT SCROLL. Measured: Individuals -0.6 screens, Institutions
     -0.1, and CORPORATES +0.1 - slightly LONGER. Do not expect it to shorten a
     page. `.blocks` already stacked and sets at 39 characters on the same page,
     which is what showed the pattern was right. */
  .outcomes > div{grid-template-columns:1fr;gap:4px}

  /* ── THE LEAD PARAGRAPHS WERE SMALLER TO READ THAN THE SMALL PRINT — 0.4.90 ─
     RJ, 4 September: *"On a phone the ledes are smaller to read than the small
     print — address this."*

     🔴 MEASURED IN X-HEIGHT, WHICH IS THE ONLY UNIT THAT SHOWS IT. On a phone
     these clamps bottom out and Cormorant's very small x-height does the rest:

         p.person-lead   15.5px Cormorant   x-height 5.98px
         p.lede          17px   Cormorant   x-height 6.56px
         p.person-note   13.5px Mulish      x-height 6.78px   ← THE CAVEAT

     So the sentence introducing a section put LESS on the glass than the note
     qualifying it. Forty-four blocks across the site, including the hero lede
     on all thirteen pages. **Nothing in the stylesheet shows this** — 17 is a
     bigger number than 13.5 and every rule looks reasonable alone.

     ⚠ AND THIS SITE HAS ALREADY FOUND AND FIXED THIS EXACT FAULT ONCE. main.css
     records it for Home's person section — caption 15px Mulish against copy
     16px Cormorant, *"a point SMALLER and reads 22% LARGER"* — and raised the
     phone size to 20px. **20 is therefore not a new number; it is the answer
     this site already reached**, and using it keeps the two sections matching
     instead of adding a second value half a pixel away.

     ⚠⚠ AND THE ANSWER IS A TOKEN THAT ALREADY EXISTS, NOT A NEW NUMBER. The
     first draft of this fix used 20px, borrowed from that Home repair. Then the
     token block at the top of main.css turned out to define the whole scale in
     x-height, with `--t-lead` at **21px on a phone — x-height 8.11** — and
     About already points at it and has never had this problem. **These rules
     carry their own clamps and simply never used the scale.** Pointing them at
     `var(--t-lead)` fixes the inversion, deletes two hand-written clamps rather
     than adding a third number, and keeps working if the typeface is replaced.

     `.person-copy p.person-lead` on Home is moved onto the same token in
     main.css, so the 20px from that earlier repair goes too — one value where
     there were three.

     Measured cost, at 375px: Institutions +0.38 screens, Individuals +0.34,
     Circles +0.26, Corporates +0.16, everything else at or under 0.07.

     ⚠ THE QUOTES WERE THE THIRD OFFENDER AND ONLY THE RE-MEASUREMENT FOUND
     THEM. With the ledes fixed, the smallest Cormorant on three door pages was
     still `.vquote blockquote p` at 17px — the same 6.56 x-height, the same
     clamp shape. **Fixing the two things RJ named would have left the reviews
     under the caveat text.** What remains smallest after this is 18px
     (x 6.95) on `clients`, `ways` and the reviews wall — above the 6.78 line,
     but only just, and worth watching.

     ⚠ `p.lede` IS IN main.css, NOT HERE, because the lede is on all thirteen
     pages and only five of them load this stylesheet. This block carries the
     `person-lead` half, which exists only on the doors.

     ⚠⚠ `p.person-lead`, NOT `.person-lead`, AND THE EXTRA ELEMENT IS LOAD-BEARING.
     `.svaflo-page-institutions .arg-body .person-lead` is a base rule 150 lines
     BELOW this block, at 0,3,0. A rule written here as `.arg-body .person-lead`
     is 0,2,0 and loses; written as `.svaflo-page-institutions .arg-body
     .person-lead` it TIES at 0,3,0 and still loses, because that rule comes
     later in the file. Adding the element name takes both selectors to 0,2,1
     and 0,3,1, which wins on specificity regardless of order — the alternative
     being a second `@media (max-width:760px)` block placed lower, which is the
     fault this file documents at 0.4.69 and must not be repeated. */
  .arg-body p.person-lead,.session p.person-lead,
  .svaflo-page-institutions .arg-body p.person-lead{font-size:var(--t-body-c);line-height:1.5}
  /* Declared above this block, so source order is enough here — no element
     name needed, unlike the person-lead selectors. */
  .vquote blockquote p{font-size:var(--t-body-c)}

  /* ── THE TWO TAP TARGETS main.css CANNOT REACH ──────────────────────────────
     Added 0.4.37, and they were missed twice before that. 0.4.35 raised
     `.more a`, `.flink` and `.legal a`; 0.4.36 added `.brand` and the footer
     contact block. Measured after each release, six of eight pages came back
     clean and the same two did not — because these two components are neither
     of those things and live on this stylesheet, not on main.css:

       .book a   Signature Sessions   14px  ← the booking link, three of them
       .ways a   Contact              22px  ← the email and both numbers

     ⚠ THE TWO SHORTEST TARGETS ON THE SITE WERE THE TWO MOST IMPORTANT LINKS
     ON THEIR PAGES. "Call +91 90515 22166 to book" is the entire conversion
     path of Signature Sessions and it was fourteen pixels tall. That is worth
     saying plainly rather than filing as a third round of tidying.

     ⚠ AND THEY GO IN *THIS* STYLESHEET. Both pages load main.css then
     audience.css, so a rule here beats an equal-specificity rule there — which
     is also why putting them in main.css's phone block would have been a
     seventh instance of the ordering trap rather than a fix for it.

     The overlay again, not padding: `.book` is uppercase 11px with letter-
     spacing and `.ways dd` sits in a definition list where padding would move
     the term away from its value. Clearance was measured before choosing it —
     nearest link centre-to-centre is 335px on Signature Sessions and 101px on
     Contact, against the 44px an overlay needs. Nothing can collide. */
  /* ⚠ MOVED OUT OF THIS BLOCK IN 0.4.41 — see the 1023px block below. Same
     reason as the overlays in main.css: 761–1023px shows the phone menu and
     was still getting desktop-sized targets. */

  .hero .wrap{grid-template-columns:1fr}
  .hero-figure{max-width:none;margin-left:0}
  /* The two-column "Have you noticed?" collapses here for the same reason the
     hero does — 5fr of 342px is 140px, and a question set in that is one word a
     line. The heading gets its space back above the list. */
  .noticed .wrap{grid-template-columns:1fr}
  .noticed h2{max-width:none;margin-bottom:clamp(20px,4vw,28px)}
  /* One thought a row. At 390px `minmax(190px,1fr) 2fr` leaves the second
     column about 150px, which is three words a line. */
  .facts > div,.movements{grid-template-columns:1fr}
  .facts > div{gap:6px}
  /* The event photographs stay two across — they are 3:2 and read fine at
     165px, and four stacked frames is a long scroll for a supporting grid. */
  .egrid{grid-template-columns:1fr 1fr;gap:14px}
}


/* ═══ THE SCHOOLS & INSTITUTIONS TYPE SCALE — 0.4.20 ══════════════════════════

   RJ: *"the upper half of the page is a little off on text sizing"*, and asked
   for a rationalisation on this page only.

   ⚠ HE WAS RIGHT AND THE FAULT HAS A NAME — IT IS THE ONE THIS STYLESHEET
   OPENS BY DESCRIBING. Measured on the live page before touching anything, the
   top half ran:

     pull-quote 38  ·  "Ask yourself this." 38  ·  the challenge 42  ·
     "What most schools overlook." 38

   **Four large items inside a four-pixel band.** The note at the head of this
   file records exactly this shape — *"seven display sizes inside a six-pixel
   band… that is why it read as flat"* — and it was fixed for the section
   headings in 0.4.18. It reappeared because `pullquote` and `challenge .figure`
   were never part of that scale: one is a quotation, the other a statement, and
   neither is an h2, so neither was ever assigned a step.

   Two specific inversions inside that band:

     · **the challenge statement outsized every heading on the page** — 42
       against 38. A paragraph larger than the headings above and below it.
     · **the pull-quote was exactly heading-sized**, so Angira's voice carried
       the weight of a section label rather than of a person speaking.

   ⚠ SCOPED TO ONE PAGE ON RJ'S INSTRUCTION, AND THAT IS A REAL COST, RECORDED
   RATHER THAN GLOSSED. `pullquote` and `challenge` also render on Individuals
   and Corporates, which keep the old sizes — so **the three doors no longer
   share one scale.** The gain is that nothing untested moved on two approved
   pages. The loss is a per-page exception, which is the kind of thing found
   later and puzzled over. This block is the explanation for whoever finds it.

   The steps, and the job each one does:

     74  the page's claim            h1
     48  the one deliberate statement  the challenge
     38  section headings            every h2
     30  her voice                   the pull-quote
     27  the reader's own questions  "Ask yourself this."
     24  labels inside running copy  the argument sub-heads
     21  introductions               ledes, list terms
     19  running copy                the argument body
     15  supporting detail           list descriptions
     11  section labels              eyebrows

   Nine steps, none closer than three pixels, each assigned to a job rather than
   to a tag. */

/* ⚠ TWO OF THE FIVE RULES THAT WERE HERE ARE GONE — 0.4.21, RJ.

     · `.challenge .figure` was scoped to 48px. **Reverted to the shared 42px**,
       to match *"What's not working"* on Individuals.
     · `.pullquote blockquote p` was scoped to 30px. **Reverted to the shared
       38px**, to match the quote on Corporates.

   They were the two changes argued hardest for in 0.4.20 — that a quote at
   heading size reads as a label rather than as a person speaking, and that the
   challenge statement should be the second moment on the page. **RJ overruled
   both, and the result is more defensible than what it replaced:** Institutions
   now matches the other doors on its two largest non-heading elements, instead
   of carrying a per-page exception for them.

   **The upper half therefore returns to 38 · 38 · 42 · 38** — the four-item band
   that prompted the rationalisation in the first place. That is a known and
   accepted state, not an oversight: consistency between the doors was judged
   worth more than separation within one page. If the band is ever raised again,
   this is the trade to reopen, and the answer is not to re-scope these two.

   What survives of 0.4.20 is below — the three elements that exist only on this
   page or are read only here, plus the `svaflo-page-<slug>` class carrying them. */
.svaflo-page-institutions .questions li{font-size:clamp(23px,2.05vw,27px)}
.svaflo-page-institutions .arg-body p > strong:first-child{font-size:clamp(18px,1.85vw,24px)}
.svaflo-page-institutions .arg-body .person-lead{font-size:var(--t-detail-c)}

/* ── TAP TARGETS FOR THIS STYLESHEET'S TWO COMPONENTS ─────────────────────────
   Added 0.4.41, moved out of the 760px block above.

   `.book a` (Signature Sessions' booking line, 14px) and `.ways dd a` (the
   Contact page's email and numbers, 22px) were the last two targets under 44px
   when 0.4.37 swept the site — and they are the most important links on their
   pages. They were fixed at 760px, which was correct until 0.4.40 moved the
   menu breakpoint to 1023px and left tablets showing a phone menu with a
   mouse's hit areas.

   ⚠ THIS BLOCK MUST STAY AFTER THE 760px BLOCK ABOVE IT, not before. Equal
   specificity, later wins — the same trap that made 0.4.39 do nothing at all
   because a `@media` block sat above the base rule it meant to override.
   Nothing here overlaps with the 760px block, but the ordering is the habit.

   Clearance was measured before choosing an overlay: nearest link centre to
   centre is 335px on Signature Sessions and 101px on Contact, against the 44px
   an overlay needs. Nothing can collide. */
@media (max-width:1023px){
  .book a,.ways dd a{position:relative}
  .book a::after,.ways dd a::after{content:"";position:absolute;inset-inline:0;
    top:50%;transform:translateY(-50%);height:44px}
}

/* ── THE ENQUIRY FORM (contact page) ──────────────────────────────────────
   ⚠ WHY IT IS IN THIS FILE AND NOT A contact.css. The stylesheet map in
   functions.php sends the contact template here, to audience.css, by an
   explicit decision recorded there: Contact was built entirely from classes
   that already existed, and two more files were two more things to keep in
   step. The form is the first thing on Contact that is genuinely its own, and
   it would have justified a new sheet — but a new sheet also means editing
   that map, and the note in functions.php says plainly that nothing errors
   when that map is wrong: the page just renders unstyled. Adding the rules
   where the page already looks is the change with no silent failure mode.
   If Contact ever gets a sheet of its own, this block moves wholesale. */

.write .lede { max-width: 34em; }

.enq { max-width: 38em; margin: 28px 0 0; }

.enq .f { margin: 0 0 22px; }

.enq label {
  display: block;
  font-size: .92rem;
  font-weight: 600;
  letter-spacing: .01em;
  margin: 0 0 7px;
  color: var(--ink);
}

.enq .opt { font-weight: 400; color: var(--soft); }

.enq input,
.enq select,
.enq textarea {
  width: 100%;
  font: inherit;
  font-size: 1rem;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid rgba(44, 48, 44, .28);
  border-radius: 2px;
  padding: 11px 13px;
  /* ⚠ 16px MINIMUM ON THE PHONE, VIA font-size:1rem ABOVE. iOS Safari zooms
     the whole page when a focused input is under 16px, and the zoom does not
     come back when the field is blurred. A form is exactly where that is
     least forgivable. */
}

.enq textarea { resize: vertical; min-height: 9em; line-height: 1.55; }

.enq input:focus,
.enq select:focus,
.enq textarea:focus {
  outline: 2px solid var(--sage);
  outline-offset: 1px;
  border-color: var(--sage);
}

.enq .hint {
  display: block;
  font-size: .82rem;
  color: var(--soft);
  margin: 6px 0 0;
  line-height: 1.45;
}

/* ── the honeypot ───────────────────────────────────────────────────────
   ⚠ NOT display:none, AND NOT hidden. Some bots skip fields that are
   display:none precisely because it is the obvious tell, and some screen
   readers announce a hidden input's label anyway. Pushed out of the flow and
   out of the accessibility tree instead, with aria-hidden and tabindex="-1"
   on the markup side. */
.enq .hp {
  position: absolute !important;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ── errors ─────────────────────────────────────────────────────────────── */

.enq .ferr {
  display: block;
  font-size: .85rem;
  color: var(--terracotta);
  margin: 6px 0 0;
  font-weight: 600;
}

.enq [aria-invalid="true"] { border-color: var(--terracotta); }

.write .fbanner {
  background: var(--paper-2);
  border-left: 3px solid var(--terracotta);
  padding: 12px 16px;
  margin: 22px 0 0;
  max-width: 38em;
  font-size: .95rem;
}

/* ── consent line and button ────────────────────────────────────────────── */

.enq .consent {
  font-size: .85rem;
  color: var(--soft);
  line-height: 1.5;
  margin: 4px 0 20px;
  max-width: 34em;
}

.enq .send { margin: 0; }

.enq button {
  font: inherit;
  font-size: .95rem;
  font-weight: 600;
  letter-spacing: .02em;
  color: var(--paper);
  background: var(--sage);
  border: 1px solid var(--sage);
  border-radius: 2px;
  padding: 13px 26px;
  cursor: pointer;
  transition: background .18s ease, border-color .18s ease;
}

.enq button:hover { background: #33503f; border-color: #33503f; }
.enq button:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

.enq .cf-turnstile { margin: 0 0 18px; }

/* ── the conditional field ──────────────────────────────────────────────── */

/* ⚠ THE CLASS, NOT THE ATTRIBUTE. `hidden` alone loses to `display:block` from
   any later rule, which is a classic way for a "hidden" field to sit there in
   plain sight on one breakpoint only. */
.enq .f.hidden { display: none; }

/* ── after it sends ─────────────────────────────────────────────────────── */

.write .wrote {
  background: var(--paper-2);
  border-left: 3px solid var(--sage);
  padding: 22px 26px;
  max-width: 38em;
  margin: 26px 0 0;
}

.write .wrote p { margin: 0; font-size: 1.05rem; line-height: 1.6; }

@media (max-width: 640px) {
  .enq { max-width: none; }
  .enq .f { margin-bottom: 18px; }
  .enq button { width: 100%; }
}


/* ── THE FORM FOLDED INTO THE OPENING — 0.4.115, 21 September 2026 ───────────
   RJ: "Why dont we drop 'tell Angira...' as well. Just fold the form into the
   page HL block, Clean and simple?" The eyebrow and heading are cleared in the
   admin; `svaflo_section_contact_write()` adds `joined` whenever the heading is
   empty, and these four rules close the seam.

   ⚠ THE BAND IS NOT REMOVED BY `ground`. `svaflo_render_sections()` computes it
   from POSITION — `$i % 2` — and only `legal` declares `alternate => false`, so
   contact's declared `'ground' => 2` is dead code. Editing it reads as the fix
   in a diff and changes nothing on the page. The background is overridden here.

   ⚠⚠ THE INDENT IS `.hero-copy`'s, NOT THE WRAP'S, AND A FIRST VERSION GOT THIS
   WRONG. Hardcoding `padding-left:34px` aligned the form to the h1 at 1710px
   and pushed it 10px RIGHT of the h1 at 390px, where `.hero-copy{padding-left:0}`
   and `.hero .wrap{padding-inline:24px}` — which is what the base `.wrap`
   already gives the form. So below 760 they align with no help, and this
   override is desktop-only. Measured in a 390px same-origin iframe, because the
   window still will not resize below 1024.

   ⚠ `:has()` IS THE ONE MODERN SELECTOR HERE and its failure is graceful: the
   hero keeps its bottom padding, so the seam opens up rather than breaking. */
section.write.joined{padding-top:0;background:var(--paper)}
.hero:has(+ .write.joined){padding-bottom:0}
.hero:has(+ .write.joined) > .wrap{padding-bottom:56px}
@media (min-width:761px){
  section.write.joined > .wrap{padding-left:clamp(0px,2vw,40px)}
}
