/* =====================================================================
   UTILITIES PAGE — page-level only
   Everything reusable lives in css/components/. The accordion is in
   components/accordion.css; the quote block and join form are shared
   partials already used by the home page.

   THIS SHEET LOADS LAST (position 10 of 10) AND EVERY OVERRIDE BELOW
   STILL WINS ON SPECIFICITY, NOT ON LOAD ORDER. That is deliberate and
   is the homepage's own pattern (`#problem.band-plum` beats
   `.band-plum`). Re-ordering the <link> tags must not be able to undo a
   page treatment — a media query adds no specificity and neither does
   being further down the list.
   =====================================================================

   DEVIATION LOG — utilities page

   IN-TREE AND PAGE-LOCAL, ON PURPOSE. why-longitude.css and
   privacy-policy.css each carry their own register in their own header, and
   that is the pattern that works: the log ships with the file it describes,
   so a reader who opens the sheet finds it without knowing it exists.

   THE PREFIX IS "UTIL-", NOT "D". The bare D prefix is EXHAUSTED as an
   unqualified identifier on this engagement — D7 alone means three different
   things (the copy document's unknown CTA destinations, privacy-policy's
   mid-word underline, and a deploy unit), and D3 means two. Any D-number
   written here without a qualifier would be ambiguous the day it was
   written. References to the copy document's series are spelled "copyflow
   Dn" throughout utilities.html for the same reason.

   UTIL-1 · THE FX CHIP'S TEXT NODE WAS SPLIT INTO TWO LINKS. Unit 9ai,
   2026-08-13. STRUCTURAL CHANGE TO CLIENT-SUPPLIED COPY.

     WHAT CHANGED: the FX "Led by" chip arrived as ONE undifferentiated text
     node carrying two people either side of a U+00B7 — "Jim Lester, CEO ·
     Colin Drylie, COO." Each name is now wrapped in its own anchor into
     our-team.html's Leadership rows. The separator sits outside both links.

     WHY: the chip is the only route from the utilities page to those two
     people. A single chip-level link would have resolved to ONE of them and
     made the other silently unreachable — it would work, and be wrong, with
     nothing on screen to indicate which of the two you were about to reach.
     Measured before the edit: one text node, zero child elements.

     ZERO CHARACTERS OF CLIENT COPY CHANGED. Roles, commas, the terminal
     period and the separator are all as authored; every chip's textContent
     is byte-identical before and after, verified by comparison rather than
     asserted. What changed is the markup shape, which is why this is logged
     as a deviation rather than treated as a copy edit.

     NOT TO BE "SIMPLIFIED" BACK to one link. The two-anchor shape is the
     whole point of the entry.
   UTIL-2 · THE DOMAINS BAND IS DELETED. CLIENT-REQUESTED,
   DIRECTOR-APPROVED (R7, 2026-08-14). `section.u-domains`, the dark band
   between the hero and the accordions, removed in full. THE ACCORDIONS ARE
   UNTOUCHED — roster order Rx · FX · CTS · CGT · MD stands and is verified
   by element on the built page.

   COPY VERBATIM, because this register is now the only place it exists in
   the tree outside _archive-checkpoint-9am-2026-08-13/:

     heading   "Built for distinct challenges. " + a <span class="u-gold">
               reading "Designed to work together."
     para 1    "Each utility is a standalone operating company — member-owned,
               built for a specific operational challenge, and designed to
               deliver durable value at the network level. Together, they
               carry out Longitude Health's broader strategy to build an
               ecosystem of interconnected utilities spanning specialty
               pharmacy and therapeutics, enterprise shared services,
               specialty-as-a-service, and payor-provider solutions. Build
               once, use many times."
     para 2    "Each utility creates value twice: measurable member value
               today, and platform depth that enables the next layer."
     the four, each a <span class="u-domain"> label plus a trailing line:
       "Pharmacy & Therapeutics"      + " is focused on revenue growth"
       "Enterprise Shared Services"   + " on cost reduction and productivity"
       "Specialty-as-a-Service"       + " on patient access and asset-light growth"
       "Payor-Provider Solutions"     + " on industry transformation and connected care."

   CHARACTER-LEVEL: two U+2014 em dashes, one in each body paragraph, none
   in the labels. The ampersand is the &amp; ENTITY, not a literal. Every
   hyphen in Specialty-as-a-Service (x3) and Payor-Provider (x1) is U+002D.
   "Health's" is U+0027. No other non-ASCII in the band.

   THE LABELS ARE AUTHORED IN TITLE CASE. The capitals are
   `text-transform:uppercase` on .u-domain. Anyone retyping from the screen
   would bake them in. The labels are --accent, NOT gold; what is gold is
   the timeline — the 28px dots and 3px connectors — and the heading span.

   IT WAS A DIFFERENT ROSTER FROM THE ACCORDION, not a subset and not an
   index into it: four DOMAINS against five UTILITIES, with no link, anchor,
   id, aria or script connecting them. The band carried no id at all, so
   nothing in the tree could target it — confirmed by a DOM sweep of all 18
   pages and a second sweep of src/js/ and every data- attribute.

   MEASURED CONSEQUENCE, LOGGED NOT RESTYLED: the band sat between two
   PAPER grounds, so removing it puts paper directly against paper with
   nothing to mark the join. `.u-hero` padding-bottom 64px plus
   `#utilities` padding-top 110px = 174px OF CONTINUOUS PAPER, and the
   ladder is FLAT — 174 at 1440, at 921 and at 390, because no media query
   touches either value. What varies is only how much dark leaves:
   665.05px at 1440, 764.06px at 921, 1265.25px at 390. The mobile page
   loses the most.

   TWENTY RULES IN THIS SHEET ARE NOW DARK AND ARE RETAINED BY RULING —
   the .u-domains, .u-domain-list and .u-domain families and their
   media-query duplicates. R8 is the consolidated dead-code unit and
   retires them together with the comment at "FOUR DOMAINS, INCLUDING
   PAYOR-PROVIDER SOLUTIONS", which is ALSO retained (R7-c) precisely so R8
   does not inherit twenty unexplained declarations.

   SEVEN STALE REFERENCES TO THIS BAND EXISTED, AND THAT COUNT IS THE POINT.
   Three were found at intake:
     src/pages/our-approach.html  the §2 client-header roster note
     css/pages/utilities.css      the "unlike .u-domain" comparator
     css/pages/utilities.css      the "scoping to .u-domains" comparator
   A fourth was found only AFTER the first build, in a partial the intake
   sweep never covered, and it turned out to be TWO in one clause:
     partials/components/join-utilities.html  :39 "the domains h2"
     partials/components/join-utilities.html  :45,:49 ".u-domain" x2
   A widened sweep then found the seventh, the TWIN of the first:
     css/pages/our-approach.css   :202, the same roster and the same
                                  #4E65DC / 2.6959 warning, in the sheet
                                  rather than the page

   TWO OF THOSE POINTERS WERE REPOINTED AT S3, 2026-08-15, AND THEY NAME
   DIFFERENT FILES NOW THAN R7 WROTE. Both referents left for our-approach
   in ABT-2 and this block was never swept: it still said src/pages/about.html
   and css/pages/about.css:179 on the morning of the rename. Measured before
   the repoint — "§2" and "client-header" appeared ZERO times in about.html,
   and #4E65DC / 2.6959 ZERO times in about.css. HAD S3 ONLY RENAMED THEM
   they would now read our-team.html and our-team.css:179: current filenames,
   still wrong, and no longer self-reporting. That is the §59 defect and this
   block is one of its instances.

   THE TWO SELF-REFERENCES LOST THEIR LINE NUMBERS IN THE SAME EDIT, AND NOT
   BECAUSE THE NUMBERS WERE MERELY STALE. They read :454 and :1070. R7 FIXED
   both comparators, so neither string has existed in this sheet since —
   measured: "unlike .u-domain" and "scoping to .u-domains" each return ZERO
   here now. A line number on a record of something that was DELETED can
   never resolve again, and adding this note pushed both targets ten lines
   further away. THE NUMBER WAS THE UNRELIABLE PART, SO THE NUMBER WENT; the
   file and the quoted string identify the referent and no later edit can
   invalidate them. Prefer a quoted string or a selector to a line number
   whenever the record has to outlive the file's current shape.
   SIX ARE FIXED IN R7. THREE COMPARATORS ARE DEFERRED TO R8 BY RULING and
   are named here so R8 inherits them explicitly rather than rediscovering
   them:
     css/pages/why-longitude.css :772   "the same device .u-domains h2 ... use"
     css/pages/why-longitude.css :1002  "THE SAME GRID DEVICE AS ... .u-domains"
     css/pages/why-longitude.css :1060-1061  the :nth-of-type trade note
   They are pointers with no measurement depending on them, and they sit in
   the sheet R8 is already opening.

   UTIL-3 · FOUR TERMINAL PERIODS ARE REMOVED FROM THE "Led by:" CHIPS.
   DIRECTOR-RULED (B1, 2026-08-17). **THIS ENTRY REVERSES A CONSTRAINT THIS
   PAGE ALREADY CARRIED IN WRITING, AND THAT IS WHY IT EXISTS.**

   THE CONSTRAINT BEING REVERSED, quoted from src/pages/utilities.html:263-267:

     "NOT ONE CHARACTER OF CHIP TEXT CHANGED — only anchor tags were inserted
      around six names. Roles, commas, terminal periods and the separator are
      all as authored, and every chip's textContent is byte-identical before
      and after, verified by comparison rather than asserted."

   That was written at 9ai, when the only change to the chips was wrapping six
   names in anchors. It asserted terminal periods were "as authored" and left
   them alone. **B1 overrides it deliberately: the chips are label fragments,
   not sentences, and the director ruled the periods off.** The 9ai statement
   is not deleted from the markup — it is still true about 9ai — but it no
   longer describes the shipped strings, and this entry is the record of why.

   DIRECTION: THE BUILD IS REMOVING PERIODS THE CLIENT AUTHORED. Four strings,
   by exact-match tail, never by pattern:

     Rx   ", CEO."       -> ", CEO"
     FX   ", COO."       -> ", COO"
     CTS  ", CEO."       -> ", CEO"
     CGT  ", President." -> ", President"

   **DO NOT CONFUSE THIS WITH index.html:167, WHICH RUNS THE OPPOSITE WAY, OR
   WITH WL-24, WHICH LANDED IN THIS SAME UNIT.** All three concern terminal
   periods and all three resolve differently:

     index.html:167   CLIENT dropped them; BUILD told NOT to restore  -> leave
     WL-24            CLIENT supplied none; BUILD adds none           -> leave
     UTIL-3 (this)    CLIENT supplied them; BUILD removes them        -> ACT

   The first two are the build declining to intervene. **This one is the build
   intervening.** A reader who meets them together must be able to tell them
   apart without re-deriving, which is the whole reason the direction is stated
   in each entry rather than left to be inferred from the strings.

   CHIP 5 IS EXCLUDED AND THE REASON IS NOT SYMMETRY. "Led by: Snehal Patel,
   MD., Executive in Residence" **already ends without a period** — measured
   U+0065, "e" — so there is nothing to remove. It also carries an INTERNAL
   "MD." which is an ABBREVIATION, not a terminator. **Any pattern-based strip
   would have eaten it.** That is why all four edits are exact-tail matches on
   named strings and why no regex touches this file. Four chips changed, five
   chips exist, and the difference is deliberate.

   THE CHIP -> our-team.html ID COUPLING IS UNAFFECTED. Six of the eleven
   leadership rows carry an id BECAUSE these chips link to them
   (our-team.html:365 records the rule and that the other five were left
   unaddressable on purpose). Every terminal period sits in the trailing text
   node OUTSIDE `</a>`, so no href changed. Verified byte-identical after the
   edit rather than assumed: five chips, six anchors, all unchanged.

   THE TWO ROSTERS REMAIN DELIBERATELY DIFFERENT. This page's accordion is
   Rx · FX · CTS · CGT · MD; the homepage's `.uc` row is Rx · FX · CGT · CTS ·
   MD. index.html was NOT OPENED in this unit and carries ZERO `acc-*`
   elements, so it has no chips to change. **Never align them.**

   ===================================================================== */

/* The hero here is a reading hero, not a staged one — no canvas, no
   sphere. The home page's hero carries the artwork; repeating it would
   make this page read as a second front door rather than as the section
   it is. */
.u-hero{
  padding-top:150px;padding-bottom:64px;
}
/* ---- TWO COLUMNS, AND THE COPY COLUMN'S WIDTH IS LOAD-BEARING -------

   THE h1 MEASURE IS A DIRECTOR REQUIREMENT: 22ch producing THREE lines,
   verified at four widths. A second column narrows the copy column, so
   the budget was MEASURED before this layout was chosen rather than
   after. Sweeping the h1's own max-width on the shipped page:

     at 1440  it renders 3 lines for any width 590..800px  (was 767)
     at 1024  it renders 3 lines for any width 450..630px  (was 576)

   The 1fr / .55fr split with a 48px gap on the existing 1040px .in gives
   the copy column 640px at 1440 and 586px at 1024 — inside both windows,
   with 50px and 136px of slack at the binding low end. `.in` therefore
   stays at 1040 and the hero keeps its alignment with the bands below.

   IF THE h1 COPY, ITS FONT SIZE OR THIS RATIO EVER CHANGES, RE-RUN THAT
   SWEEP. The line count is the requirement; the column width is only the
   means, and nothing on screen announces when it stops being three. */
.u-hero .in{
  max-width:1182px;
  display:flex;align-items:center;gap:5vw;
}
.u-hero-copy{min-width:0;flex:1 1 auto}

/* THE FIGURE MIRRORS THE HOMEPAGE HERO STAGE, MEASURED NOT GUESSED.
   index.html's `.hero .stage` is `min(37vw,480px)` square on a 1320px
   `.in` with a 5vw gap, stacking to `min(350px,72vw)` centred at 920.
   Measured on the shipped homepage: 480.0 @1440, 378.9 @1024, 350.0
   centred @768. Those rules are reproduced here verbatim so the two
   heroes are the same object at every width rather than approximately
   similar.

   `.in` WIDENS 1040 -> 1320 TO MATCH, and that is what makes the h1
   survive. At 480px of figure plus a 72px gap on the old 1040 the copy
   column would have been 512px — below the 590px floor at which the h1
   stops being three lines. On 1320 it is 768px. The homepage breaks out
   wider than the site's 1180 default for the same reason.

   Square by aspect-ratio, so a width change cannot distort it. */
.u-hero-fig{
  margin:0;position:relative;
  flex:0 0 min(37vw,480px);width:min(37vw,480px);
  aspect-ratio:1;
}
.u-hero-vid{
  display:block;width:100%;height:auto;
  aspect-ratio:1 / 1;
  border-radius:50%;
}

/* MEASURE, NOT A BREAK. The headline falls to three lines because the
   measure is set to 22ch, not because anything was inserted into the
   markup. There is no <br>, no &nbsp; and no <wbr> in the h1 — a hard
   break is correct at exactly one viewport and wrong at every other,
   and it survives copy edits as a wrong break rather than reflowing.
   Line counts were measured, not predicted; the figures are in the Unit
   A report. */
.u-hero h1{max-width:22ch}

/* THE ACCENT SPAN TAKES --accent, AND THE TOKEN CHOICE IS A FINDING.
   The dispatch identified it two ways — "the site's existing accent
   violet token" and "the same token the Join Us button uses as its
   background" — and those resolve to DIFFERENT tokens. Measured:
   .btn takes var(--pill-hover) #585EDC (components/buttons.css), while
   --accent is #696FE8 and its documented job in tokens.css is literally
   "type accent: .cta-line, h1/h2 em, nav hover". This is an h1 em, so
   --accent is used.

   THE OTHER READING WOULD ALSO HAVE COLLIDED WITH STEP 3. Using one
   violet as this foreground AND as the quote band's ground is exactly
   the recombination tokens.css forbids: the accent family was split
   because a mark on a ground and a fill carrying its own label want
   opposite things the moment either value moves. --accent stays a
   foreground here; --pill-hover stays a background there. */
.u-hero h1 .u-accent{color:var(--accent)}

/* EYEBROW ONE STEP LARGER: 11px -> 14px, which is the size the homepage
   hero's own kick already uses (`.hero .kick`). It is a step that exists
   on the scale rather than a new value, and it stays mono, uppercase and
   letterspaced — only the size moves. It is still SMALL TEXT at 14px
   regular, so it is judged at 4.5, not 3.0. */
.u-hero .kick{font-size:14px}

.u-hero .lead{
  margin-top:22px;font-size:18px;line-height:1.6;
  color:var(--on-page-body);max-width:56ch;
}
.u-hero .btn{margin-top:30px}

/* =====================================================================
   DOMAINS SECTION — "Built for distinct challenges"

   THE GROUND AND TEXT TOKENS ARE THE HOMEPAGE'S, READ OFF ITS BUILT
   OUTPUT RATHER THAN SAMPLED. The homepage's "Healthcare's biggest
   challenges" section is `#problem.band-plum`, and components/bands.css
   sets `.band-plum{background:var(--ground-dark);color:var(--on-dark)}`
   with `.band-plum .body{color:var(--on-dark-body)}`. Those three tokens
   are reused verbatim below. No hex was sampled and no token was added.

   THE HOMEPAGE'S TEXTURE OVERLAY IS NOT COPIED. That overlay is scoped
   `#problem.band-plum::before` — homepage-only by construction — and its
   .10 opacity was derived against a LIGHTENING paint on that ground. Do
   not carry that number here.
   ===================================================================== */
.u-domains{background:var(--ground-dark);color:var(--on-dark);position:relative}

/* ---- TEXTURE ON THE DARK BAND ------------------------------------------

   SAME TREATMENT AS THE QUOTE BAND — same file, same 18px tile, same
   repeat, same ::before mechanism, and now the SAME opacity (.10) by
   director value. ONLY THE PAINT TOKEN DIFFERS, and that difference is
   forced.

   THE PAINT MUST LIGHTEN, AND --ink WOULD BE A LITERAL NO-OP HERE.
   --ink is rgb(41,38,49); --ground-dark resolves through --plum to
   rgb(41,38,49). They are THE SAME COLOUR. Painting ink on this band at
   any opacity composites to the ground exactly — it would render, pass
   every declaration check, and change nothing. DO NOT CARRY THE QUOTE
   BAND'S PAINT ACROSS.

   --slate IS NOT A GUESS: it is the token the homepage ALREADY paints on
   this identical ground (`#problem.band-plum::before`, css/pages/home.css).
   Same ground, same lightening direction, established precedent. No new
   token, no new asset, no colour value outside tokens.css.

   WHICH END BINDS INVERTS, AND THIS IS THE WHOLE POINT.
   The paint LIGHTENS, so the ground moves TOWARD the light text: the
   worst case is the FULLY-LIT composite and the bare ground is the BEST
   case. The quote band is the mirror image — its paint darkens, its BARE
   ground binds at 5.1858, and that figure is INVARIANT under any ink
   opacity. Do not carry either band's reasoning to the other.

     bare      rgb(41,38,49)     L* 15.90   body 8.6943   <- best case
     fully-lit rgb(46.3,45.8,57.3) L* 19.33 body 7.8662   <- BINDING, vs 4.5

   AMPLITUDE HISTORY: .24 -> .15 -> .10, all director values. Every step
   down IMPROVES this band and cannot harm it, because lowering opacity
   moves the binding fully-lit end back toward the bare ground. Body has
   gone 6.7609 -> 7.4614 -> 7.8662 across those three steps.

   EQUAL OPACITY IS NOT EQUAL PERCEIVED STEP, AND THAT IS RECORDED RATHER
   THAN CORRECTED. The two bands paint different tokens in OPPOSITE
   directions on different grounds, so a shared opacity cannot produce a
   shared perceived step. Measured at .10/.10: quote dL* -2.90, this band
   dL* +3.43. See the Unit report for the figures and the flag. THIS IS AN
   OBSERVATION FOR ADAM, NOT A LICENCE TO CHANGE THE VALUE. */
.u-domains::before{
  content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  background:var(--slate);
  -webkit-mask-image:url(../../assets/longitude-texture.svg);
          mask-image:url(../../assets/longitude-texture.svg);
  -webkit-mask-size:18px 18px;     mask-size:18px 18px;
  -webkit-mask-repeat:repeat;      mask-repeat:repeat;
  -webkit-mask-position:top left;  mask-position:top left;
  opacity:.10;   /* .24 -> .15 -> .10, director values */
}
/* The content rides above the overlay. WITHOUT THIS the ::before paints
   over the copy — it is a later sibling in paint order. Same reason the
   quote band and the homepage's problem band both carry it. */
.u-domains > .in{position:relative;z-index:1}
.u-domains .u-gold{color:var(--gold)}

/* JOIN HEADING ACCENT — utilities only. join-utilities.html is this page's
   own wrapper; the other four pages carry their own join partials and none
   of them contains this sentence. Measured: the string appears on
   utilities.html once and on the other four zero times. */
#join .u-join-accent{color:var(--accent)}
.u-domains .body strong{font-weight:700;color:var(--on-dark)}

/* ---- TWO COLUMNS BY GRID PLACEMENT, NOT BY MARKUP ORDER -------------

   THE DOM STAYS IN T03 ORDER: h2, body paragraph, list, closing
   paragraph. The timeline is moved into a second column with explicit
   grid-column / grid-row, so the reading order a screen reader and a
   keyboard follow is unchanged and the visual order is a presentation
   layer over it. Reordering the markup would have produced the same
   picture and a different document.

   THE PARAGRAPHS ARE SELECTED BY :nth-of-type, NOT BY A NEW CLASS, so
   no attribute was added to copy-bearing markup. Both carry .body, and
   p is the only element type they share, so nth-of-type(1) is the lead
   paragraph and (2) is the closing one. If a third paragraph is ever
   added to this section these placements must be re-derived — that is
   the cost of a positional selector and it is recorded here rather than
   discovered later. */
.u-domains .in{
  max-width:1040px;
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,.82fr);
  column-gap:5vw;
  align-items:start;
}
.u-domains .in > h2{grid-column:1;grid-row:1;max-width:20ch}
.u-domains .in > p.body:nth-of-type(1){grid-column:1;grid-row:2}
.u-domains .in > .u-domain-list{grid-column:2;grid-row:1 / span 3;align-self:center}
.u-domains .in > p.body:nth-of-type(2){grid-column:1;grid-row:3}
.u-domains .body{margin-top:20px;font-size:16.5px;max-width:68ch;color:var(--on-dark-body)}

/* FOUR DOMAINS, INCLUDING PAYOR-PROVIDER SOLUTIONS.

   THE SECTION THESE RULES STYLED WAS REMOVED IN R7 (2026-08-14) AND THEY
   ARE NOW DARK — nothing on this page matches them. They are RETAINED
   DELIBERATELY, with this rationale beside them, because R8 is the
   consolidated dead-code unit and will retire the rules and this comment
   together. Retiring the comment first would hand R8 twenty unexplained
   declarations and no way to judge them. The copy the band carried is
   recorded in the R7 register entry.
   THIS REVERSES A PRIOR DO-NOT-PUBLISH INSTRUCTION AND THE REVERSAL IS
   DELIBERATE. The build previously carried three and this comment said
   Payor-Provider was pipeline-only and must not be named — that came from
   the T03 content outline and the D19 copy deck. The client-supplied T03
   PDF (2026-08-07) names four and is the governing authority; the
   replacement sheet rules that T03 wins without exception. Do not restore
   the three-item list on the strength of the older documents.

   THE PILL OUTLINE IS REMOVED AND THE ROWS ARE NOW A CONNECTED LIST: a
   filled gold dot per row, a gold connector between consecutive dots,
   label and clause to the right. NO COPY CHANGED — the label text and
   the clause text are exactly as they were, and the label keeps the mono
   uppercase face it already had. Only the pill's border, radius and
   padding are gone. */
/* THE COLUMN IS A GRAPHIC, NOT A BULLET LIST, AND THE THREE MEASUREMENTS
   MOVE TOGETHER. Dot 13 -> 28px, connector 1.5 -> 3px, row rhythm 26 ->
   46px, indent 34 -> 58px, label 10 -> 12px, clause 16 -> 17px. Scaling
   the dot alone would have produced a large bullet beside unchanged type,
   which reads as an error rather than as a deliberate change of register. */
.u-domain-list{
  list-style:none;margin:0;padding:0;
  display:flex;flex-direction:column;gap:0;
}
.u-domain-list li{
  position:relative;
  display:flex;align-items:baseline;flex-wrap:wrap;gap:0;
  padding:0 0 46px 58px;
  font-size:17px;line-height:1.55;color:var(--on-dark-body);
  opacity:0;transform:translateY(10px);
  transition:opacity .5s ease,transform .5s ease;
}
.u-domain-list li:last-child{padding-bottom:0}

/* the dot */
.u-domain-list li::before{
  content:"";position:absolute;left:0;top:0;
  width:28px;height:28px;border-radius:50%;
  background:var(--gold);
  transform:scale(.2);
  transition:transform .5s ease;
}
/* the connector — one segment per gap, so the last row has none.
   scaleY from the top so it reads as drawn downward into the next dot.
   left is (28 - 3) / 2 so the segment is centred under the dot; if the
   dot or the stroke changes, this number is derived from both and has to
   be recomputed rather than nudged. */
.u-domain-list li:not(:last-child)::after{
  content:"";position:absolute;left:12.5px;top:28px;
  width:3px;height:calc(100% - 28px);
  background:var(--gold);
  transform-origin:top center;
  transform:scaleY(0);
  transition:transform .45s ease;
}

/* ---- TOP-DOWN STAGGER, GATED ON THE EXISTING ONE-SHOT REVEAL --------

   NO NEW JAVASCRIPT AND NO NEW OBSERVER. js/reveal.js already carries a
   single IntersectionObserver that adds .on and calls unobserve() on
   first fire, and the <ul> already carried .rv. So this is in-place,
   fires once and settles: no scroll listener, no scrollY read, no
   progress scalar, no requestAnimationFrame, no re-trigger on re-entry.
   The narrow override Adam granted for this section is therefore spent
   on CSS delays only — the register rule in js/reveal.js is not relaxed.

   The delays run dot -> connector -> dot down the four rows. */
.u-domain-list.on li::before{transform:scale(1)}
.u-domain-list.on li::after{transform:scaleY(1)}
.u-domain-list.on li{opacity:1;transform:none}

.u-domain-list.on li:nth-child(1),
.u-domain-list.on li:nth-child(1)::before{transition-delay:0ms}
.u-domain-list.on li:nth-child(1)::after{transition-delay:130ms}
.u-domain-list.on li:nth-child(2),
.u-domain-list.on li:nth-child(2)::before{transition-delay:260ms}
.u-domain-list.on li:nth-child(2)::after{transition-delay:390ms}
.u-domain-list.on li:nth-child(3),
.u-domain-list.on li:nth-child(3)::before{transition-delay:520ms}
.u-domain-list.on li:nth-child(3)::after{transition-delay:650ms}
.u-domain-list.on li:nth-child(4),
.u-domain-list.on li:nth-child(4)::before{transition-delay:780ms}

/* flex:0 1 auto + min-width:0, NOT 0 0 auto. THIS IS A MEASURED FIX, NOT
   A TIDY-UP. At `0 0 auto` the label is pinned to its max-content width;
   enlarging it to 12px at .18em tracking then pushed "Enterprise Shared
   Services" past a 320px viewport — measured 1 overflowing element and
   documentElement.scrollWidth 336. A flex item also will not shrink below
   its min-content size unless min-width is released, so both halves are
   required and neither alone is sufficient. */
/* THE LABEL IS 19px, NOT 18px, AND THE ONE PIXEL IS THE WHOLE REASON IT
   PASSES. --accent on this band's fully-lit composite rgb(46,46,57)
   measures 3.2204. WCAG large text is >=24px, or >=18.66px when bold.

     18px / weight 800 -> SMALL text, threshold 4.5 -> 3.2204 FAILS
     19px / weight 800 -> LARGE text, threshold 3.0 -> 3.2204 PASSES

   18px misses the boundary by 0.66px; 19px clears it by 0.34px. Same
   colour, same weight, visually indistinguishable — the classification is
   doing the work, not the contrast. --accent also fails at 4.5 on the
   BARE ground (3.5594) and at every texture opacity, so this is not
   something a lighter overlay could rescue; --pill-hover is worse still
   at 2.5876.

   THEREFORE: DO NOT REDUCE THIS BELOW 19px, and do not let a media query,
   a rem change or an inherited size push the COMPUTED value under
   18.66px. If it ever computes smaller, the element silently becomes
   small text and the contrast requirement doubles with nothing on screen
   to show it. Computed size is verified at 1440/1024/768/375 in the Unit
   report rather than trusted from this declaration. */
.u-domain{
  flex:0 1 auto;min-width:0;
  font-family:var(--mono);font-size:20px;font-weight:800;letter-spacing:.18em;
  text-transform:uppercase;color:var(--accent);
}

/* =====================================================================
   UNIT B — ACCORDIONS: lockups, larger sans teaser, sand panel, and the
   Ecosystem card in a right-hand column.

   EVERY RULE IS SCOPED `#utilities`, so components/accordion.css stays
   byte-identical. That sheet is linked by utilities.html ONLY (measured:
   1 link tag here, 0 on the other four pages), so editing it would in
   fact be safe today — the scoping is deliberate anyway, because "only
   this page links it" is a fact about the current include graph and not
   a property of the file. `#utilities .acc-mark img` is (1,1,1) against
   accordion.css's (0,1,1) and wins on specificity, not order.
   ===================================================================== */

/* THE LOCKUP REPLACES THE CIRCULAR BADGE. accordion.css sizes the mark as
   a 52px circle holding a 36px square PNG tilted 11.998deg to the hero
   sphere's angle. A wordmark cannot be tilted or circle-cropped, so the
   circle, the fixed square and the rotation are all released — restated
   in full rather than partially overridden, because leaving the rotation
   behind would skew the wordmark and leaving the square would crush its
   4.65:1 aspect. */
/* flex-shrink MUST BE 0 ON THE MARK, AND THIS WAS MEASURED THE WRONG WAY
   ROUND FIRST. Written as `0 1 auto` the mark is shrinkable, and because
   the teaser beside it is long the row's hypothetical main size exceeds
   the container at every width — so flex shrank the mark by an amount
   that depended on how long THAT ROW's teaser happened to be. Measured
   at 1440: five lockups at five different widths — 232.33, 214.80,
   226.31, 155.97, 164.63 — where they must be uniform.

   WORSE AT 320: `max-width:100%` then clamped the WIDTH while `height`
   stayed explicitly set, so the constraint algorithm did not restore the
   aspect. The mark measured 44.06 x 38.00 — ratio 1.16 against the
   asset's 4.65. A squashed wordmark, from two rules that are each
   individually reasonable.

   So the mark does not shrink; the TEASER absorbs, and narrow widths
   reduce the HEIGHT, which takes the width with it and keeps the aspect.
   max-width:100% stays as a backstop that should never bind. */
#utilities .acc-mark{
  flex:0 0 auto;min-width:0;width:auto;height:auto;
  background:none;border-radius:0;
}
/* HEIGHT DRIVES, WIDTH FOLLOWS THE viewBox. All five lockups share
   viewBox "0 0 397.25 85.49" (aspect 4.6467) and DECLARE NO width OR
   height, so a single height drives all five identically — MD included.
   Its badge-path difference changes what it PAINTS, not the box it
   paints into. Measured widths and MD-beside-another are in the report.

   DO NOT TRUST naturalWidth/naturalHeight ON THESE FILES. They read
   300x65, which is Chrome's DEFAULT REPLACED-ELEMENT SIZE for an SVG
   with no intrinsic dimensions (300 wide, height derived from the
   aspect) — not a property of the asset. The <img> width/height
   attributes in the markup are the viewBox rounded to integers, present
   only to reserve the aspect before load; the rendered ratio 4.6465
   tracks the viewBox's 4.6467, not the attributes' 4.6706.

   TRANSFORM:none REMOVES A STATIC TILT, NOT A MOTION. accordion.css sets
   `transform:rotate(11.998deg)` on this img to match the hero sphere's
   angle. It carries NO transition and NO animation, so it was never
   motion in the accessibility sense and never had — or needed — a
   reduced-motion branch. Measured: no rule in any stylesheet targets
   `.acc-mark img` under `prefers-reduced-motion`; that block in
   accordion.css covers `.acc-panel`, `.acc-panel > .acc-inner`, the
   :has() open state and `.acc-ind` pseudo-elements only. So this
   (1,1,1) declaration out-specifies nothing in the accessibility path.
   IF A REDUCE RULE IS EVER ADDED FOR THIS ELEMENT it must be written at
   (1,1,1) or higher — a media query adds no specificity and a class-only
   selector would silently lose to this one. */
#utilities .acc-mark img{
  width:auto;height:75px;max-width:100%;transform:none;
}

/* ---- BUTTON, INDICATOR ------------------------------------------------

   THE + IS NOT A TEXT CHARACTER, AND THAT SETTLES ITS THRESHOLD.
   components/accordion.css draws it as two `content:""` pseudo-element
   bars — `.acc-ind` has textContent length 0, measured. It is therefore a
   NON-TEXT GRAPHICAL OBJECT under SC 1.4.11 at a flat 3.0, not text at
   4.5-or-3.0-by-size. --accent on the accordion ground measures 3.9310
   and PASSES. There is no font-size on it to fall below 18.66px, so that
   failure mode cannot arise here. THE CONTRAST BETWEEN THE TWO CASES IS THE
   POINT AND IT OUTLIVES ANY ONE EXAMPLE: a graphical object is judged at a
   flat 3.0 and cannot be resized out of compliance, whereas TEXT at the same
   colour is judged at 4.5 unless it clears 18.66px bold — so a text element
   passing on --accent is passing on its SIZE, and a later type change can
   fail it silently. This page carried such an element until R7 removed it.

   IF THIS EVER BECOMES A TYPED "+" the analysis changes completely: it
   would become text, 3.9310 would be judged at 4.5 unless it were >=
   18.66px bold, and it would fail. Keep it as bars. */
#utilities .acc-btn{padding:38px 4px}
#utilities .acc-ind{
  flex:0 0 34px;width:34px;height:34px;
  margin-top:0;align-self:center;   /* vertically centred in the row */
}
#utilities .acc-ind::before,
#utilities .acc-ind::after{
  width:30px;height:4px;margin:-2px 0 0 -15px;
  background:var(--accent);
}

/* SPACE ABOVE THE GROUP MATCHED TO THE SPACE BELOW IT. Measured before:
   180px above against 94px below, a ratio of 1.91 — the 54px
   `.acc-list{margin-top}` in components/accordion.css sat on top of the
   section's own 110px padding. Released here; the residual difference is
   closed on the section's own padding so both ends are measured equal
   rather than assumed. Figures are in the Unit report. */
#utilities .acc-list{margin-top:0}
/* Releasing the 54px took 180 -> 126 above against 94 below. The residual
   32px is structural (the section's padding box sits 16px outside the
   first row's border-top at the top and 16px inside the last row at the
   bottom), so it is closed on the section's own padding-bottom rather
   than by trimming the top — that keeps the top at the site's standard
   110px band rhythm. Both ends are then MEASURED equal, not assumed. */
#utilities{padding-bottom:142px}

/* teaser: larger, and explicitly the sans face rather than inherited */
#utilities .acc-desc{
  font-family:var(--sans);
  font-size:18px;line-height:1.45;margin-top:12px;
  color:var(--on-page-body);
}

/* ---- EXPANDED PANEL: sand ground, two columns ----------------------

   PADDING SITS ON THE CHILDREN, NOT ON .acc-inner, AND THAT IS LOAD-
   BEARING. The panel collapses via `grid-template-rows:0fr` on
   .acc-panel with `overflow:hidden` on .acc-inner. Padding on .acc-inner
   would contribute box height that the 0fr row cannot remove, so every
   collapsed row would show a sand strip. Collapsed panel height is
   asserted at 0 in the Unit B report rather than assumed.

   THE SECOND COLUMN IS GRID, SO THE DOM STAYS IN T03 ORDER: body,
   subnote, meta, CTA, then Ecosystem. A reader in source order gets the
   utility before its cross-reference, which is the order the client
   wrote. */
#utilities .acc-inner{
  background:var(--ground-alt);color:var(--on-alt);
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,.62fr);
  column-gap:44px;align-items:start;
}
/* ALL FIVE ROWS USE THIS RULE AS OF 9z. IT IS NOT A CTS MODIFIER.
   It was authored for CTS, which rendered no sidebar card because the copy
   supplied that field empty and an empty card would have claimed otherwise.
   9y removed Rx's card and 9z removed the remaining three, so every panel on
   the page is now a single column and every one of them is styled by this
   line. The rule itself has never changed — it is reused rather than
   duplicated.

   AN EDIT MADE "FOR CTS" MOVES ALL FIVE ROWS, NOT ONE AND NOT TWO. The
   selector name is now the only thing on the page that still suggests this
   is CTS-specific, and it is misleading. Renaming it is safe — it is
   referenced from this sheet and from five class attributes in
   pages/utilities.html, nowhere else — but it was out of scope here and is
   left for a unit that is already touching the markup. */
#utilities .acc-inner-solo{grid-template-columns:minmax(0,1fr)}

#utilities .acc-main{padding:28px 0 32px 72px}
#utilities .acc-body{padding:0 0 4px;max-width:64ch}
#utilities .acc-meta{margin:20px 0 0}
#utilities .acc-note{margin:20px 0 0;max-width:64ch}
#utilities .acc-cta{margin:22px 0 0}

#utilities .acc-eco{
  margin:28px 28px 32px 0;
  background:var(--ground-page);
  border-radius:14px;padding:22px 24px;
}
#utilities .acc-eco-h{
  margin:0;
  font-family:var(--mono);font-size:9.5px;letter-spacing:.18em;
  text-transform:uppercase;font-weight:400;
  color:var(--on-page-soft);
}
#utilities .acc-eco-b{
  margin:12px 0 0;font-size:15px;line-height:1.6;color:var(--on-page);
}
#utilities .acc-eco-b b{font-weight:700}

/* =====================================================================
   9y — THE THREE-COLUMN PANEL (Longitude Rx only, for now)

   SCOPED TO .acc-main-cols, NOT TO .acc-main. FX, CTS, CGT and MD still
   render the 9x panel and are 9z work that is not dispatched. Every rule
   below keys on the modifier so the other four are untouched by
   construction rather than by nobody having noticed them.

   COLOUR IS HELD, LAYOUT IS NOT. The approved rendering sets the collapsed
   summary and these three headings in --accent. Measured on their own
   grounds, --accent is 3.9310 on paper and 3.6759 on cream against a 4.5
   small-text threshold, so both are built in the ink tokens instead:
   the summary stays --ink-body, the headings take --ink-soft. Director
   ruling, 2026-08-12: build the layout, hold the colour. Structure and
   copy match the approved layout; those two colours do not, and the
   divergence reverses in one pass when the token question is settled.

   --accent IS used on the connector, and that is not an inconsistency.
   The connector is non-text decoration held to 3.0, which 3.6759 clears
   on the cream panel ground. The threshold is different because the
   thing being measured is different.
   ===================================================================== */

/* PADDING GAINS A RIGHT SIDE HERE. The 9x panel runs one prose column with
   max-width:64ch, so a zero right padding never showed; a three-column grid
   has no such measure and would run to the panel edge. */
#utilities .acc-main-cols{padding:28px 72px 32px 72px;--colgap:44px}

/* ---- lede + attribution chip ---------------------------------------
   THE FLEX RATIOS ARE WHAT KEEP THE CHIP AT ITS CONTENT WIDTH. It is
   flex:0 0 auto against a lede that is flex:1 1 auto with min-width:0,
   so the lede absorbs every spare pixel — and, since 9aa, gives pixels
   back — while the chip neither grows nor shrinks.

   9y's NOTE HERE CLAIMED THESE RATIOS ALONE STOPPED THE CHIP WRAPPING.
   THEY DO NOT, AND 9z PROVED IT: two rows wrapped with these exact
   ratios in place. Flex ratios govern how a line DISTRIBUTES space;
   they do not govern whether the line BREAKS. That is flex-wrap, below. */
/* THE ROW DOES NOT WRAP, AND THAT IS THE FIX FOR THE CHIP DROPPING.
   At 9z this was flex-wrap:wrap, and a flex line breaks on the items'
   HYPOTHETICAL sizes — flex-basis clamped by max-width — BEFORE any
   shrinking is considered. The lede's hypothetical was its full 58ch
   measure (564.3px at a 896px row), so on the two rows with the longest
   attributions the pair exceeded the row and the chip wrapped to its own
   line: FX over by 19.8px, MD by 59.2px. CGT cleared by only 27.5px, so
   one word added to its attribution would have joined them.

   NARROWING THE LEDE'S max-width WAS REJECTED. It would have had to
   absorb MD's worst case for every row, shortening a measure that is
   correct on the other four to fix two, and it would still have been a
   fixed budget that the next copy edit could exceed.

   nowrap MAKES THE LEDE THE FLEXIBLE ONE INSTEAD. It is already
   flex:1 1 auto with min-width:0, so with the line unable to break it
   shrinks to whatever the chip leaves; the chip is flex:0 0 auto and
   keeps its content width. The chip can no longer drop for ANY
   attribution length — the failure mode is gone rather than budgeted
   for. What a longer attribution now costs is lede measure, which
   degrades a character at a time instead of reflowing the layout.

   THE NARROW BRANCH PUTS wrap BACK, deliberately. Below 920 the panel is
   one column and a chip held beside the lede would crush both. */
#utilities .acc-lede-row{
  display:flex;align-items:flex-start;gap:28px;flex-wrap:nowrap;
}
#utilities .acc-lede{
  flex:1 1 auto;min-width:0;margin:0;max-width:58ch;
  font-size:17.5px;line-height:1.6;color:var(--on-page-body);
}
/* THE CHIP'S TINT IS --ground-page ON --ground-alt — the same paper-on-cream
   pairing the Ecosystem card used inside this identical panel, so it is an
   established surface here rather than a new one. No new token. */
/* THE CHIP'S NAMES ARE LINKS, AND WITHOUT THIS RULE THEY WOULD NOT LOOK
   LIKE ANY. base.css:25 sets a{color:inherit;text-decoration:none}, so a bare
   anchor inside the chip renders EXACTLY as the plain text did — a link with
   no affordance at all, which is worse than no link because it is undetectable.

   THE UNDERLINE IS THE AFFORDANCE AND THE INK DOES NOT CHANGE.
   --accent was measured and FORECLOSED: #696FE8 on the chip's own ground
   (--ground-page paper, NOT the cream panel the chip sits on) reads 3.9310,
   and at 14.5px the text is SMALL against a 4.5 threshold — short by 0.5690.
   Same shape as the .cta-line finding. Do not re-propose a violet chip link.

   Keeping --on-page-body means the link measures what the chip already
   measured: 8.0825 on paper. No new colour, no new token.

   FOCUS USES THE SITE'S EXISTING INDICATOR, --focus, at the same 3px/2px the
   accordion buttons and our-team.html's summaries already use. */
#utilities .acc-chip a{
  color:inherit;
  text-decoration:underline;
  text-underline-offset:2px;
}
#utilities .acc-chip a:focus-visible{outline:3px solid var(--focus);outline-offset:2px}

#utilities .acc-chip{
  flex:0 0 auto;margin:2px 0 0;
  background:var(--ground-page);
  border-radius:999px;padding:9px 18px;
  font-size:14.5px;line-height:1.3;color:var(--on-page-body);
  white-space:nowrap;
}

/* ---- the three-node connector --------------------------------------

   GEOMETRY LIFTED FROM why-longitude.css .wl-conn (lines 920-1012 at 9x),
   INCLUDING ITS REASONING, WHICH IS WHY IT IS WORTH REPEATING RATHER THAN
   RE-DERIVING. The dots are grid items on equal thirds at
   justify-self:center, so their centres sit at 1/6, 1/2 and 5/6 of the rail
   at every width. The segments are absolutely positioned and inset with
   left/right percentages, which resolve against the containing block's
   padding box. A grid-spanning segment would need a percentage margin, and
   a percentage margin on a grid item resolves against its GRID AREA — a
   different basis, and the trap that produced this shape in the first place.

   TOP IS calc(), NOT translateY: the segment has a fixed height, so
   `top:calc(50% - .5px)` centres it arithmetically and leaves transform
   unspoken-for. NOTHING HERE IS SVG, so the Chrome behaviour where the
   individual transform properties silently do not apply to SVG elements
   cannot arise.

   TWO DELIBERATE DEPARTURES FROM .wl-conn, BOTH RULED 2026-08-12:
     rule   — hairline SOLID, not the dotted repeating-linear-gradient.
              Because it is solid, the clip-path draw that .wl-conn needs
              (scaleX would smear a gradient's dots into ovals) has no
              purpose here, and there is no draw at all — see below.
     colour — --accent, not --gold.

   NO ANIMATION, AND THAT IS A DECISION. .wl-conn draws on a .on class from
   reveal.js. This connector lives inside a disclosure panel that is
   visibility:hidden until opened, so a one-shot IntersectionObserver would
   fire against a hidden element and the draw would be spent before anyone
   saw it. It renders complete. No new JavaScript, no new observer.

   THIS IS A SECOND COPY OF A GEOMETRY THAT ALREADY EXISTS IN
   why-longitude.css AND THE DUPLICATION IS KNOWN. Consolidating the two is
   item 5 on the consolidation backlog and was explicitly out of scope
   tonight; why-longitude.css is not to be refactored for this. */
/* --colgap IS ONE VALUE DRIVING FOUR PLACES, AND THAT IS THE WHOLE POINT.
   The column grid, the rail grid and both segment insets read it, so the
   nodes cannot drift off the columns they head when the gutter is retuned.

   THE NODES ARE LEFT-ALIGNED TO THEIR COLUMNS, NOT CENTRED OVER THEM.
   Approved comp: each dot sits at the LEFT EDGE of its column, level with
   the first character of the heading beneath it. That is a different
   requirement from 9y's, and both of 9y's constructions were wrong for it.

   THE HISTORY IS KEPT BECAUSE IT IS THE SAME TRAP TWICE. .wl-conn insets
   its segments at 16.6667% / 50%, putting endpoints at the centres of three
   EQUAL THIRDS — correct on why-longitude, which has no gutter. Carried
   here unchanged at 9y, the outer two nodes landed 14.66px inboard of their
   columns because a 44px gap means a column centre is not a third's centre.
   9y fixed that by deriving the half-width from real geometry. 9aa moves
   the target again, to the column's left edge.

   THE DOTS NOW NEED NO ARITHMETIC AT ALL. They are grid items on the same
   three-column, same-gutter grid as the headings, at justify-self:start —
   so a dot's left edge IS its column's left edge, by construction, at every
   width, with no percentage anywhere. Nothing to re-derive if the gutter or
   the column count changes. THE SEGMENTS still need insets, because they
   are positioned rather than placed, and those are derived below.

   DO NOT VERIFY THIS BY RE-DERIVING THE SAME FORMULA. 9y's geometry probe
   checked the endpoints against the construction that produced them and
   passed a connector whose nodes were 14.66px off the columns — it
   confirmed the code against its own basis. The alignment is verified by
   measuring each dot's left edge against the rendered left edge of the
   heading text beneath it, at six widths, on all five rows. Those figures
   are in the checkpoint notes.

   SEGMENT ENDPOINTS, DERIVED FROM THE COLUMN GEOMETRY:
     a column is  W = (100% - 2*gap)/3
     column lefts are  0,  W+gap,  2*(W+gap)
       = 0,  33.3333% + gap/3,  66.6667% + 2*gap/3
     a dot's centre is its column's left edge + dot/2
   The rule runs dot-1 centre to dot-3 centre and STOPS THERE — it does not
   reach the row's right edge, and the right-hand inset below is what holds
   that. Two segments meeting under dot 2, so the markup is unchanged. */
#utilities .acc-conn{margin:26px 0 0;--dot:24px}
#utilities .acc-conn-rail{
  position:relative;
  display:grid;grid-template-columns:repeat(3,1fr);
  column-gap:var(--colgap);
  align-items:center;height:var(--dot);
}
#utilities .acc-cx-dot{
  grid-row:1;justify-self:start;
  width:var(--dot);height:var(--dot);border-radius:50%;
  background:var(--accent);
  /* above the segments, so a segment running under a dot cannot show
     through it. z-index alone is not enough on a static element. */
  position:relative;z-index:1;
}
#utilities .acc-cx-1{grid-column:1}
#utilities .acc-cx-3{grid-column:2}
#utilities .acc-cx-5{grid-column:3}
#utilities .acc-cx-seg{
  position:absolute;top:calc(50% - .5px);height:1px;z-index:0;
  background:var(--accent);
}
/* dot-1 centre -> dot-2 centre */
#utilities .acc-cx-2{
  left:calc(var(--dot)/2);
  right:calc(66.6667% - var(--colgap)/3 - var(--dot)/2);
}
/* dot-2 centre -> dot-3 centre */
#utilities .acc-cx-4{
  left:calc(33.3333% + var(--colgap)/3 + var(--dot)/2);
  right:calc(33.3333% - 2*var(--colgap)/3 - var(--dot)/2);
}

/* ---- the three columns ---------------------------------------------
   align-items:start so a short column's heading does not float against a
   tall neighbour's baseline. */
#utilities .acc-cols{
  margin:26px 0 0;
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  column-gap:var(--colgap);row-gap:28px;align-items:start;
}
/* ####################################################################
   FIFTEEN ELEMENTS DEPEND ON THE SIZE AND WEIGHT BELOW FOR A LARGE
   CLASSIFICATION. DROPPING EITHER FAILS ALL FIFTEEN, SILENTLY.

   The three column headings render in --accent on the cream panel ground
   at a MEASURED 3.6759. That is legal ONLY as LARGE text, where the
   threshold is 3.0. LARGE requires >=18.66px AND >=700. This rule sits at
   19px / 700 with 0.34px and nothing to spare on the weight.

     --accent on cream, measured          3.6759
     threshold as LARGE (>=18.66 & >=700)    3.0   <- clears by 0.6759
     threshold as SMALL                      4.5   <- FAILS by 0.8241

   Take the size to 18px, or the weight to 600, and every one of the
   fifteen reclassifies as SMALL and fails by 0.8241. NOTHING REPORTS IT.
   The colour does not change, the markup does not change, no console
   warning fires, and a contrast checker pointed at the token still
   returns 3.6759 — the number was never wrong, only the threshold it is
   read against. This is the same shape as the .cta-line note in
   components/buttons.css, and it is now load-bearing in two places.

   RECOLOURING TO #4E65DC DOES NOT RESCUE IT. Measured on this ground:
   4.3910, still short of 4.5. There is no value of the accent that makes
   a SMALL classification legal here, so the size and weight ARE the
   accessibility mechanism. Treat them as such.

   9y HELD THIS ELEMENT AT --ink-soft FOR EXACTLY THIS REASON, at 9.5px
   where LARGE was unreachable. The 2026-08-12 ruling lifted the hold for
   these headings ONLY, because the size change crosses the boundary. The
   collapsed summary is NOT covered and stays --ink-body — it sits at 18px
   on paper, under 18.66, and would fail at 3.9310 against 4.5.

   19px / 700 / --accent IS .cta-line's TREATMENT, ADOPTED DELIBERATELY.
   That element already sits in this component at this ratio and has
   already been ruled. These headings inherit a measured precedent instead
   of establishing a new one, which is why no new measurement was needed
   for the colour — only for the wrap, which is recorded in the notes.

   THE FACE IS UNCHANGED AND STAYS MONO. The ruling enumerated size,
   weight, uppercase and colour; it did not name a face, and .cta-line's
   sans is not part of what makes the ratio legal. Changing it would be a
   design move made under cover of an accessibility edit.

   LETTERSPACING DROPS .18em -> .04em, AND THAT IS NOT A FREE CHOICE.
   .18em was tuned for a 9.5px micro-label. Carried to 19px it doubles the
   tracking in absolute terms and pushes the longest heading well past its
   column. .04em is the working value at this size; the wrap measurements
   at every breakpoint are in the checkpoint notes.
   #################################################################### */
#utilities .acc-col-h{
  margin:0;
  font-family:var(--mono);font-size:19px;letter-spacing:.04em;
  text-transform:uppercase;font-weight:700;
  color:var(--accent);
}
#utilities .acc-col-b{
  margin:12px 0 0;font-size:15px;line-height:1.6;color:var(--on-page-body);
}

@media(max-width:920px){
  /* one column: the card drops beneath the body rather than beside it,
     which is also DOM order, so nothing reorders on the narrow path. */
  #utilities .acc-inner{grid-template-columns:minmax(0,1fr)}
  #utilities .acc-main{padding:24px 20px 8px}
  #utilities .acc-eco{margin:0 20px 26px}
  #utilities .acc-mark img{height:38px}
  #utilities .acc-desc{font-size:16.5px}

  /* 9y: the three columns stack, and the connector goes with them rather
     than staying a horizontal rail above a vertical list — a three-node
     row above one column would point at nothing. The rail is removed from
     flow entirely instead of being restyled into a vertical variant: it is
     decorative and aria-hidden, so nothing announced is lost, and the copy
     it sat above is unchanged. THE COLUMN HEADINGS ARE NOT RESIZED — 9.5px
     is what the 4.6361 was measured at, and shrinking them on the narrow
     path would move a ratio that already has only 0.1361 of margin. */
  #utilities .acc-main-cols{padding:24px 20px 8px}
  #utilities .acc-cols{grid-template-columns:minmax(0,1fr);row-gap:24px}
  #utilities .acc-conn{display:none}
  /* the row is nowrap above this breakpoint; one column has no room to
     hold the chip beside the lede, so it wraps again here. */
  #utilities .acc-lede-row{flex-wrap:wrap}

  /* white-space:normal ALONE NEVER WRAPPED THIS CHIP, AND IT SHIPPED THAT
     WAY FROM 9y THROUGH 9z. The declaration PERMITS a break; it does not
     force the box narrower. The chip was flex:0 0 auto, so its flex-basis
     resolved to max-content and flex-shrink:0 refused to reduce it — the
     text had permission to wrap inside a box that was never made narrow
     enough to need to. Measured before this fix: the chip's right edge
     cleared its own content box by up to 150.9px at 320 and by 56.9px at
     414, and pushed past the VIEWPORT on three rows at 320.

     IT WAS MISSED BY A PROBE THAT MEASURED THE WRONG BOX. 9z checked
     .acc-inner's rect for overflow and reported none at every width. The
     overflowing element was the chip, and .acc-inner is overflow:visible,
     so a child crossing its edge cannot move the parent's rect. The
     measurement was correct and the noun was wrong.

     flex:0 1 auto RESTORES SHRINKING and min-width:0 lets it go below
     min-content; max-width:100% is the backstop that makes exceeding the
     line box impossible rather than merely unlikely. Verify this by
     measuring the CHIP's right edge against .acc-main-cols' content-box
     right edge — never by measuring the panel. */
  #utilities .acc-chip{
    white-space:normal;
    flex:0 1 auto;min-width:0;max-width:100%;
  }
}
/* At phone widths a 4.65:1 wordmark cannot share a row with the teaser
   and the expand control: even at 34px it is ~158px of a ~244px content
   box. The mark takes its own full-width line instead — flex-basis 100%,
   NOT `order`, so the visual sequence still matches DOM sequence and the
   button's accessible name (alt, then teaser) is computed from contents
   in the order they are written. */
@media(max-width:560px){
  #utilities .acc-btn{flex-wrap:wrap;row-gap:12px}
  #utilities .acc-mark{flex:0 0 100%}
  #utilities .acc-mark img{height:34px}
}

/* closing roadmap + CTA */
.u-close{text-align:center}
.u-close .in{max-width:760px}
.u-close p{
  margin-top:20px;font-size:18px;line-height:1.6;
  color:var(--on-page-body);
}
.u-close .btn{margin-top:32px}

/* =====================================================================
   QUOTE BAND — UTILITIES ONLY, SCOPED .band-slate.u-quote

   EVERY RULE HERE IS DOUBLE-CLASSED SO components/quote-block.css STAYS
   BYTE-IDENTICAL. That sheet is shared: index.html renders the only
   other element matching its bare `blockquote`, `blockquote::before` and
   `.attrib` selectors, and editing any of them would move the homepage's
   quote — which is AA-verified against its own shipped bytes and cannot
   be seen from this page. `.band-slate.u-quote` is (0,2,0) against
   `.band-slate` (0,1,0) and wins on specificity alone.
   ===================================================================== */

/* GROUND: --pill-hover, AND THE CHOICE IS FORCED BY THE ATTRIBUTION.
   .attrib is --white at 10.5px — SMALL TEXT, threshold 4.5 — and it is
   the tightest element on this band, exactly as the dispatch predicted.
   Measured white-on-violet: --accent/--pill #696FE8 gives 4.1669 and
   FAILS; --pill-hover #585EDC gives 5.1858 and passes. tokens.css
   independently records 5.1858 for the button's white label on this same
   value, which is the same pairing doing the same job.

   THE TEXTURE CANNOT RESCUE THE OTHER CANDIDATE. The overlay paints
   --ink, which DARKENS, so for light text the worst case is the bare,
   un-inked ground — invariant under the overlay. A failing bare ground
   stays failing at every opacity. */
.band-slate.u-quote{background:var(--pill-hover);color:var(--on-pill)}

/* TEXTURE — longitude-texture.svg as a MASK, never a background-image.
   The file's single <path> carries no fill attribute, so painting it
   directly would put black into the build; as a mask its alpha decides
   WHERE paint lands and an existing token decides WHAT the paint is.
   Zero colour literals enter the build.

   ITS viewBox IS SQUARE (0 0 72.36 72.36), SO IT TILES. That supersedes
   the no-tiling ruling in components/quote-block.css, which was measured
   on the 8000px lattice raster whose motif period is non-integer. Two
   different files, two different answers; the lattice rule still stands
   for the lattice and both textures stay live.

   Every longhand the shared ::before sets is RESTATED here rather than
   partially overridden — mask-size, mask-repeat and mask-position all
   have to move together or the cover/no-repeat pair survives underneath. */
.band-slate.u-quote::before{
  background:var(--ink);
  -webkit-mask-image:url(../../assets/longitude-texture.svg);
          mask-image:url(../../assets/longitude-texture.svg);
  -webkit-mask-size:18px 18px;     mask-size:18px 18px;
  -webkit-mask-repeat:repeat;      mask-repeat:repeat;
  -webkit-mask-position:top left;  mask-position:top left;
  opacity:.10;   /* .28 -> .15 -> .10, director values */
}
/* AMPLITUDE HISTORY. .14 -> .28 (2026-08-08) with the tile 72 -> 48px,
   then -> .15 with the tile 48 -> 18px on director value 2026-08-09.
   The mechanism has never changed: same mask, same repeat, same SVG,
   same paint token — only amplitude and tile.

   THE PATTERN WAS ALWAYS PAINTING. The 2026-08-08 raise was made because
   the texture "looked invisible", and that premise was later disproved by
   pixel count — see the handoff §17.1. DO NOT INFER A RENDER FAULT FROM
   AN AMPLITUDE JUDGEMENT; count pixels first.

   BARE GROUND BINDS ON THIS BAND AND IS INVARIANT UNDER OPACITY. --ink
   darkens, so for light text the worst case is the un-inked ground at
   white 5.1858 — no ink opacity can move it. Amplitude here is therefore
   a legibility decision, never a contrast one. The dark band is the
   mirror image and its FULLY-LIT end binds; do not carry either band's
   reasoning across.

   THE PAINT STAYS --ink AND MUST NOT BECOME WHITE OR ANY LIGHTER VALUE.
   Modelled before building: white at .08 alpha already drops white-on-
   composite to 4.4473 and FAILS .attrib at 4.5; .12 gives 4.1371 and .20
   gives 3.5554. There is no white opacity that is both visible and
   passing. --ink DARKENS, so every increase moves text contrast the safe
   way, and the binding number for light text stays the BARE un-inked
   ground at 5.1858 — invariant under this overlay, which is why raising
   the amplitude is a legibility decision here and not a contrast one.
   DO NOT CARRY THIS NUMBER TO THE SLATE BAND OR THE PROBLEM BAND; all
   three grounds invert differently. */

/* THE MARK READS AS A DISPLAY ELEMENT, NOT AN ORNAMENT: 96px -> 160px.
   It stays --gold on the new ground and measures 2.8727, below 3.0.
   THAT IS DELIBERATE AND IS NOT A NEW FAILURE. It is decorative under
   1.4.11 — a typographic quotation mark adjacent to text that itself
   passes, carrying no information the quote does not — and it is the
   same standing decision as Ruling O, which left the identical mark at
   2.7008 on the slate ground. Enlarging a decorative mark does not make
   it informational. Do not open it as a defect. */
.band-slate.u-quote blockquote::before{
  font-size:160px;line-height:.42;margin-bottom:10px;
}

/* PORTRAIT — CAPPED AT 200 CSS px BECAUSE THE SOURCE IS 200x200.
   lh-portrait-patel-binita.jpg is a CLIENT-SUPPLIED photograph of a real
   named person. NEVER AI-generated, AI-upscaled or AI-enhanced; never a
   style, reference, frame-capture, interpolation or synthesis input.
   Mechanical crop and resize only. APPROVAL TO USE IS NOT PERMISSION TO
   PROCESS.

   200 CSS px IS THE CEILING AND IT IS ALREADY AT IT. At DPR 1 that needs
   200 backing pixels and the file has exactly 200 — zero headroom. At
   DPR 2 it needs 400 and the file cannot supply them, so the image is
   already relying on the browser's own downscale-free 1:1 path at DPR 1
   and will be softer at DPR 2. THIS IS NOT FIXABLE HERE: no sharpening,
   smoothing, enhancement or filter may be applied, and no larger variant
   may be generated by any means. If more presence is wanted, request a
   higher-resolution original from the client. Reported to Adam in the
   Unit A report rather than worked around.

   300 CSS px IS A TEMPORARY, DIRECTOR-APPROVED DISPLAY SIZE AND IS NOT
   AN ENDORSED CEILING. Adam overrode the 200px cap knowingly on
   2026-08-08 to judge whether the composition lands before commissioning
   a replacement photograph. THE FILE IS UNCHANGED — this is a CSS size
   change and nothing else; the asset is byte-identical and no upscale,
   resample, sharpen, filter or second variant was produced. The portrait
   rule bars PROCESSING the asset; it does not bar the browser scaling it.

   THE SOFTNESS IS REAL AND IS THE POINT OF THE TRIAL: 200 backing pixels
   against 300 CSS px is 1.5x short at DPR 1 and 3x short at DPR 2. When
   the higher-resolution original arrives, this block is where the size
   lives; if the trial is abandoned instead, revert to 200. */
.band-slate.u-quote .portrait{flex:0 0 300px;width:300px;height:300px}

@media(max-width:920px){
  .u-hero{padding-top:128px}
  /* ONE COLUMN BELOW 920. Stacking restores the h1's full 22ch measure,
     so the 768/375/320 line counts are exactly what they were before the
     video existed — verified, not assumed. Stacked order is DOM order:
     eyebrow, h1, body, CTA, then video. */
  .u-hero .in{flex-direction:column;align-items:flex-start}
  .u-hero-fig{flex-basis:auto;width:min(350px,72vw);align-self:center;margin-top:26px}
  /* one column: the grid placements above must be RELEASED, not just
     overridden column-wise, or the explicit grid-row values keep the
     closing paragraph pinned to row 3 beneath an empty row 2. Stacked
     order is DOM order — h2, body, list, closing — which is what the
     narrow reading order is required to be. */
  .u-domains .in{grid-template-columns:minmax(0,1fr);column-gap:0}
  .u-domains .in > h2,
  .u-domains .in > p.body:nth-of-type(1),
  .u-domains .in > .u-domain-list,
  .u-domains .in > p.body:nth-of-type(2){
    grid-column:1;grid-row:auto;align-self:stretch;
  }
  .u-domain-list{margin-top:28px}
}
@media(max-width:760px){
  .band-slate.u-quote .portrait{flex-basis:220px;width:220px;height:220px}
}
/* NARROW STEP-DOWN. The enlarged graphic is sized for the second column;
   at phone widths the same 28px dot and 58px indent eat a fifth of the
   viewport. Dot, connector offset, indent and rhythm step down TOGETHER —
   the connector's left is (22 - 3) / 2, re-derived from the smaller dot
   rather than carried over, because a stale offset here puts the segment
   off-centre and nothing errors. */
@media(max-width:560px){
  .u-domain-list li{padding:0 0 34px 44px;font-size:16px}
  .u-domain-list li::before{width:22px;height:22px}
  .u-domain-list li:not(:last-child)::after{left:9.5px;top:22px;height:calc(100% - 22px)}
  /* THE SIZE STEP-DOWN IS DELETED, NOT REDUCED. This block used to carry
     `.u-domain{font-size:11px}`, authored when the label was 12px mono.
     After the colour change that override silently reclassified the
     element as SMALL text at 375 and failed it at 4.5 — the base size was
     never the problem, this override was. FIT IS FIXED WITH TRACKING,
     WHICH DOES NOT TOUCH THE CLASSIFICATION. Never reintroduce a
     font-size step-down here at any breakpoint. */
  .u-domain{letter-spacing:.06em}
}

/* =====================================================================
   REDUCED MOTION — FINAL STATE, IMMEDIATELY, EVERY SELECTOR RESTATED

   A MEDIA QUERY ADDS NO SPECIFICITY, so each rule below is written to
   out-specify the animated rule it replaces rather than relying on being
   later in the file. THE TECHNIQUE, STATED WITHOUT ITS ORIGINAL EXAMPLE:
   scope each reduced-motion rule one class deeper than the animated rule it
   overrides, so it wins on specificity alone and the breakpoint cannot be
   defeated by source order. The pair this block was written for measured
   (0,1,2) at rest and (0,2,2) revealed, and the scoped overrides (0,2,2) and
   (0,3,2); that section was removed in R7 and those particular rules are now
   dark, but the rule of thumb governs everything added here later. No
   shorthand and no wildcard: a
   `*{animation:none}` sweep would also silently disable anything added
   here later without anyone noticing it had been covered.
   ===================================================================== */
@media(prefers-reduced-motion:reduce){
  /* AUTOPLAY IS AN HTML ATTRIBUTE AND NO MEDIA QUERY CAN SUPPRESS IT —
     js/hero-video.js pauses and rewinds under reduce. These rules only
     ensure nothing here animates. Every selector is restated in full;
     a media query adds no specificity. */
  .u-hero-fig,
  .u-hero-fig.rv,
  .u-hero-fig.rv.on{opacity:1;transform:none;transition:none;transition-delay:0s}
  .u-hero-vid{transition:none;animation:none}
  .u-domains .u-domain-list li,
  .u-domains .u-domain-list.on li{
    opacity:1;transform:none;transition:none;transition-delay:0s;
  }
  .u-domains .u-domain-list li::before,
  .u-domains .u-domain-list.on li::before{
    opacity:1;transform:scale(1);transition:none;transition-delay:0s;
  }
  .u-domains .u-domain-list li:not(:last-child)::after,
  .u-domains .u-domain-list.on li:not(:last-child)::after{
    opacity:1;transform:scaleY(1);transition:none;transition-delay:0s;
  }
}
