/* =====================================================================
   WHY LONGITUDE — page sheet
   Copy source: longitude-t02-why-longitude-2026-08-07.md, Part A, verbatim.
   No colour value appears here. Everything refers to css/tokens.css.
   =====================================================================

   VERIFY BY COMPUTED VALUE ON A REAL ELEMENT, NOT BY READING THIS FILE.
   A selector split reads as obviously-winning far more often than it wins.

   That sentence has now been orphaned TWICE IN ONE DAY — it was written
   beside a class-scoped rule R1 retired, re-homed beside the id-scoped
   rule that replaced it, and orphaned again when R4 deleted that section.
   It is general, it is not about any one rule, and it is parked here so
   there is no third time. It is also §48 in the discipline catalogue.

   TYPOGRAPHIC DEVIATION LOG

   Every place this page departs from T02's Part A, and why. Nothing here
   is a repair: T02 wins verbatim and the departures below are structural,
   ruled, or artifacts of the PDF the copy was transcribed from.

   1. "See the model" ships as "See the model" plus a space and U+2192.
      R3. The trailing arrow is a site-wide CTA convention carried by .btn
      and .cta-line on both built pages, and the other four T02 CTAs
      already have it. Convention, not copy.

   2. specialty-as-a-service — hyphen restored. The PDF breaks the word
      across a line and the extractor emitted it unhyphenated. Confirmed
      rather than inferred: both built pages already carry a 118-character
      identical run ending "specialty-as-a-service, and payor-provider
      solutions". Same class as Ruling 6 (back-office).

   3. "Group purchasing organizations" — joined from a PDF line break.
      Same class as 2, but with NO built-page confirmation behind it.
      Weaker evidence, recorded as such.

   4. T02 §3 carries a sentence that does not parse and whose provenance is
      unresolved: "Every utility funded, they hold member value in." It is
      transcribed EXACTLY. Not paraphrased, not repaired, not smoothed.
      It is with the client. Do not fix it here.

   5. "health system-owned" in the hero and "health-system owned" inside
      the Childs quote. Both stay. The quote is verbatim client speech.

   6. The domain list. T02 reads "The platform spans pharmacy and
      therapeutics…"; both built pages prefix "specialty" before it. T02
      wins on this page. The one-word divergence across three pages is the
      client's to resolve.

   7. The bracketed design note in T02 §5 is a client instruction to us,
      not page copy. Deliberately not rendered.

   8. T02 §5's header is split into an h2 and a deck paragraph. R2.
      Every character preserved, none moved between the two, including the
      colon that ends the heading and the capital that opens the deck.

   9. The meta description is two contiguous sentences lifted verbatim from
      T02 §5's body. T02 supplies no meta copy and invention is barred, so
      this is a selection rather than an authoring decision.

   10. T02 prints "Model Comparison" as a bold label immediately above the
       table. It renders as the table's <caption>, which is the element for
       exactly that. Structural placement of existing copy — zero characters
       changed — and it avoids inventing a heading the source does not have.

   11. The join band's h2 is the homepage's approved line, lifted verbatim
       from partials/components/join-home.html including its inline
       emphasis. R4. The copy column carries the heading and nothing else.

   12. §6's Childs quote loses its enclosing ASCII quotation marks.
       Ruling F, T02 B6. Part A is uniformly ASCII and carries exactly two
       U+0022 — this quote's own opening and closing pair. components/
       quote-block.css renders the typographic ornament through
       blockquote::before, so keeping the literal pair would set the
       quotation twice. 501 characters in the source, 499 rendered, and
       the two removed are the pair and nothing else. The Patel precedent.

   13. The five headings carry a wrap-only <em> (8u). Emphasis phrases are
       a director ruling and the wrap changes no character: every
       heading's textContent is byte-identical before and after, verified
       by comparison rather than asserted. §6's heading deliberately
       carries NO <em> — the ruling names five phrases and this is not one
       of them, and inventing a sixth would be a copy decision.

   13a. §2's WRAP MOVED ONE WORD LEFT IN 9b, ON A DESIGN-LEAD REVISION:
       "structural challenges." becomes "solve structural challenges."
       Still a re-wrap and still not a copy edit — the word "solve" was
       already in the heading and simply crossed the tag boundary, and
       the heading's textContent is byte-identical before and after at 74
       characters, verified by comparison. This is the only one of the six
       wraps that moved and the only one carrying class="g"; the other
       five are untouched and stay --accent. NOTE FOR ANY FUTURE AUDIT OF
       ITEM 13: the count of emphasis wraps on this page is SIX, not five
       — the hero's h1 carries one that predates 8u's five h2 phrases.
       Count them on the DOM, not from this log.

   14. TWO PARAGRAPHS OF §3 ARE DELETED. DIRECTOR-APPROVED (9c). This is
       the FIRST DELETION AGAINST T02 ON THIS PAGE and it is a different
       class of departure from every item above it — 1 to 13a change how
       existing copy is marked up, sized or wrapped; this one removes
       copy the source supplies. Recorded as such so it is not read as a
       re-grouping. The two are:
         - "The value doesn't stop at the member level. As more utilities
           are built, …reusable infrastructure."
         - "Longitude is showing a new path for transformation: one that
           doesn't require health systems to choose between moving fast
           and keeping control."
       Nothing was written to replace them. T02's §3 is now five
       paragraphs' worth of copy rendered as three groups plus a
       connector.

   15. §3's REMAINING COPY IS RE-GROUPED ACROSS ELEMENTS, WHICH DROPS
       CONNECTIVES AND CAPITALISES FRAGMENTS (9c). Sentence-internal
       fragments are promoted to their own elements, and a fragment that
       starts an element takes a capital. Every character-level delta,
       enumerated so none of them is discovered later and "fixed":

         T02 "…three functions: a fund that capitalizes each utility, an
         incubation function that builds it, and a membership
         organization through which member system CEOs set the
         direction."
           -> cue line  "The structure works across three functions:"
           -> node 1    "A fund that capitalizes each utility"
                        lower-case "a" -> "A"; trailing comma dropped
           -> node 2    "An incubation function that builds it"
                        "an" -> "An"; trailing comma dropped
           -> node 3    "membership organization"
                        "and a " dropped; NO capital — this fragment
                        continues into its own subordinate line and
                        capitalising it would assert a sentence break
                        the copy does not have
           -> node 3 sub "through which member system CEOs set the
                        direction."

         T02 "…delivered: solutions built…buyers; a genuine role…needs;
         and participation in a model…economic."
           -> item 1    "Solutions built…buyers"
                        "s" -> "S"; trailing semicolon dropped
           -> item 2    "A genuine role…needs"
                        "a" -> "A"; trailing semicolon dropped
           -> item 3    "Participation in a model…economic."
                        "and p" -> "P"; keeps its full stop

       DO NOT "RESTORE" ANY OF THESE. Node 3's lower-case m in
       particular reads as an error and is not one.

       *** NODE 3's ENTRY ABOVE IS SUPERSEDED BY 9af, 2026-08-13. THE REST
       OF ITEM 15 STANDS UNCHANGED. ***
       The original text is left visible deliberately — a later reader needs
       to see what was ruled and why it stopped applying, not a silently
       rewritten entry.

       WHAT CHANGED: node 3's rationale was that the fragment "continues
       into its own subordinate line", so capitalising it would assert a
       sentence break the copy does not have. CLIENT DIRECTION REMOVED THAT
       SUBORDINATE LINE (deviation 17). The rationale is not overruled — it
       is VOIDED BY THE REMOVAL OF THE THING IT DEPENDED ON. With the line
       gone, node 3 is a complete standalone fragment, and the lower-case m
       becomes exactly the error this entry said it was not.

       NODE 3 NOW READS "A membership organization". The "and a " that item
       15 recorded as dropped is restored as "A ", and the capital is now
       correct rather than forbidden. Nodes 1 and 2 are untouched and their
       entries above still apply as written.

   16. §4 IS RESTRUCTURED, ONE PARAGRAPH IS DELETED, AND TWO WORDS ARE
       AUTHORED. DIRECTOR-APPROVED (9f). Third restructure on this page
       and the first to introduce copy that is not in T02 at all — that
       is a different class of departure from 14 and 15 and is separated
       out below.

       (a) DELETED. The paragraph beginning "The platform spans pharmacy
           and therapeutics". Its content restructures into the right
           column and ITS FINAL SENTENCE IS RETAINED VERBATIM as the
           closing line: "That value compounds as the network scales."

       (b) AUTHORED — NOT IN T02. The label "Member returns:". T02 has
           "— returning revenue growth, … to the systems that built it";
           the label replaces that framing. The words "Member returns"
           appear nowhere in the source. Approved by the director as new
           copy. THIS IS THE ONLY AUTHORED STRING ON THE PAGE; every
           other departure in this log moves, wraps or drops existing
           characters. Do not let it set a precedent by resemblance.

       (c) RE-GROUPED, same class as 15 — fragments promoted to their own
           elements, dropping connectives and capitalising openings:

             "The platform spans" -> label "The platform spans:"
                        colon added; the verb keeps its own words
             "pharmacy and therapeutics,"   -> "Pharmacy and therapeutics"
             "enterprise shared services,"  -> "Enterprise shared services"
             "specialty-as-a-service,"      -> "Specialty-as-a-service"
             "and payor-provider solutions" -> "Payor-provider solutions"
             "revenue growth,"              -> "Revenue growth"
             "cost reduction,"              -> "Cost reduction"
             "expanded patient access,"     -> "Expanded patient access"
             "and industry transformation"  -> "Industry transformation"

           In every case: leading article or "and " dropped, first letter
           capitalised, trailing comma dropped. The em dash before
           "returning" and the clause "to the systems that built it" are
           dropped with the sentence that carried them.

       (d) THE HEADING'S WRAP MOVED AND ITS COLOUR CHANGED. It was
           "grow more valuable over time." in --accent; it is now
           "designed to grow more valuable over time." in --gold via
           base.css's `h2 em.g`. Same device as 13a. The heading's
           textContent is byte-identical before and after — verified by
           comparison, not asserted. This is the SECOND heading on the
           page carrying .g; #fragmentation's is the first.

       (e) THE CTA IS A TEXT LINK AND THE MOCK SHOWS A FILLED BUTTON.
           THIS IS A DEVIATION FROM THE DESIGN LEAD'S MOCK, RULED, NOT AN
           OMISSION. The copy "Explore our Ecosystem →" is unchanged; the
           promotion to .btn that 9c performed for Join Us was attempted
           here, MEASURED, and REVERTED.

           --pill-hover measures 2.8600 against this band's bare ground
           and 2.5876 against its inked composite, both under SC 1.4.11's
           3.0 for non-text contrast. That is the standing prohibition
           this page already carries — "A .btn MAY NEVER SIT ON
           .band-plum — its --pill-hover fill measures 2.8600 against the
           3.0 non-text threshold" — reaching this band BY VALUE, because
           --ground-fill and --plum hold the same colour. Reproducing
           2.8600 to four decimals is confirmation, not coincidence.

           .cta-line takes --accent at 19px/700, which clears 18.66px
           bold and is therefore LARGE text at threshold 3.0: 3.2204 on
           the inked composite, 3.5594 bare. The same treatment both plum
           bands already carry, and the reason the standing prohibition
           "costs nothing here".

           A STANDING MEASURED RULING BEATS A FRESH INSTRUCTION THAT DID
           NOT KNOW ABOUT IT. Do not re-promote this button without
           moving --pill-hover or the ground.

   17. A SECOND DELETION AGAINST T02. DIRECTOR-APPROVED (9af,
       2026-08-13). Item 14 records itself as the FIRST deletion against
       T02 on this page and separates that class sharply from the
       re-groupings of 15 and 16. This is the second, and it belongs in
       14's class, not 15's: it removes source copy rather than moving or
       re-marking it.

       WHAT WAS REMOVED, BY LOCATION AND NOT BY QUOTATION: the subordinate
       span element inside the third connector node, on the line
       src/pages/why-longitude.html carried as 265 at checkpoint-9ae.
       Per §7.18 the removed string is not reproduced here — quoting it
       would leave every future grep matching this log as well as any
       surviving copy, and reporting one more than the page contains.

       WHAT HAPPENED TO T02's FRAGMENT, IN FULL. T02's sentence closed
       "...and a membership organization through which member system CEOs
       set the direction." Item 15 dropped the leading "and a ". 9af
       removes the trailing clause AND supplies "A " in its place. So the
       whole of that fragment has now been altered in two separate units,
       in two different classes of departure, and NEITHER is visible from
       the other's entry alone — which is why 15's node-3 entry carries a
       supersession note pointing here.

       T02 IS NOW STALE ON THIS NODE IN TWO RESPECTS and that is on the
       client list, not something to reconcile in the build.

       ITS CSS RULE IS NOW DEAD AND HAS BEEN LEFT IN PLACE. See the note
       at the rule itself. Deleting it was expressly not done in this
       unit — the .acc-eco-* precedent: a rule that loses its last consumer
       is retired deliberately, in a unit that is looking at it, not
       incidentally by whoever removed the markup.

   18. A CALL TO ACTION IS DELETED. DIRECTOR-APPROVED (R1, 2026-08-13).
       This is a deletion of client-supplied copy and belongs in item 14's
       class, not 15's: it removes text rather than moving or re-marking it.

       WHAT WAS REMOVED. The anchor that closed the dark dot-field band —
       the band R1 moved onto this page from index.html, which sits above
       #fragmentation. Its text was "Why Longitude" followed by a space and
       U+2192. Its authored href, read with getAttribute rather than the
       resolved .href property, was "#pivot".

       IT WAS NOT BROKEN AND THAT IS THE POINT. "#pivot" addressed the
       section immediately below it, which moved to this page in the same
       unit, so the link would still have resolved here. It goes because
       its LABEL names the page it now sits on: an anchor reading "Why
       Longitude" on why-longitude.html points a reader at where they
       already are. The reason is the label, not the target — do not
       "restore" it by repointing.

       THE SECTION NOW CARRIES NO CALL TO ACTION. Logged consequence, not a
       defect. It vacated a measured 53.35px of vertical space (a 31.34px
       inline-block plus its 22px margin-top, identical at 1440x1024,
       1440x900 and 390x844). DO NOT close that gap, do not add a
       replacement, and do not promote the pivot band's CTA to cover it.

       PER §7.18, NOTE THAT THIS ENTRY NOW CONTAINS THE REMOVED STRING.
       Item 17 declined to reproduce its removed text for exactly this
       reason. The string was recorded here by explicit instruction, so a
       source grep for that label WILL match this comment and report one
       more than the document contains. Check the comments-stripped DOM.

   19. A CTA DESTINATION CHANGES, WITH ZERO CHARACTERS OF COPY TOUCHED.
       DIRECTOR-APPROVED (R1, 2026-08-13). Recorded here because the
       register is the record of departures from source, and a destination
       is part of what was specified even when the words are not.

       The pivot band's anchor was authored "#utilities" — again read with
       getAttribute — and now reads "utilities.html". Its text is unchanged
       and unquoted here: not one character moved.

       WHY IT COULD NOT STAY. "#utilities" is a same-page fragment naming a
       section of index.html. On this page no such id exists, so the link
       would have scrolled nowhere while still looking live — it would not
       have 404'd and nothing would have errored. Deleting it instead was
       rejected: it is the section's only wayfinding. utilities.html is the
       same content in full.

       TWO IDENTICAL STRINGS, TWO DESTINATIONS, BOTH CORRECT. index.html
       retains an anchor with exactly this text in its members band, still
       addressing "#utilities", and it is still right there because that id
       is still on that page. So the same label now resolves differently on
       the two pages, deliberately and page-appropriately. A later
       consistency sweep MUST NOT reconcile them.

   20. A CSS DECLARATION IS RETIRED. DIRECTOR-APPROVED (R1, 2026-08-13).
       Not a copy departure — recorded here because deviation 17 set the
       precedent that a rule losing its last consumer is retired
       DELIBERATELY, in a unit that is looking at it, rather than
       incidentally by whoever removes the markup. This unit was looking
       at it.

       WHAT WAS DELETED, VERBATIM: `.band-plum > .in{display:block}`.
       It sat under a long comment block earlier in this sheet.

       IT HAD ONE LIVE CONSUMER AND IT WAS THE WRONG ONE. Measured on the
       built page at 1440x1024, 1440x900, 1440x760 and 390x844: this page
       carries exactly TWO .band-plum elements — #fragmentation, and
       #problem, which R1 moved here from index.html. (#ecosystem is
       .wl-eco and only LOOKS like a third because it shares the ground
       colour; reporting grounds by colour instead of by class is what put
       a third on the list in the first place.) On #fragmentation the
       id-scoped rule now sitting beside the re-homed comment out-specifies
       it at ALL FOUR widths, so it decided nothing there. Its only live
       effect was on the arriving section, whose two-column dot field it
       silently flattened.

       THE FAILURE IT CAUSED, because it is the reason for the class of
       fix rather than the instance: forcing that container to a block box
       made bands.css's `flex:0 0 min(30vw,340px)` inert, .dots went full
       width, and .fwrap inflated from 340x302.88 to 1180x1030.88 — past
       reveal.js's 0.9 intersection threshold, which is what adds `built`.
       Twelve circles and five words stayed at opacity 0. Both sheets
       loaded, every tag was present, nothing errored, and the section
       rendered plausibly. Narrowing the selector to #fragmentation was
       rejected: it would have authored a rule overridden everywhere it
       applied, leaving the next imported section to meet the same wall.

       THE COMMENT HISTORY WAS RE-HOMED, NOT RETIRED WITH IT. It now sits
       with the id-scoped rule that governs that container, which is where
       a reader asking why that rule is id-scoped will be standing. Two of
       its sentences called this failure in advance and are preserved
       verbatim — the one recording that 9b turned §2 into a grid, and the
       one warning to verify by computed value on a real element because a
       selector split reads as obviously-winning far more often than it
       wins. The note about components/bands.css carrying the same shape at
       .band-slate .in, answered differently on the About page, is flagged
       post-launch, is not this page's to fix, and is untouched.

   21. THE HERO IS REBUILT FROM ANOTHER SECTION'S COPY, TWO SECTIONS ARE
       DELETED, AND ONE BAND CHANGES GROUND. CLIENT-REQUESTED,
       DIRECTOR-APPROVED (R4, 2026-08-13). The largest single departure on
       this page; every part of it is recorded here because no other file
       will hold it.

       THE HERO'S HEADING AND LEAD ARE REPLACED by the copy that arrived
       with #problem under R1 — the "Healthcare's biggest challenges are
       shared" heading and the $5 trillion / 400 systems / 6,000 hospitals
       paragraph. Both are carried BYTE-IDENTICAL; the strings were copied
       programmatically, never retyped. The T02 copy that stood in the hero
       is displaced, not edited. The eyebrow is UNTOUCHED and remains
       authored in TITLE CASE — base.css:76 renders the capitals, and
       anyone retyping from the screen would bake them in.

       THE <em class="g"> HOOK IS DROPPED, ON A MEASUREMENT. The heading
       arrived with .g, which paints --gold. MEASURED: --gold on this
       page's paper ground is 1.7030 — it fails even the 3.0 large-text
       threshold, where on the plum band it had measured 8.2161. With the
       hook removed the <em> takes this page's own `h1 em` rule, --accent,
       at 3.9310 against 3.0 for a clamp(36px,4.4vw,60px) heading that is
       LARGE at every width. No colour was authored: an attribute was
       removed and an existing rule took over.

       THIS IS A VISIBLE DESIGN CHANGE AND IS RECORDED AS ONE, NOT AS A
       TECHNICAL FIX. The client's GOLD emphasis on "Longitude is changing
       that." is now VIOLET. It is a consequence of the ground moving from
       plum to paper, not a restyle: 8.2161 where the sentence used to sit,
       1.7030 where it sits now, against a 3.0 floor. It is also what the
       hero's own emphasis span already did on this page before this unit,
       so the hero is internally consistent. REVERSIBLE IN ONE ATTRIBUTE —
       restoring class="g" restores the gold and the failure together.
       FLAGGED FOR RICK.

       THE DOT FIELD MOVES INTO THE HERO and is RECOLOURED, because its
       ground changed from plum to paper:
           .sd-c  --on-dark (--cream) 1.0694 -> --ink 13.9920  vs 3.0
           .sd-m  --mark  UNCHANGED at 3.9310 vs 3.0 graphical — measured
                  on the new ground, not assumed to carry over
           .fw    --on-dark 1.0694 -> --ink 13.9920
       THE FIVE WORD-SPANS ARE TEXT, NOT GRAPHICS, and their threshold
       MOVES WITH THE VIEWPORT: font-size is clamp(16px,2.1vw,28px), so
       they are LARGE (3.0) above ~889px wide and SMALL (4.5) below it.
       --mark clears 3.0 but FAILS 4.5, so it was not available. --ink is
       the only value that clears at every width. They are aria-hidden and
       transitional — fwIn then fwOut leaves them at opacity 0 — but they
       are visible text for about 2.7s and neither fact exempts them.

       THE FIFTH WORD LOSES ITS ACCENT, AND THAT IS A DESIGN ELEMENT
       REMOVED ON A CONTRAST FINDING, NOT A TIDY-UP. "care." carried
       `--dc:var(--mark)` inline so it settled violet while the other four
       settled cream. --mark is exactly the value that fails 4.5 at narrow
       widths. ROUTE TAKEN: the inline custom properties in the markup were
       NOT touched — the @keyframes fwColl rule now lands on var(--ink)
       directly instead of var(--dc). The client-authored markup is
       unaltered and the five inline --dc declarations are now INERT.
       Recorded because an inert inline property is a latent trap: anyone
       restoring var(--dc) to that keyframe silently restores the failure.

       #pivot TURNS PLUM, ID-SCOPED, and FLIPS to graphic-left via
       flex-direction:row-reverse on its .in — visual order only; source,
       reading and tab order stay copy-first. Foreground measurements are
       recorded at the rule itself. .blabel needed an explicit --white
       (14.8318) because it sets no colour and inherited --slate.

       #problem IS REMOVED. A and B took both its children and an empty
       section is not a placeholder. #fragmentation IS REMOVED. Its copy is
       recorded in checkpoint-9an's notes — cross-referenced, not
       re-recorded here. AFTER THIS UNIT THIS PAGE CARRIES NO .band-plum
       ELEMENT AT ALL.

       THE DUPLICATION OPEN ITEM RAISED AT 9an IS RESOLVED BY THIS UNIT.
       That entry recorded that this page argued fragmentation twice, from
       the same statistics, in two bands rendered alike. The duplicate is
       the section deleted here. Read 9an's open item with this entry.

       Both sections arrived under R1 (checkpoint-9an); the complete
       pre-rework tree is in _archive-checkpoint-9am-2026-08-13/.

   22. TWO HERO MEASURES ARE ADJUSTED. DIRECTOR-SUPPLIED, VERIFIED IN
       CONSOLE (R5, 2026-08-13). Not a copy departure and not a colour
       decision — recorded because both values are judgement calls that
       arrived as numbers, and a number with no provenance is re-derived by
       the next person who meets it.

           .wl-hero .in   max-width  1040px -> 1182px
           .wl-hero h1    max-width  18ch   -> 20ch

       BOTH ARE VALUE CHANGES TO RULES THAT ALREADY EXISTED. No selector,
       no new specificity relationship, no new sheet.

       1182 IS NOT "1180 PLUS TWO", AND THE DISTINCTION MATTERS BECAUSE THE
       2px READS AS A TYPO. base.css:28 sets a global `.in{max-width:1180px}`
       and this hero has overridden it to 1040 since it was built, so the
       change is +142px ON THIS ELEMENT and it CROSSES the global on the way
       rather than drifting off it. The director flagged the 2px delta as
       possibly incidental and ruled it shipped as measured; it was NOT
       rounded to 1180 on the build's judgement. `.wl-hero .in` is (0,2,0)
       against base's (0,1,0) — it wins on specificity, not load order.

       NEITHER RULE IS INSIDE A MEDIA QUERY, checked by brace tracking
       rather than by eye (§49). The hero's <=920 rule sets flex-direction,
       not max-width, so a wider container cannot silently defeat the stack.

       THE R4 GATE WAS RE-RUN IN FULL AND HELD. This unit widens the box the
       dot field lives in, and js/reveal.js needs .fwrap to reach a 0.9
       intersection ratio or every dot stays at opacity 0 with nothing in
       the console — the 9an failure. Measured after the change, six widths:
       built TRUE and ratio 1.0 at every one; .fwrap 340x302.88 at the three
       1440 widths, and correctly smaller where min(30vw,340px) binds
       (276.3 at 921, 260 at 920, 234 at 390). #pivot was untouched and its
       9aq figures are unchanged.

       LOGGED CONSEQUENCE OF 20ch, NOT SMOOTHED. The heading now carries the
       copy that arrived from #problem, which is long for an h1. At 1440 it
       measures 697.27 x 417.56 over SIX LINES at 60px; at 920, six lines at
       40.48px; at 390 it fills the 322px column over NINE LINES. The
       20ch cap is not what makes it tall — the sentence is — but 20ch is
       what fixes the line count at the top end. Reported to the director
       rather than adjusted.

   ── WL- PREFIX FROM HERE. Entries 1-22 above are unprefixed and are NOT
      renumbered; the record is never rewritten. R6 opens the page-local
      prefix convention on this file, as UTIL-1 did for utilities.css and
      HOME-1 for home.css. Numbering continues rather than restarting, so
      WL-23 follows 22 and no number is ever reused.

   WL-23. THREE SECTIONS ARE DELETED, BOTH HERO CTAs ARE DELETED, AND A
       SHARED QUOTE BAND ARRIVES. CLIENT-REQUESTED, DIRECTOR-APPROVED
       (R6, 2026-08-14). The largest deletion this page has taken. Every
       string below is recorded because this register is now the only place
       in the tree some of it exists; the pre-rework markup is also in
       _archive-checkpoint-9am-2026-08-13/.

       ─ #ecosystem, DELETED. Heading: "An ecosystem " + an <em class="g">
         reading "designed to grow more valuable over time."
         "Where this ends: a fully operating cooperative — owned by its
         members, governed by its CEOs — running across every major cost and
         clinical domain as permanent shared infrastructure for the systems
         that built it. Members shape what gets built and on what terms."
         "This is being built now. The systems that build it govern it."
         Gold labels "The platform spans:" and "Member returns:", over
         Pharmacy and therapeutics / Enterprise shared services /
         Specialty-as-a-service / Payor-provider solutions, and
         Revenue growth / Cost reduction / Expanded patient access /
         Industry transformation. Bolded close: "That value compounds as the
         network scales." CTA "Explore our Ecosystem" + U+2192 -> utilities.html.

       ─ #the-model, DELETED, INCLUDING THE COMPARISON TABLE — the largest
         single block of client content the page carried. Heading: "Not
         another vendor relationship. " + <em> "A different model entirely:".
         Deck: "Built differently, governed differently, designed to last."
         Body: "Longitude is owned, funded, and governed by health systems —
         not sold to them. Members shape what gets built, hold a stake in
         what it produces, and govern where it goes. Most models don't offer
         all three." (that apostrophe is U+0027, straight.)
         Caption "Model Comparison" — TITLE CASE as authored; the capitals
         seen on screen are a text-transform. Column headers, authored in
         caps: COLLABORATIVE TYPE / WHAT THEY DO / HEALTH SYSTEM ROLE.
         Seven rows, each type / what they do / health system role:
           Traditional venture funds | Invest in discrete point solutions
             with no health system input or ownership | Passive limited partner
           Strategic venture funds | Deploy capital using health systems as
             LPs to validate and commercialize portfolio companies | Active
             LP, early customer
           Venture studio consortiums | Build early-stage ventures with
             health systems as co-designers and first customers |
             Co-designer, design partner
           Group purchasing organizations | Pool member volume to negotiate
             vendor contracts and extract pricing discounts | Contract
             participant
           System consolidators | Acquire health system networks to build and
             scale portfolio companies | Acquisition target
           Benchmarking consortiums | Convene health systems for shared
             performance data, measurement, and market insight | Peer
             collaborator
           Longitude Health (in <strong>, row class wl-row-lh) | Builds
             interconnected utilities engineered for durability and systemic
             scale | Co-owner, governing member
         THE TABLE WRAPPER WAS A KEYBOARD-SCROLLABLE REGION —
         role="region", tabindex="0", aria-labelledby pointing at the
         caption. That affordance leaves with it.

       ─ #proof, DELETED. Heading "The network is growing."
         "Onvida Health was the first health system outside the founding five
         to choose Longitude — twice. They started with Longitude Rx for
         specialty pharmacy, then came back for clinical trials."
         "Two separate challenges, two separate decisions, one ecosystem."
         Quote: "We selected Longitude Rx because they are mission-aligned,
         health-system owned and innovative in their approach compared to
         others we assessed. They bring the infrastructure and expertise to
         design and build the right pharmacy model for our community, while
         supporting our patients with clinical and financial oversight at
         every step."
         Attribution, two spans: "Jake Childs, PharmD," / "Chief Operating
         Officer of Onvida Health." CTA "Join Us" + U+2192 -> #join.
         Its logo was the page's ONLY asset reference; referenced drops
         39 -> 38 and the built copy is removed. The source file is retained.

       ─ NON-ASCII ACROSS ALL THREE, recorded so a re-set is exact: em
         dashes U+2014 (two in #ecosystem's first paragraph, one in #proof's
         lede). Every apostrophe in the three is U+0027, straight. No curly
         apostrophes anywhere in the deleted copy.

       ─ BOTH HERO CTAs DELETED, verbatim with codepoints:
           "See the model" + U+0020 + U+2192   class="btn"       href="#the-model"
           "Explore utilities" + U+0020 + U+2192  class="cta-line"  href="utilities.html"
         Both arrows are LITERAL U+2192, not entities; both carry one
         U+0020 before the arrow. Labels are otherwise pure ASCII, 15 and 19
         characters. THE .wl-cta WRAPPER WENT WITH THEM — an empty flex
         container left behind would have kept its own box and invalidated
         the measured deltas below.
         The first was the page's PRIMARY call to action and the only
         in-page anchor on the site other than #join. A DOM sweep of all 18
         pages plus header and footer, and a second sweep of src/js/ and
         data- attributes, found exactly ONE link to any of the three
         deleted ids — that one. Nothing else dangles.

       ─ THE COMMENT BLOCK ABOVE THE CTAs WAS DELETED OUTRIGHT, not
         rewritten. It documented the .btn/.cta-line split and asserted
         "#the-model RESOLVES ... Neither dangles". Both statements became
         false in this unit and nothing remained for it to describe.

       ─ MEASURED CONSEQUENCE OF THE CTA REMOVAL, not restyled around:
         the hero shortens by 81.92px at 921 and above, and by 131.26px at
         390 — the row wraps to two lines there, so mobile tightens nearly
         twice as much as desktop. THE HEADING AND THE DOT FIELD DO NOT MOVE
         OR RESIZE AT ANY WIDTH: h1 holds 697.27 x 417.56 at 1440 over six
         lines and 322 x 375.75 at 390 over nine, and .fwrap holds
         340 x 302.88 at 1440 — so the 9an reveal mechanism is untouched.

       ─ MEASURED CONSEQUENCE OF THE SECTION REMOVALS, logged not restyled:
         the page goes from SEVEN sections to FOUR, and loses three of its
         four grounds below the fold. The gold band is gone — it was the only
         gold ground on the site. Remaining sequence, still strictly
         alternating with no same-on-same seam: hero paper, #pivot plum,
         #origin paper, quote band slate, join paper.

       ─ 61 RULES IN THIS SHEET ARE NOW DARK and are RETAINED BY RULING, not
         overlooked: the whole .wl-eco-*, .wl-proof-* and .wl-table*
         families, plus .wl-deck, .wl-model .in, .wl-cta, .wl-cta .cta-line
         and .wl-btn-edge. That is 36% of the sheet. R7 is a consolidated
         dead-code unit and will decide them together; do not retire them
         piecemeal. buttons.css loses nothing — two .btn survive on the page.

       ─ THE QUOTE BAND ARRIVES via partials/components/quote-block.html,
         the SAME partial index.html includes, not a copy. It carries no id,
         so a second consumer introduces no duplicate id anywhere. ITS
         TREATMENT IS NOT IN THIS SHEET: the five .band-slate.quote-feature
         rules moved from pages/home.css into components/quote-block.css in
         this unit, keyed to the selector rather than to any page, so the
         band cannot render differently depending on where it lands.
         Verified: 54 computed values identical between the two pages at
         1440, 760 and 390, and identical to index.html's pre-move baseline.

   WL-24. A TERMINAL PERIOD IS ABSENT FROM NEW CLIENT COPY AND SHIPS THAT WAY.
       CLIENT-SUPPLIED, DIRECTOR-APPROVED (B1, 2026-08-17). Four strings in
       `#origin`'s band 2 were replaced — the `.wl-o2-lede` and all three
       `.wl-o2-list` items. This entry covers the punctuation of ONE of them.

       DIRECTION: PERIOD PRESENT -> ABSENT. The outgoing third bullet ended
       U+002E; the incoming one ends U+0074, "t". Transcribed as authored. The
       period was NOT restored and must not be.

         out: "Participation in a model built to generate durable value over
              time — strategic and economic."
         in:  "A model that generates durable value over time — strategic and
              economic — that flows back to the systems that built it"

       THE GOVERNING PRECEDENT IS index.html:167 AND IT RUNS THE SAME WAY.
       There, five client-supplied strings arrived with their terminal periods
       dropped where every previous string had one; the ruling was that it is
       "systematic rather than a typo, but possibly an artifact of the client
       typing a bulleted list, so it ships as authored and goes to the client
       for confirmation. DO NOT 'RESTORE' THEM." Identical shape here: one item
       in a list of three, the other two never carried a period, and the
       client's own text is the authority. SAME-DIRECTION PRECEDENT.

       **DO NOT CONFUSE THIS WITH UTIL-3, WHICH RUNS THE OPPOSITE WAY.** That
       entry landed in the SAME UNIT and records the BUILD removing periods the
       CLIENT AUTHORED, on four `.acc-chip` strings in utilities.css. Here the
       client supplied no period and the build added none. **One entry is the
       build declining to add; the other is the build choosing to remove.** A
       reader meeting both must not collapse them into "B1 dropped some
       periods".

       THE OTHER TWO BULLETS AND THE LEDE ARE NOT PUNCTUATION DEVIATIONS.
       Neither replacement bullet had a terminal period going in or coming out,
       and the lede still ends U+003A as it did before. Recorded so this entry
       is not read as covering all four strings.

       THE LEDE'S `<em>` WAS PRESERVED BY RULING, AND THAT IS A COLOUR
       DECISION RATHER THAN A COPY ONE. The incoming lede arrived as PLAIN
       TEXT. `.wl-o2-lede em` is `{font-style:normal;color:var(--accent)}` —
       the element is a PAINT DEVICE, not emphasis — so transcribing the string
       literally would have silently deleted an `--accent` treatment measuring
       **3.6759 on --cream at 34px/700, LARGE, PASS**. Preservation cost
       nothing in fidelity: the em-wrapped clause, "three things the outside
       market has never reliably delivered:", is BYTE-IDENTICAL between the
       outgoing and incoming strings, so only "that translates into" -> "that
       means" actually changed. **A copy replacement that arrives without
       markup is not an instruction to remove markup — establish what the
       markup DOES before dropping it.**

       NUMBERED WL-24, NOT 20. The dispatch proposed "deviation 20"; **20 was
       already taken** — "A CSS DECLARATION IS RETIRED (R1, 2026-08-13)" — and
       this log runs 1-22 unprefixed then WL-23. The convention above is
       explicit that numbering continues and no number is ever reused. Same
       collision class as ABT-3 at S3, and it was caught by enumerating the log
       rather than by trusting the markup's reference to "deviation 19".

   WL-25. THE NODE LABELS' MEASURE WIDENS AND A NARROW BAND TAKES A SMALLER
       TYPE SIZE. CLIENT-REQUESTED (BugHerd #5), DIRECTOR-RULED (B3,
       2026-08-17). The brief was to eliminate the three-line widow under the
       #origin connector for as long as possible across widths, accepting that
       some widths may force it.

       **THIS IS NOT A GLOBAL REVERSAL OF 9d's 16 -> 26px. THE BASE STAYS
       26px.** 26px holds at 15 of the 16 widths measured, and the reduction is
       scoped to a single band. Read the two changes as one mechanism:

         base    .wl-node{max-width: 250px -> 290px}   font-size UNCHANGED 26px
         banded  @media(min-width:768px) and (max-width:939.98px)
                 .wl-node{font-size:clamp(20px, 3.49vw - 6.8px, 26px)}

       THE CAP FIXES EVERY WIDTH WHERE IT BINDS, AND ONLY THOSE. At 250px the
       labels ran 3/3/2; at 290px they run 2/2/2 wherever the track is wide
       enough for the cap to govern — 940px up. Below 940 the three-column
       track is NARROWER than 290px, so the cap never binds and font-size is
       the only lever left. Measured node box 250 x 99.797 -> 290 x 66.531:
       exactly one 33.28px line box leaves each label.

       THE BAND IS 768-939.98 AND ITS BOUNDS ARE MEASURED, NOT CHOSEN. Below
       768 the layout is already single-column via the max-width:767px block
       further down, which sets max-width:none and where 26px already gives
       2/2/2. From 940 up the cap governs again. Between them the required size
       RISES WITH WIDTH, which is why a flat value is wrong:

         768 -> 20px    800 -> 21px    830 -> 22px    860 -> 23px    880 -> 24px

       A FLAT 20px ACROSS THE BAND OVERSHOOTS ITS OWN TOP — measured 2/2/1 at
       939, node 3 collapsing to one line. The clamp tracks the requirement
       instead: 20px at 768 rising to 26px at 940, where it meets the base and
       stops. **A ONE-LINE LABEL IS NOT AN IMPROVEMENT OVER A THREE-LINE ONE.**
       The block above this rule states the wrap IS the design — at full track
       width these set on one line and the column reads as a caption — so the
       target is TWO lines, not fewer.

       THE CLAMP IS THIS PROJECT'S EXISTING PATTERN, NOT A NEW MECHANISM.
       `.vm-band .vm-label` on our-approach.html is
       clamp(21px, 1.4vw + 8px, 28px) for the same reason: a floor that
       guarantees something at every width, a ceiling that holds the designed
       size, and a slope between them.

       ⚠ SOURCE ORDER IS LOAD-BEARING (§49). A MEDIA QUERY ADDS NO
       SPECIFICITY. The base rule and the banded rule are both (0,1,0), so the
       banded one wins ONLY because it comes later in the file. **Move it above
       the base rule and it silently never applies** — nothing errors, nothing
       looks broken at 1440, and the widow simply returns at 768.

       NO CONTRAST EXPOSURE, AND THIS IS THE PART THAT COULD HAVE BEEN GUESSED
       WRONG. `--on-page` on the page ground measures **13.9920 at every size
       tested — 26, 22, 20 and 18px — clearing LARGE 3.0 AND SMALL 4.5 both.**
       The block above already says the ratio does not change with size; the
       reclassification at 18.66/700 is real and nothing here depends on it.
       **The reduction is a TYPOGRAPHIC decision, not an accessibility one**, and
       a future edit must not reason as though the size were protecting a ratio.

       FLAGGED FOR RICK. A type size the design lead raised 16 -> 26px at 9d is
       now smaller than 26 between 768 and 939.98. It is scoped, it is the
       minimum that clears the widow at each width in that band, and it is
       reversible in one declaration — but it is a visible departure from a
       design-lead decision and the client should see it.

       320px STAYS A WIDOW, RULED OPEN, NOT A DEFECT AND NOT AN OMISSION.
       Measured 3/3/2 at 320 **today, at the shipped 250px/26px** — it is
       PRE-EXISTING and this unit neither causes nor cures it. Below 768 the
       cap is `none`, so the track governs and only font-size could reach it:
       23px is the largest size giving 2/2/2 at 320. **A flat mobile reduction
       is destructive — measured at 22px, 360 and 390 fall to 2/2/1 and 500 and
       767 to 1/1/1.** Reaching 320 needs its own narrow query, which the
       director declined: 320 is the width where the type would have to shrink
       furthest for the least reach. **Do not "finish the set" by adding a
       mobile band without re-measuring 360 through 767.**

   WL-26. THE #origin WORD SEQUENCE LOOPS INSTEAD OF SETTLING. CLIENT-REQUESTED
       (BugHerd #4), DIRECTOR-RULED (B3, 2026-08-17). The five-word firework in
       the hero dot field ran once and held its end state; it now hard-resets to
       the beginning and replays.

       THE MECHANISM IS NOT IN THIS SHEET. It is a JS re-trigger in
       js/reveal.js — `.built` is removed, a reflow is forced, and `.built` is
       re-added on a LOOP_MS interval. **Nothing in this file changed for it:**
       the four animations, their four durations, and the per-word --t-in and
       --t-out delays set inline in the markup are all untouched.

       WHY NOT `infinite`, AND WHY NOT MERGED KEYFRAMES. Adding `infinite` to
       the four declarations desynchronises them — four durations (500/160/300/
       160ms) against two delay origins, each restarting on its own period.
       Merging them into one percentage-keyframed animation would need the
       per-word interval between entry and exit encoded as percentages, and
       **that interval VARIES PER WORD: 2100 / 1980 / 1860 / 1740 / 1620 ms**,
       because --t-in steps 260ms while --t-out steps 140ms. One shared keyframe
       set cannot express five different internal gaps without flattening the
       choreography. **The class re-trigger is the only mechanism that preserves
       the approved motion exactly.**

       THE SEQUENCE ENDS AT 2960ms, measured on real elements via the Web
       Animations API rather than summed from the file. LOOP_MS is 3400, so the
       emptied end state is held ~440ms before the replay. **That pause is a
       ruled taste value, not a derived one.**

       NO FILL-MODE CHANGE WAS NEEDED. Removing `.built` drops the animations
       entirely and the base `.dots .fw{opacity:0}` reasserts — that IS the hard
       reset. **The end state of this sequence is opacity 0**: the words fly out
       and collapse, so the loop reads appear -> scatter -> vanish -> reappear.
       Anyone changing fwOut or fwColl should know the loop depends on that
       final invisibility looking deliberate.

       THE REDUCED-MOTION GUARD IS UNCHANGED AND ALREADY SUFFICIENT. The
       prefers-reduced-motion block further down sets `.dots .fwrap{display:none}`
       and `.dots .fw{animation:none}`; measured with the preference set, ZERO
       animations run. reveal.js additionally refuses to create the interval at
       all. **Nothing is lost to assistive technology either way — `.dots`
       carries aria-hidden="true" and the words are decorative.**

       THIS IS THE FOURTH EXCEPTION TO A CONCEPT-LEVEL REGISTER, and the
       register is in js/reveal.js, not here. Read it there before relaxing
       anything else: the lift is scoped to this dot field and licenses nothing
       on any other section.

   WL-27. THE LOOP GETS A CHOREOGRAPHY, AND THE SHIPPED DEFECT WAS NOT THE
       ONE IT LOOKED LIKE. CLIENT-REQUESTED, DIRECTOR-RULED (B5, 2026-08-17),
       after seeing WL-26's loop live on dev.

       **THE DOTS NEVER RESET. THAT WAS THE DEFECT, NOT THE HOLD LENGTH.**
       WL-26's mechanism is `remove .built` -> `void offsetWidth` -> `add
       .built`, and that completes INSIDE ONE FRAME. The words are driven by
       ANIMATIONS, which restart from zero on a class re-add, so they replayed
       correctly. The dots are driven by a TRANSITION on `.sd`, and a transition
       needs two rendered states to run — the forced reflow that makes the words
       restart is exactly what denies the dots the intermediate frame they would
       need to travel back to `opacity:0`.

       MEASURED BEFORE THE FIX, polling computed opacity across the SECOND reset
       where the field was long settled: **no dot fell below 0.99 at any
       sample.** The dots came up once during cycle 1 and stayed up forever.
       **Cycle 1 looked designed. Every cycle after it was five words flashing
       on and off over a static dot field** — which is what the director saw and
       is not what WL-26 was aimed at. **A mechanism that works for one element
       type and silently no-ops for another, inside the same class flip, is the
       shape to watch for here.**

       ── WHAT SHIPPED IN B5

         0.00 - 1.54   words fade in, staggered           UNCHANGED
         1.54 - ~2.5   words held visible                 EXTENDED via --t-out
         ~2.5 - 3.3    words scatter                      UNCHANGED
         ~2.6 - 3.4    dots arrive, staggered             UNCHANGED
         3.4  - 8.4    DOTS FLOAT ALONE, words absent     NEW
         8.4  - ~9.6   dots fade out randomised / words fade in   NEW

       ── THE RE-ENTRY NEEDED NO NEW KEYFRAMES, AND THAT IS THE LARGEST
       SIMPLIFICATION IN THE UNIT.

       `fwIn` already staggers on every re-trigger: `--t-in` is inline per span
       and re-applies each time `.built` returns. Measured on the shipped
       mechanism before any change — [0.21,0,0,0,0] at +80ms rising to
       [1,0.91,0.36,0,0] at +640ms. **It reads as a snap on the live page only
       because the dots do not leave.** Fix the dots and the existing cascade IS
       the staggered re-entry. **No re-entry animation was authored. Do not add
       one.**

       ── OPACITY ONLY, AND THE REASON IS OWNERSHIP.

       `.dots.leaving .sd` sets `opacity` and `transition-delay` and NOTHING
       ELSE. Once `.built` is on, `sorbit` runs infinite and drives the
       `transform` SHORTHAND; an animation beats a transition on the same
       property, so any transform in the fade-out would be silently overridden
       by the drift. **`sorbit` never touches opacity — all five of its stops
       are `translate()` — so opacity is free and the two do not contend.**

       ── THE `--fd` HAZARD, WHICH IS THE ONE REAL RISK IN THIS DESIGN.

       The departure order is randomised per cycle by JS, and **JS WRITES ONLY
       THE CUSTOM PROPERTY `--fd`.** It must never write `style.opacity` or an
       inline `transition-delay`. **An inline style outranks a media query**, so
       either would re-enable motion for a reader who has asked for none — the
       `prefers-reduced-motion` block below forces `.sd` to `opacity:1` with
       `transition:none`, and that suppression holds ONLY while the value
       arrives through the cascade. A custom property consumed by a rule stays
       inside the cascade; an inline declaration steps outside it.

       ── THE WORD HOLD LIVES IN THE MARKUP, NOT IN THIS SHEET.

       The visible hold was never 0.56s. Derived from the inline values it was
       **1.60 / 1.48 / 1.36 / 1.24 / 1.12 s** per word — the gap between a word
       reaching full opacity at `--t-in + 0.5` and starting to leave at
       `--t-out`. Reaching ~2s meant raising the five inline `--t-out` values in
       src/pages/why-longitude.html. **Those are style attributes on the spans,
       so the hold is a MARKUP number, and a future edit that changes it must
       open the markup rather than this sheet.**

       ── WHY THE INTERVAL WENT, AND THE THIRD REASON IS THE LOAD-BEARING ONE.

       A ~9.6s cycle triples a 3.4s cycle's drift exposure, and `setInterval`
       does not fire in a backgrounded tab then fires immediately on return.
       **But the reason that decides it: `.dots.paused` sets
       `animation-play-state:paused` from an IntersectionObserver that
       DELIBERATELY DOES NOT UNOBSERVE, and it does nothing whatsoever to a
       timer.** Under the interval the loop could reset a field the reader
       cannot see, so they returned to it mid-cycle. The chain is gated on that
       same paused state and will not advance while the field is off-screen.

       ── THIS IS A FIFTH EXCEPTION, NOT AN AMENDMENT TO THE FOURTH.

       The fourth licensed LOOPING THE SEQUENCE THAT ALREADY EXISTED. This adds
       motion the site has never carried — a dot fade-out, the dots having only
       ever faded in — and moves the cycle off a fixed interval. Reading it as
       an amendment would say the fourth licensed "this band loops, in whatever
       form"; it did not, and the register's own closing line refuses that
       generalisation. **The register is in js/reveal.js. Read it there before
       relaxing anything else.**

   A NOTE ON SUB-BAND NOMENCLATURE, because it has already caused one
   wrong assertion. "BAND 1 / 2 / 3" in units 9c-9e means the three
   SUB-BANDS INSIDE `section#origin` — .wl-o1, .wl-o2, .wl-o3. It does
   NOT mean page-level sections. This page has SEVEN page-level sections,
   counted on the DOM: wl-hero (no id), #fragmentation, #origin,
   #ecosystem, #the-model, #proof, #join. Under that numbering "band 2"
   resolves to #fragmentation, which is plum and has never been in the
   scope of any band-numbered unit. Count sections on the DOM; read
   "band N" as an #origin sub-band.

   A NOTE ON CHECKING THIS LOG. Items 1 and 4 quote strings that also ship
   as page copy. They are in a DIFFERENT FILE from the markup, so a
   per-file count over why-longitude.html is unaffected — but a
   repository-wide grep for either string will match this comment as well
   as the rendered text and report one more than the page contains. Count
   on the DOM, which carries no comments.

   ===================================================================== 
   WL-28. THE #pivot CTA IS RE-GROUNDED TO GOLD. CONSEQUENCE OF THE --accent
   TOKEN MOVE. C2, 2026-08-17.

   `#pivot > .in > .copy > .cta-line` takes `--gold` instead of the inherited
   `--accent`. **Colour only — one added declaration, no copy, no geometry.**
   The selector matches the colour-override cluster it sits in (`… > h2`,
   `… > .body`, `.blabel`), which is the shape this band already uses to restate
   colour on the dark ground.

     before   --accent #2B61C9 on --plum   2.5821   19px/700 LARGE, thr 3.0  FAIL
     after    --gold   #F0B83F on --plum   8.2161   19px/700 LARGE, thr 3.0  PASS

   ── A CONSEQUENCE OF C1, NOT A NEW DECISION.

   C1 moved `--accent` #696FE8 -> #2B61C9 at client request; on `--plum` this
   link fell 3.5594 -> **2.5821, below its threshold.** **TOK-1 in tokens.css
   carries the 55-instance census — that entry and this one are ONE decision
   recorded in two places.** C1 shipped the failure knowingly rather than widen
   its manifest; C2 closes it. The homepage's twin is **HOME-6** in `home.css`,
   written in the same unit against the same figures.

   ── `--gold` IS ALREADY THIS PALETTE'S DARK-GROUND ACCENT.

   `h2.tlw-h2` on our-approach measures **8.2161 on plum — the identical
   figure**, being the identical pair of colours. Rejected alternatives, measured
   on plum: `--ink-on-dark` 8.6943 and `--cream` 13.0839 both clear easily **but
   are the dark-ground BODY colours, so a CTA wearing them stops reading as a
   link**; `--slate` 3.0421 clears by 0.0421, which is no margin; `--pill-hover`
   2.8600 fails. Legibility was not the only criterion.

   ── ⚠ THIS DOES NOT GRANT R4.

   **R4 is the client asking for gold on this page's `h1 em`, which sits on
   `--paper`, where gold measures 1.7030 and fails even 3.0. That request stands
   REFUSED.** This is gold on `--plum` at 8.2161 — **same colour, same page,
   different ground, opposite verdict**, a 4.8x spread. **R4 and WL-28 are on
   the same sheet and will be read together, which is exactly the confusion this
   paragraph exists to prevent.** The ground is the variable, not the colour.

   **AND THERE IS ALREADY A GOLD `em` ON THIS PAGE, WHICH IS NOT R4 EITHER.**
   `#pivot`'s own h2 — "We bring health systems together" — carries `em.g` at
   46px/700 and renders gold on plum at **8.2161, the identical figure**, via
   `base.css`'s pre-existing `h2 em.g` hook (see the note at the `.wl-*` heading
   rules). **It is an h2 em on a DARK ground. R4 is an h1 em on `--paper`.**
   A reader who finds gold emphasis rendering on why-longitude and concludes R4
   was granted has matched the element type and missed the ground.

   **This also makes the re-grounding local rather than borrowed: the CTA now
   matches the gold of the heading directly above it in the same band**, at the
   same measured ratio. The cross-page reference to `h2.tlw-h2` is corroboration,
   not the source of the choice.

   ── SCOPING, BECAUSE `.cta-line` IS A SHARED CLASS.

   Nine `a.cta-line` render site-wide; **seven sit on light grounds passing at
   5.0671 or 5.4187 and must not move.** The base colour is declared once, at
   `components/buttons.css:78` — **no page sheet declared it, so this is an
   ADDED scoped rule, not a swap.** Scoped to `#pivot`, which holds exactly one
   `.cta-line`. §46.

   Cascade enumerated, not assumed (§65): the only matching `color` rules are
   `a{color:inherit}` and `.cta-line{color:var(--accent)}`, and **no `:hover`,
   `:focus` or `:visited` rule exists for `.cta-line` in any sheet**, so there is
   no second state to carry. (1,1,0) against (0,1,0).

   
   WL-29. FOUR TICKETS IN ONE UNIT: A LEAD IS DELETED, A HEADING IS
   RE-CASED, THE THREE ROWS ARE NUMBERED, AND A WHOLE BAND GOES.
   CLIENT-REQUESTED (BugHerd #16, #17, #18, #19/#23), N2, 2026-08-18.

   ── #16 · THE $5tn LEAD IS DELETED.

   `.wl-hero`'s `<p class="lead">` removed entire, −338 B. Siblings were
   `<span class="kick">`, `<h1>`, then this; **the h1 is not orphaned and the
   container is not emptied.** No ground seam — `.wl-hero` sits on `--paper`
   and the sequence either side is untouched. Deviation against
   `longitude-v14-copy-spec-2026-08-03.md`, logged.

   ── #17 · A CASING CHANGE AGAINST HARVESTED T02 COPY.

   "For member systems," -> "For Health Systems," — sentence case to title
   case, **+0 B, the strings are the same length.** The `<em>` clause after
   it is untouched. Deviation against
   `longitude-t02-why-longitude-2026-08-07.md`, logged. Note the sheet
   already records this page's kick as "title case as authored and
   internally inconsistent"; this is a second title-case string, requested
   rather than inherited.

   ── #18 · ⚠ THE RING IS LOAD-BEARING. A BARE GOLD DISC FAILS 1.4.11.

     gold on --ground-alt        1.5925   thr 3.0   FAILS by 1.4075
     --ink ring vs the ground   13.0839   thr 3.0   PASS
     --ink ring vs the gold fill 8.2161   thr 3.0   PASS
     --ink numeral on gold       8.2161   28px/700 LARGE, thr 3.0  PASS

   **`--ground-alt` IS `--cream` (#F6F0E6), and gold on cream is the same
   1.5925 G4 measured for the our-approach divider — the R4 shape exactly.**
   The `.beacon-badge` pattern this echoes works only because it sits on
   `--plum` at 8.2161; moving the idea to a light ground inverts the result.
   **The ring is not decoration: remove it and the disc fails.** Same remedy
   9x applied to the violet button on gold. `box-shadow` inset rather than
   `border` so there is no layout effect at any box-sizing.

   **56px disc / 28px numeral = 50% fill.** The starting 28-in-50 measured
   56% against `.beacon-badge`'s 46%, with ~11px clearance either side of a
   digit. 28px is an on-scale step — it is `.vm-label`'s size on
   our-approach, and this page already uses 28px five times.

   ── #18 · ::marker WAS TESTED AND REFUTED, SO A CHILD ELEMENT WAS REQUIRED.

   Tested in Chrome rather than assumed: `::marker` **applied** content,
   font-size, font-weight and color, and **rejected** background, width,
   height and `display:flex` — it reported 15.58px wide, `inline-block`, and
   a transparent background against a gold request. **It cannot draw a 56px
   flex disc.** So each `<li>` takes a `<span class="wl-num">` as its FIRST
   CHILD. **It does NOT collide with `li + li::before`** — that pseudo-element
   belongs to the `<li>`, and a child span occupies neither of its slots.

   ── #18 · THE NUMERALS ARE EXPOSED, NOT aria-hidden, AND THAT IS THE POINT.

   **The `.beacon-badge` exemption does not transfer.** Those letters
   duplicate the first letter of the adjacent title, so the meaning is
   genuinely carried by neighbouring text and C1 exempted them as decorative.
   **A numeral duplicates nothing.** Hidden, a screen reader gets an
   unnumbered list where a numbered one was requested. `list-style` stays
   `none` — the span carries the numeral, so restoring a native marker would
   announce it twice.

   ── #18 · HUNG, NOT INDENTED, AND THE HAIRLINE CLEARANCE WAS RE-DERIVED.

   `left:-80px` — a 56px disc with its right edge 24px clear of the text,
   inside ~191px of free gutter. **The measure stays 554px.** Indenting would
   have dropped it to ~482px, about 13%, adding lines to the longer items.

   **The clearance is set by the disc's TOP, not its height.** Content begins
   26px below the hairline on items 2 and 3, and the hairline occupies
   y=0..1, so the gap is **25.0px for a 50px disc and 25.0px for a 56px one**
   — a taller disc grows downward into the item, not upward toward the rule.
   li[1] and li[2] have 109.17px of content height, so a 56px disc leaves
   53.17px spare. **No collision, and no hairline inset was needed.**
   `li:first-child` takes `top:0` because it carries `padding-top:0`,
   mirroring the rule directly above it.

   ── #19/#23 · THE BAND AND ITS CTA GO TOGETHER, BY RULING.

   `.wl-o3` removed entire with its comment, −582 B, including
   `<div class="wl-o3-cta"><a class="btn" href="#join">Join Us →</a></div>`.
   **Director ruling: the Join Us button is sticky in the nav and this
   instance was only a jump link to the form section immediately below, so
   no conversion point is lost.** Removing a CTA is a conversion change, and
   it is recorded as a ruling rather than a consequence.

   **#19 AND #23 WERE DUPLICATE TICKETS ON ONE INSTANCE.** The sentence
   occurs once in code. Two tickets did not mean two occurrences.

   ── ⚠ AND A CLAIM THIS BUILD HAS BEEN CARRYING IS WRONG.

   The N0 recon said the page's other Join Us was in §6. **It is not.** §6's
   own header claims it carries "the second of T02's two Join Us CTAs", and
   **§6 contains no `.btn` at all.** The three `href="#join"` on the built
   page came from the header partial, the join band partial, and the
   `.wl-o3` CTA now removed — so **`.wl-o3` held the page's ONLY in-body Join
   Us CTA.** The include comment that said "both of T02's in-body Join Us
   CTAs" has been corrected in the markup. The ruling stands unchanged — the
   sticky nav and the form band immediately below are the paths — but the
   premise it was offered against was looser than reported. **The comment
   that found this told us to: "COUNT THEM ON THE DOM rather than trusting a
   number written here."**

   
   WL-30. THE #pivot BEACON LOOPS. EXCEPTION SIX, A CONCEPT-LEVEL DIRECTOR
   DECISION, L1, 2026-08-18.

   `.badge`, its `.bring` ring and its twelve `.bd` dots now reset and replay on
   the #origin cadence. **Scoped to section#pivot on why-longitude.html. It
   licenses nothing elsewhere** — not our-team.html, which links badge.css and
   renders no `.badge`.

   ── ⚠ THIS REVERSES A DECISION reveal.js RECORDED IN WRITING.

   `reveal.js` carried, in the words observer: *"`.badge` KEEPS ITS FIRE-ONCE
   BEHAVIOUR and is deliberately not looped."* **Superseded in the same edit
   that contradicted it, 2026-08-18.** Left standing it would have told the next
   editor to undo this unit. **The surrounding sentence about `.dots` was
   correct and stays — the half was superseded, not the entry** (§75).

   ── THE PHASES, AND WHY THE CHAIN WAITS ON THE RING.

     build-in   .bd 0.24s on a 0.055s stagger -> 0.845s
                .bring 1s after a 0.9s delay  -> ~1.9s   <- the LAST to finish
     hold       DOT_HOLD_MS, the ruled five seconds
     departure  twelve dots at 0.055s apart over a 0.45s fade
                11 x 0.055 + 0.45 = 1.055s, order REVERSED so the ring unwinds
     reset      remove built, remove leaving, forced reflow, add built

   **Chaining on the dots would have started the hold a second early**, so the
   chain waits on the ring's `stroke-dashoffset` transitionend — the same shape
   as the #origin cycle waiting on `fwTrav` on the LAST word.

   **DOT_HOLD_MS IS READ FROM THE #origin CONSTANT, NOT COPIED.** The ruled
   five-second hold is one decision and must not become two numbers. The literal
   5000 appears exactly once in reveal.js.

   **THE FORCED REFLOW IS MANDATORY.** `remove('built'); remove('leaving');
   void offsetWidth; add('built')` — cycleDots records that removing only
   `.built` leaves no intermediate state for the transition to run back through,
   because the reflow completes inside one frame, and the dots stay up forever.

   ── cycleDots WAS MEASURED NON-REUSABLE, NOT ASSUMED TO BE.

   It queries `.fw` words, waits on `fwTrav`, shuffles `.sd` delays through
   `--fd` and reads `.paused`. **The badge has no `.fw`, no `.sd` and no
   `fwTrav`** — badge.css carries **zero @keyframes** and is transitions only.
   `cycleBadge()` is its own chain over the same phase shape.

   ── ⚠ SPECIFICITY, TWICE, AND THE SECOND ONE IS THE SUBTLE ONE.

   `.badge.built .bd:nth-of-type(n)` is (0,3,1). A departure rule written as
   `.badge.leaving .bd` is (0,2,1) and **loses** — the dots would keep their
   build-in delays and never leave. **That is the B5 defect exactly (§65).** The
   departure rules carry `:nth-of-type` to tie at (0,3,1) and sit BELOW the
   built rules so source order decides.

   **AND THE REDUCED-MOTION BLOCK HAD TO BE RAISED TO MATCH.** It sets
   `.badge .bd` at (0,2,0) inside a media query, and **A MEDIA QUERY ADDS NO
   SPECIFICITY (§49)** — the new (0,3,1) departure rules would have beaten it
   and a reader who asked for no motion would have watched the dots fade out.
   The block now carries `.badge.leaving .bd:nth-of-type(n)` too. **The loop is
   gated so `.leaving` is never added under reduced motion, but that block must
   not depend on the gate to be correct.**

   ── WCAG 2.2.2 PAUSE STOP HIDE — THREE DECLARATIONS, TOGETHER, HONESTLY.

     utilities.html <video autoplay loop>   declared, director-accepted
     #origin dot field loop, 8.85s period   UNDECLARED until now. Introduced by
                                            B3/B5; declared and accepted at L1.
     #pivot beacon loop, ~8.0s period       declared and accepted at L1

   **All three fail 2.2.2 at Level A**: motion that starts automatically, runs
   past five seconds, and sits in parallel with other content, with no pause,
   stop or hide mechanism. Zero such controls exist on the page.

   **WHAT THE MITIGATIONS ARE, AND WHAT THEY ARE NOT:**

   - **The prefers-reduced-motion gate is the substantive defence.** The loop is
     never created and the badge arrives complete and unanimated.
   - **aria-hidden DOES NOT SATISFY 2.2.2.** The `<svg class="bdots">` and every
     `.bd` inside it are `aria-hidden="true"`, which removes the motion from the
     accessibility tree **and not from the screen**. A sighted reader with
     vestibular sensitivity sees it regardless. The `.blabel` copy outside the
     svg is NOT hidden and does not animate.
   - **`.paused` is an off-screen optimisation, not a user affordance.** It
     stops motion the reader cannot see; it gives them no control over motion
     they can.

   **NO PAUSE CONTROL WAS ADDED. That is a separate decision affecting the
   pages that carry these loops and it has not been taken.**

   ── BLAST RADIUS, RE-DERIVED AND SMALLER THAN REPORTED AT HALF A.

     badge.css <link>   1 page   why-longitude.html
     reveal.js <script> 6 pages  index, our-approach, our-origins, our-team,
                                 utilities, why-longitude
     .badge element     1 page   why-longitude.html

   **Half A said reveal.js loads on 19 pages. It does not — that figure was
   carried from form.js.** A raw grep says 20 because comments name the file
   (§25); the `<script src=…>` count is 6. **our-team.html links badge.css and
   renders no badge**, so the sheet's second consumer has nothing to break.

   ── ⚠ L1-FIX (2026-08-18): THE RESET WAS CORRECT; THE DEPARTURE HAD ZERO
      MARGIN. A LIVE 50%-REBUILD DEFECT, CAUGHT IN REAL-BROWSER REVIEW.

   The loop as first shipped rebuilt each cycle from a partially-built (~50%)
   state on a real browser. **The reset sequence was NOT the cause** — it is
   byte-identical to cycleDots and its forced reflow is correct. The cause was a
   ZERO-MARGIN RACE: the departure `span` = (12-1)x55 + 450 = **1055 ms equalled
   the last dot's exact fade-completion** (delay 605 + duration 450 = 1055), so
   `setTimeout(reset, span)` fired at the instant the fade ended. On a dropped
   frame the last dots were still mid-fade; `remove('built')` reverts them toward
   base opacity 0 via the `.bd` 0.24s base transition, the `void offsetWidth`
   reflow snapshots them at ~0.5, and `add('built')` rebuilds from 0.5.

   **#origin never showed this because its span (1110) exceeds its fade (last
   .sd 660 + 220 = 880) by 230 ms.** The badge had 0 ms. The fix is a TAIL, not a
   change to the reset or the fade: the reset now fires at
   `span + BADGE_RESET_MARGIN_MS`, **BADGE_RESET_MARGIN_MS = 230** — #origin's
   proven slack. (Alternative considered: 240 = the `.bd` base transition
   duration; 230 chosen for parity with the reference loop, which is proven to
   reset clean.) The full period grows 7.97s -> ~8.2s, acceptable: the beacon
   need not match #origin's period, only clear its own fade. The departure, the
   build-in, the hold and DOT_HOLD_MS are UNCHANGED; the copy was untouched.

   ── ⚠ A TIMING RACE PASSED THE HEADLESS PROBE AND FAILED THE REAL RENDER.

   L1's verification measured worst-case child opacity at every reset and read
   **0.002**, dismissed as a razor edge and reported "clean-ish". It was the
   defect: 0.002 is the last dot finishing at the EXACT reset frame in a fast
   headless run; a real browser, or one dropped frame, put that dot at ~0.5.
   **A near-zero-but-not-zero worst-case reading at a race boundary is a FAILURE
   reading, not a pass** — see the discipline catalogue.

   */

/* The copy column rides above the overlay. WITHOUT THIS the ::before
   paints over the text — it is a later sibling in paint order. */

/* ---------------------------------------------------------------------
   §6b — THE SAME TEXTURE ON THE GOLD QUOTE BAND (8v treatment, 9h ground)

   THIRD INSTANCE OF THIS OVERLAY, AND THE FIRST ON A LIGHT GROUND.
   Identical terms to #fragmentation and #ecosystem: --slate through
   longitude-texture.svg at 18px, repeat, top left, opacity .10, every
   longhand restated prefixed and unprefixed. Still not merged into a
   selector list with the other two — those two sit on one value, this one
   on another, and a palette move separates them.

   THE DIRECTION INVERTS HERE AND THAT CHANGES WHICH END BINDS.
   --slate is DARKER than --gold, so this overlay DARKENS its ground where
   on the two dark bands the same paint LIGHTENS. Measured: gold relative
   luminance 0.53165 bare, 0.48036 inked. For the DARK foregrounds this
   band carries, a darker ground means LESS contrast, so the INKED
   composite BINDS and the bare ground is the best case — the opposite of
   #fragmentation. DO NOT CARRY A BINDING END BETWEEN BANDS ANY MORE THAN
   A NUMBER.
   --------------------------------------------------------------------- */
.wl-proof-quote-band{position:relative}
.wl-proof-quote-band::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;
}
.wl-proof-quote-band > .in{position:relative;z-index:1}

/* ---------------------------------------------------------------------
   HERO — a reading hero, not a staged one

   No canvas and no sphere, for the reason utilities.css records for
   .u-hero: the home page carries the artwork, and repeating it would make
   this page read as a second front door rather than as the argument it is.
   T02 gives the hero a header, one body paragraph and two CTAs, and that
   is all this is.

   NO .rv IN THE HERO, AND IT IS A CHOICE RATHER THAN A PRECEDENT.
   The two built pages disagree: index.html's hero carries no reveal class,
   utilities.html's carries one on every child. .rv resolves to opacity:0
   until js/reveal.js adds .on, so anything carrying it renders blank if
   that script fails to load or throws. base.css's reduced-motion branch
   covers the motion PREFERENCE; nothing covers a script that never
   arrives. The h1 and the lead are this page's primary claim and are left
   out of that dependency. Every band below the fold does reveal — since
   8u on its individual children rather than on its .in — where the reveal
   is the point and a failure costs one section rather than the page's
   opening line.

   NO NEW REVEAL IS DEFINED IN THIS FILE, so no new reduced-motion branch
   is needed here. The page uses base.css's .rv and nothing else — its
   @media(prefers-reduced-motion:reduce) block restates .rv at equal
   specificity and presents the settled state immediately. If a later unit
   adds a reveal of its own, it needs its own branch restating its own
   selector: a media query adds no specificity.
   --------------------------------------------------------------------- */
/* THE FOURTH PAGE-LEVEL .kick BUMP. base.css:76 sets .kick at 11px and
   each page hero raises it to 14px with a one-line rule: home.css:220,
   utilities.css:244, our-team.css (.a-hero .kick — a SELECTOR, not a line number; it moved twice in nine days), and this. Same pattern, no new class,
   no new token, nothing scoped beyond the hero. The size does not move the
   ratio — 14px is SMALL exactly as 11px is, so the threshold stays 4.5 and
   the measured 4.5994 on this hero's paper ground is unchanged by it. The
   ground dependency is recorded at the element in why-longitude.html. */
.wl-hero .kick{font-size:14px}

.wl-hero{padding-top:150px;padding-bottom:64px}
/* MEASURE ADJUSTMENTS, DIRECTOR-SUPPLIED AND VERIFIED IN CONSOLE (R5).
   1040px -> 1182px and 18ch -> 20ch. Both are VALUE CHANGES to rules that
   already existed here; no selector and no specificity relationship
   entered the sheet.

   1182 IS NOT "1180 PLUS TWO". base.css:28 sets a global `.in`
   max-width:1180px, and this hero has overridden it to 1040 since it was
   built — so the change is +142px on this element, and it CROSSES the
   global rather than drifting off it. Recorded because the 2px reads as a
   typo against base.css and is not one; it was measured. `.wl-hero .in` is
   (0,2,0) against base's (0,1,0) and wins on specificity, not load order.

   NEITHER RULE IS INSIDE A MEDIA QUERY — checked by brace tracking, not by
   eye (§49). The hero's ≤920 rule sets flex-direction, not max-width, so a
   wider container cannot silently defeat the stack; gated and measured.

   THE DOT FIELD LIVES INSIDE THIS BOX. `.wl-hero .dots` is
   flex:0 0 min(30vw,340px) (see the hero layout block later in this file),
   and js/reveal.js needs .fwrap to reach a 0.9 intersection ratio or every
   dot stays at opacity 0 with nothing in the console — the 9an failure.
   The R4 gate was re-run in full against this widening and held at all
   four widths. */
.wl-hero .in{max-width:1182px}
.wl-hero h1{max-width:20ch}
.wl-hero .lead{
  margin-top:22px;font-size:18px;line-height:1.6;
  color:var(--on-page-body);max-width:56ch;
}

/* HERO CTA ROW — the pairing has no precedent, so it is this sheet's job.
   Both built heroes carry exactly one CTA; T02's carries two. They are
   laid out in T02's order, the first as .btn and the second as .cta-line,
   which is how primary and secondary are distinguished everywhere else on
   the site.

   .cta-line CARRIES margin-top:22px OF ITS OWN, correct for the stacked
   case in a body section and wrong in a row — it would drop the second
   label below the button. Zeroed here at (0,2,0) against
   components/buttons.css's (0,1,0); this sheet also loads last, so the
   override holds on either ground. READ IT BACK ON THE ELEMENT rather
   than trusting the arithmetic.

   flex-wrap IS LOAD-BEARING AT 320. The two labels do not share a line at
   that width and must stack rather than overflow the 34px gutters.
   --------------------------------------------------------------------- */
.wl-cta{
  margin-top:30px;
  display:flex;flex-wrap:wrap;align-items:center;
  gap:18px 26px;
}
.wl-cta .cta-line{margin-top:0}

/* ---------------------------------------------------------------------
   READING MEASURE ON THE BODY BANDS

   base.css caps .body at 56ch, so the paragraphs are already set. The
   headings are not: h2 is clamp(28px,3.4vw,46px) inside a 1180px .in,
   which at full width runs a long header past a comfortable measure.
   Capped in ch so the limit follows the type rather than the viewport —
   the same device .u-domains h2 and .u-hero h1 use.

   The hero's own h1 cap is set in the hero block above, not restated here.
   --------------------------------------------------------------------- */
.band-plum h2,
.wl-origin h2{max-width:24ch}

/* ---------------------------------------------------------------------
   THE .rv SPLIT ON THIS PAGE IS DELIBERATE AND ASYMMETRIC

   Stated here as a DECISION, not as a pattern to copy. The hero carries no
   reveal class; every band below it reveals. Do not make it consistent in
   either direction without re-reading the reasoning in the hero block
   above — the asymmetry is the point, and both "add .rv to the hero" and
   "strip .rv from the bands" would discard it.

   THE GRANULARITY IS PER ELEMENT, NOT PER BAND (8u). Until 8u the class
   sat on each band's `.in`, so a section faded in as a single lump: four
   reveal nodes inside <main>, against index.html's 16 and utilities'
   17 — both of which reveal individual headings, paragraphs and CTAs.
   The class now sits on the h2, on each p.body, on the deck, on each
   a.cta-line and on .wl-tablewrap, which is the shape both built pages
   already use. Nothing else changed: this is still base.css's one .rv
   rule and js/reveal.js's existing one-shot IntersectionObserver, which
   adds .on and unobserves on first fire. NO new observer, no scroll
   listener, no scrollY read, no progress scalar — the register rule in
   js/reveal.js is not relaxed and this unit did not touch that file.

   COUNT THE NODES ON THE DOM, NOT IN THIS COMMENT. The join band carries
   its own .rv from partials/components/join-why-longitude.html, which is
   a SHARED partial on four pages and is not this page's to move; a count
   taken over <main> and a count taken over the document therefore differ
   by exactly that one, and both are correct answers to different
   questions.

   .wl-tablewrap CARRIES tabindex="0" AND NOW ALSO CARRIES .rv, which is
   worth stating rather than discovering. .rv resolves to opacity:0 until
   the observer fires, so if js/reveal.js never loads the scroll region is
   focusable and invisible. That is the same dependency every revealed
   element on the page takes, and it is why the hero's h1 and lead are
   deliberately kept out of it — the opening claim does not depend on a
   script, the table does. base.css's prefers-reduced-motion branch
   presents the settled state immediately and covers the preference; it
   does not cover a script that never arrives.

   FOR CONTEXT, NOT FOR IMITATION: our-team.html carries .rv throughout,
   including its hero. The two pages differ on purpose and that difference
   is not a defect on either side.
   --------------------------------------------------------------------- */

/* ---------------------------------------------------------------------
   §5 — THE DECK (R2)

   The second half of T02 §5's header, split from the h2 at the colon.
   It is a PARAGRAPH, not a heading: it carries no outline weight and
   promoting it to h3 would invent a level the source does not have and
   put a skipped level into the page's heading outline.

   Sized between the h2 and the body so it reads as a standfirst. At 20px
   non-bold it is SMALL TEXT at a 4.5 threshold — 24px is the large-text
   boundary and this is deliberately under it, so the token choice is
   judged at the stricter number: --on-page-body on --paper is 8.0825.
   --------------------------------------------------------------------- */
.wl-deck{
  margin-top:14px;
  font-family:var(--serif);
  font-size:clamp(18px,1.7vw,20px);
  line-height:1.4;
  color:var(--on-page-body);
  max-width:46ch;
}

/* ---------------------------------------------------------------------
   §5 — THE MODEL COMPARISON TABLE

   THE EMPHASISED ROW USES AN EXISTING ROLE PAIR AND INVENTS NOTHING.
   --ground-fill / --on-fill is documented in tokens.css as the pair for
   "a dark fill's foreground", which is exactly this job: a filled row
   carrying its own text. Measured on the page ground:
     row fill --ground-fill against --paper   13.9920  (non-text, vs 3.0)
     row text --on-fill on --ground-fill      13.0839  (small text, vs 4.5)
   The other 21 cells take --on-page-body on --paper at 8.0825 and the
   three header cells --on-page at 13.9920.

   COLOUR IS NOT THE SOLE MEANS OF DISTINGUISHING THE ROW. T02 bolds that
   one cell of 24 and the <strong> is carried through, so the emphasis
   survives a monochrome rendering and a forced-colours mode.

   320px IS A STOP CONDITION AND THE ANSWER HERE IS A SCROLL REGION, NOT A
   REFLOW. Three columns of running prose cannot be squeezed into 320 minus
   68px of gutters without either truncating cells or dropping to a
   per-cell stacked layout — and stacking needs each cell relabelled with
   its column header, which means duplicating the three header strings into
   CSS generated content. That would put copy in a stylesheet, give the
   page two sources for the same string, and hand it to a mechanism screen
   readers treat inconsistently. The table keeps its shape and the
   container scrolls. min-width is what forces the scroll instead of a
   crushed, illegible squeeze.

   THE 320 BEHAVIOUR IS MEASURED, AND THE MECHANISM DOES WHAT IT CLAIMS.
   Re-measured in 8u over http://localhost against a real engine, not
   carried forward from a report:

     width  documentElement          .wl-tablewrap        right-edge
            scrollWidth/clientWidth  client / scroll      offenders
     1440   1440 = 1440              1040 / 1040  static  0
      768    768 =  768               700 /  700  static  0
      375    375 =  375               307 /  680  scrolls 28, ALL inside
      320    320 =  320               252 /  680  scrolls 28, ALL inside

   THE 28 IS THE POINT, NOT A DEFECT. Those are the table's own cells,
   whose right edges sit past the viewport INSIDE the scroll region —
   which is exactly what min-width:680px is for. The number that matters
   is the one beside it: elements overflowing OUTSIDE .wl-tablewrap is 0
   at every width, and the document itself never gains a horizontal
   scrollbar. A probe that only counted right-edge offenders would report
   28 and read as a failure; a probe that only checked scrollWidth would
   report clean and never look at the region. Both questions have to be
   asked, and they are different questions.

   At 768 the table fits at 700 = 700 and the region stops scrolling, so
   the scroll behaviour is genuinely width-driven rather than always-on.
   The region keeps tabindex="0" and role="region" at every width.

   THE MEASUREMENT CARRIES ITS INSTRUMENT. Taken with a positive control —
   an injected element 200px wider than the viewport — asserted to FIRE
   the detector at each width before the real figures were read. A probe
   that cannot return a failure always agrees with whoever ran it.
   --------------------------------------------------------------------- */
/* ---------------------------------------------------------------------
   §5 — THE BODY COPY TAKES A WIDER MEASURE (9k, design-lead revision)

   86ch, up from base.css's 56ch. One value, one element.

   SCOPED TO THE DIRECT CHILD SO IT CANNOT REACH A TABLE CELL.
   `#the-model > .in > p.body` is a child chain, so a `.body` anywhere
   inside .wl-tablewrap could not match it even if one were added later.
   Measured before writing it: zero `.body` elements inside the table
   today, so a descendant selector would have been harmless right now and
   fragile the moment a cell took the class. The table's columns are not
   body copy and this cap must never reach them.

   THE DECK IS DELIBERATELY NOT INCLUDED, and it is a judgement rather
   than an omission. `.wl-deck` is the SECOND HALF OF THIS SECTION'S
   HEADER, split from the h2 at the colon under R2 and logged as
   deviation 8 — its own block above calls it a standfirst and says it is
   "sized between the h2 and the body". Its measure is part of that role.

   AND THE TWO CAPS ARE CURRENTLY TUNED TO RENDER EQUAL, WHICH ONE SHARED
   ch VALUE WOULD DESTROY. `ch` resolves in the element's own font, and
   these two fonts differ: at 1440 the deck's ch measures 11.13px and the
   body's 9.19px. So 46ch and 56ch — different numbers — land at 511.66px
   and 513.74px, TWO PIXELS APART. Measured, both of them.

   Give both 86ch and they land at 957.18px and 790.34px: a 166.84px
   split, because the serif ch is the wider unit. The near-equality is
   the current design and one shared ch value cannot preserve it.
   Breaking it is a design decision and was not this unit's to take.

   If the deck should widen too, it needs its OWN value chosen to keep or
   deliberately break that relationship — not this one repeated.

   THE h2 IS UNTOUCHED AND IT HAS NO CAP AT ALL. `.band-plum h2` and
   `.wl-origin h2` carry 24ch; `.wl-model h2` is in neither list, so it
   runs the full 1040px .in and always has. Nothing here changes that.
   --------------------------------------------------------------------- */
.wl-model .in{max-width:1040px}
#the-model > .in > p.body{max-width:86ch}
.wl-tablewrap{
  margin-top:34px;
  overflow-x:auto;
  -webkit-overflow-scrolling:touch;
}
.wl-tablewrap:focus-visible{outline:3px solid var(--focus);outline-offset:3px}

.wl-table{
  border-collapse:collapse;
  width:100%;
  min-width:680px;
  font-size:15px;
  line-height:1.5;
  text-align:left;
}
.wl-table caption{
  caption-side:top;
  text-align:left;
  font-family:var(--mono);
  font-size:11px;
  letter-spacing:.18em;
  text-transform:uppercase;
  color:var(--on-page);
  padding-bottom:12px;
}
.wl-table th{
  font-family:var(--mono);
  font-size:10.5px;
  letter-spacing:.14em;
  font-weight:640;
  color:var(--on-page);
  border-bottom:2px solid var(--on-page);
  padding:0 18px 10px 0;
  vertical-align:bottom;
}
.wl-table td{
  color:var(--on-page-body);
  border-bottom:1px solid var(--rule-hair);
  padding:14px 18px 14px 0;
  vertical-align:top;
}
.wl-table th:last-child,
.wl-table td:last-child{padding-right:0}
.wl-table td:first-child{color:var(--on-page);font-weight:640;white-space:nowrap}

/* THE EMPHASISED ROW. (0,2,1) against the (0,1,1) of .wl-table td and the
   (0,2,1) of .wl-table td:first-child — equal to the latter, and later in
   the file, so it wins on order for the first cell too. VERIFY BY COMPUTED
   VALUE: a first-cell rule that kept --on-page would read 1.0679 against
   this fill and would be invisible, and nothing about the source would
   look wrong. */
.wl-table .wl-row-lh td{
  background:var(--ground-fill);
  color:var(--on-fill);
  border-bottom:none;
}
.wl-table .wl-row-lh td:first-child{color:var(--on-fill);padding-left:18px}
.wl-table .wl-row-lh td:last-child{padding-right:18px}

/* ---------------------------------------------------------------------
   §2 — HEADING LEFT, PROSE RIGHT (9b, design-lead revision)

   THE SAME GRID DEVICE AS §3, §6 AND .u-domains, NOT A SECOND APPROACH.
   The DOM stays in T02 order — h2, three body paragraphs — and the
   heading is placed in column 1 with explicit grid-column / grid-row, so
   the order a screen reader and a keyboard follow is unchanged and the
   visual arrangement is a presentation layer over it. No markup was
   reordered and no class was added to copy-bearing markup: the
   paragraphs are selected by element and class.

   THE HEADING SPANS ALL THREE ROWS, AND THAT IS LOAD-BEARING RATHER THAN
   TIDY. With `grid-row:1` alone the heading would size row 1 by itself,
   and row 1 also holds the first paragraph — so a 64px heading five
   lines deep would open a gap of a couple of hundred pixels between
   paragraph one and paragraph two while the other two rows stayed short.
   Spanning 1 / span 3 makes the PARAGRAPHS size the rows and lets the
   heading sit inside their total. This is also why the release below
   matters: an explicit row that survives into one column pins content
   beneath empty cells, which is the failure utilities.css records.

   THE HEADING IS THE OTHER HALF OF THE LAYOUT. 8v measured two columns
   on this section and found it produced more void than it filled at a
   46px heading. The column is 554px at 1440 and a 46px heading occupies
   roughly 300px of the 371px the prose column runs to — the void 8v
   found. At 64px the heading fills its column, which is what makes the
   two columns pay for themselves here. DO NOT REVERT ONE WITHOUT THE
   OTHER; see the §3 block below for the same statement from its side.

   THE 24ch CAP IS NOT RELAXED AND AT 1440 IT IS INERT. `.band-plum h2`
   caps this heading at 24ch, which resolves to about 892px at 64px —
   wider than the 554px column, so the column is what constrains the
   measure and the cap costs nothing. Below 920 the section is one
   column and the cap binds again, at roughly 557px inside a 700px .in at
   768. Both states are measured in the unit report rather than inferred
   from the declaration. Nothing here relaxes a reading measure.

   THE EM IS GOLD THROUGH base.css's EXISTING `h2 em.g` HOOK, not through
   a rule in this sheet. index.html's #problem heading already uses that
   hook on this identical ground, so gold-on-inked-plum is precedent and
   not a new pairing. `h2 em.g` is (0,1,2) against `h1 em,h2 em`'s (0,0,2)
   and wins on specificity, so link order cannot undo it. THE COST OF
   REUSING THE HOOK IS A DEPENDENCY ON A FILE THIS SESSION MAY NOT EDIT:
   if `h2 em.g` is ever removed from base.css this heading silently falls
   back to --accent and back to a 0.2204 margin. Recorded so the coupling
   is visible rather than discovered.

   THE PROSE SIZE IS ONE VALUE FOR ALL THREE PARAGRAPHS AND THE WEIGHT IS
   NOT. 18.5px on a 1.78 leading, against base.css's 16.5/1.65. 18.5px is
   chosen over 19px deliberately: WCAG's large-text boundary for bold is
   18.66px, so at 18.5px the bold closing paragraph stays SMALL and every
   foreground on this band is judged at the STRICTER 4.5 threshold. At
   19px the closing line would reclassify as LARGE and be judged at 3.0 —
   it passes either way at 7.8662, but one threshold across the whole
   block is the honest reading and it is the conservative one. A 0.16px
   change of font-size moves a threshold by 1.5; that is the trap.

   THE CLOSING PARAGRAPH IS SELECTED BY :last-of-type. All three children
   are p, so last-of-type is the third. A paragraph appended AFTER it
   would take the weight and this one would lose it — that is the cost of
   a positional selector, recorded here rather than discovered later, and
   it is the same trade .u-domains records for its :nth-of-type pair.
   .u-domains pairs its weight bump with a colour bump to --on-dark; that
   is NOT copied. 9b was asked for a weight change and the colour stays
   --on-dark-body, so the closing line reads heavier without also reading
   brighter than the two above it. Flagged for the design lead, not acted
   on.
   --------------------------------------------------------------------- */
/* row-gap:0 IS THE ONE LINE HERE THAT IS NOT COSMETIC. bands.css sets
   `.band-plum .in{display:flex;gap:5vw;align-items:center}` and `gap` is a
   SHORTHAND — it sets row-gap as well as column-gap. On the block box the
   comment at the top of this sheet is right that gap is inert, but the
   moment this container becomes a grid the inherited row-gap wakes up at
   5vw and inserts 72px between every pair of paragraphs at 1440, ON TOP OF
   .body's own 20px margin. Measured before this line existed: paragraph
   tops 838.28 / 1029.05 / 1318.58, i.e. 92px apart where the rhythm is 20.
   Setting column-gap alone does NOT close it — the shorthand's other half
   survives. §22, in a new place: a shorthand has two halves and overriding
   one leaves the other. */
/* The columns start on the same line. .body carries margin-top:20px from
   base.css and the heading carries none, so without this the prose column
   begins 20px lower than the heading for no reason anyone chose. Only the
   FIRST paragraph is zeroed — the 20px between paragraphs is the rhythm
   and stays, and it stays at 20px rather than scaling with the new size. */

/* =====================================================================
   §3 — THREE SUB-BANDS (9c, design-lead restructure)

   THIS REPLACES 8v's TWO-COLUMN TREATMENT OF THIS SECTION ENTIRELY.
   8v put the heading in a left column and the five paragraphs in a
   right one. The design lead's revision drops that: the heading is
   full-width and centred, two paragraphs are deleted, and the rest is
   re-grouped into three sub-bands with the middle one on its own
   ground. The 8v rules are gone rather than overridden — leaving them
   live would have fought every rule below.

   THE §2 BLOCK ABOVE STILL REFERS TO "the §3 block below" FOR THE
   PAIRED STATEMENT that a two-column placement and a display heading
   are one change. That statement is now made in §2's block alone,
   because §3 no longer carries a two-column layout to make it from.
   §2's own reasoning is unaffected and its layout is untouched.

   ONE SECTION, THREE BANDS, ONE HEADING. base.css sets
   `section{padding:110px 34px}`. That padding is zeroed on .wl-origin
   and re-applied to each sub-band, so the middle band's ground can
   bleed the full viewport width instead of stopping at the section
   gutter. The vertical rhythm is preserved end to end: 110px above
   band 1 and 110px below band 3, exactly as the single section had,
   with 84px between bands.

   WHY NOT THREE SECTIONS. The section carries one h2 and one id. Three
   sections would mean either three headings this copy does not have,
   or two sections with no heading at all — a worse document outline in
   exchange for nothing this layout needs.
   ===================================================================== */
.wl-origin{padding:0}
.wl-o1{padding:110px 34px 84px}
.wl-o2{padding:84px 34px}
.wl-o3{padding:84px 34px 110px}

/* ---------------------------------------------------------------------
   BAND 2's GROUND: --ground-fill / --on-fill, AND THE CHOICE IS THE
   INTERESTING PART

   The brief's stop condition was "if no existing token pair provides a
   ground visibly distinct from bands 1 and 3, stop". One does. Four
   candidates were measured against band 1's ground (--ground-page,
   L* 97.65) before this one was taken:

     --ground-alt   (cream)  L* 95.00   dL*  2.65   accent 3.6759
     --ground-field (white)  L* 100.00  dL*  2.35   accent 4.1669
     --ground-slate          L* 47.67   dL* 49.98   accent 1.1700
     --ground-dark  (plum)   L* 15.90   dL* 81.76   accent 3.5594
     --ground-fill  (ink)    L* 15.90   dL* 81.76   accent 3.5594

   9e SUPERSEDES THE PARAGRAPH THAT USED TO SIT HERE, BY DIRECTOR
   DECISION. 9c rejected --ground-alt for this band on two grounds: that
   2.65 dL* is a tint rather than a contrast, and that §4 immediately
   below is already --ground-alt, so cream here would render
   paper / cream / paper / cream with the band-3 strip reading as a seam.
   The FIRST objection is answered by the design lead choosing a light
   band deliberately — this is no longer trying to be a contrast. The
   SECOND is answered by moving the dark DOWN the page: §4 #ecosystem
   goes dark in unit 9f, immediately after this one.

   SO THE ADJACENCY IS REAL AND IS KNOWN. Between 9e and 9f this section
   ends light and §4 begins on the same cream. That state is
   director-accepted and TEMPORARY, and it is recorded in checkpoint-9e
   as an open item rather than compensated for here. Do not "fix" it by
   moving this band's ground back.

   --ground-slate IS FORECLOSED FOR BODY COPY, PROJECT-WIDE. Its own
   --on-slate measures 4.3009 against a 4.5 small-text threshold, and
   --accent on it is 1.1700. Band 2's right column is body copy. Not a
   candidate.

   WHY --ground-alt AND NOT --ground-field, THE OTHER LIGHT CANDIDATE.
   The mock reads as a warm sand marginally off the page ground, and
   only one of the two is warm OR off it in the right direction:

     token                    L*      dL* vs page   warmth (R-B)
     --ground-page (paper)    97.65       0.00           +9
     --ground-alt   (cream)   95.00       2.65          +16
     --ground-field (white)  100.00       2.35            0

   --ground-field is NEUTRAL — zero warmth — and it is LIGHTER than the
   page, so it reads as a card cut out of the band rather than as a
   ground the band sits on. --ground-alt is warmer than the page and
   darker than it, which is what a sand band does. The 2.65 dL* is the
   whole point rather than a shortfall: the design lead asked for
   marginally distinct.

   THE FOREGROUND IS ITS OWN PAIR, --on-alt, AT 13.0839. No token was
   added and no value was invented — this is a swap of which existing
   pair the band references. --ground-fill / --on-fill, which this band
   carried from 9c until 9e, are untouched and still correct for any
   dark fill that is not the problem band.
   --------------------------------------------------------------------- */
.wl-o2{background:var(--ground-alt);color:var(--on-alt)}

/* ---------------------------------------------------------------------
   BAND 1 — CENTRED HEADING, SERIF LEDE, CUE LINES

   THE 24ch HEADING CAP IS RAISED HERE AND NOWHERE ELSE. `.wl-origin h2`
   caps at 24ch for a left-aligned column heading; centred and
   full-width that cap would hold the line to roughly 641px inside an
   1180px .in and read as a narrow block floating in the middle of the
   band. `#origin .wl-o1 h2` is (1,1,1) against (0,1,1) and wins on
   specificity. The cap is RAISED, not removed — text-wrap:balance from
   base.css still does the line breaking.
   --------------------------------------------------------------------- */
#origin .wl-o1 h2{
  max-width:34ch;
  margin-inline:auto;
  text-align:center;
}
/* The serif lede. A NARROWER MEASURE THAN THE HEADING, deliberately —
   it is the only running prose on this band and it sits under a centred
   display line, so it needs a reading measure rather than the band's
   width. Serif is a departure from .body's sans and is the design
   lead's; it is the same face the headings use, var(--serif). */
.wl-o-lede{
  margin:26px auto 0;
  max-width:56ch;
  font-family:var(--serif);
  font-size:19px;line-height:1.7;
  color:var(--on-page-body);
  text-align:center;
}
/* The two cue lines, above and below the connector. Bold sans, centred.
   These are NOT .body — .body is 16.5px regular with a 56ch cap and a
   left-aligned measure, and restating all of that to override it would
   be worse than not taking it. */
.wl-o-cue{
  margin:30px auto 0;
  max-width:52ch;
  font-size:19px;font-weight:700;line-height:1.55;
  color:var(--on-page);
  text-align:center;
}
/* THE SETUP LINE SCALES WITH THE NODES, THE CLOSING LINE DOES NOT (9d).
   Both cue lines share .wl-o-cue and 9d moves only the first — it is the
   sentence the connector answers, and the mock sets it just under the node
   label. The closing line stays at 19px because nothing in this unit's
   brief moves it.

   SELECTED BY A CLASS, NOT BY POSITION. `p.wl-o-cue:nth-of-type(2)` would
   also hit it — the lede is p1, this is p2 — but it silently retargets if
   any p is added to this band. .wl-o-setup adds no copy and cannot drift. */
.wl-o-setup{font-size:24px;line-height:1.4}

/* ---------------------------------------------------------------------
   THE THREE-NODE CONNECTOR

   GEOMETRY, AND WHY IT IS ABSOLUTE POSITIONING RATHER THAN GRID SPANS.
   The requirement is that each segment's endpoints land on the CENTRES
   of its adjacent dots at every width. The dots are grid items, one per
   third, each justify-self:center — so their centres are at exactly
   1/6, 1/2 and 5/6 of the rail, whatever the rail measures.

   A GRID-SPANNING SEGMENT CANNOT EXPRESS THAT WITHOUT A PERCENTAGE
   MARGIN, AND A PERCENTAGE MARGIN IS THE TRAP. A margin percentage on a
   grid item resolves against the item's GRID AREA, not against the rail
   and not against the item's own width — a different basis from the one
   the same declaration would use on a flex item. The segments are
   absolutely positioned instead and inset with left/right percentages,
   which resolve against the containing block's padding box and nothing
   else. 16.6667% / 50% puts each endpoint on a dot centre by
   construction, at every width, with no dependence on the dot's size.

   TOP IS calc(), NOT translateY, BECAUSE transform IS SPOKEN FOR.
   Centring the segment with translateY(-50%) would occupy the transform
   property that the draw needs. The segment has a fixed height, so
   `top:calc(50% - 1.5px)` centres it arithmetically and leaves transform
   free. In the event the draw is clip-path rather than transform — see
   below — but the constraint held while that was being decided and the
   arithmetic is the more robust form regardless.

   NOTHING HERE IS SVG. The dots are spans with border-radius; the
   segments are spans carrying a repeating-linear-gradient. The Chrome
   behaviour where the individual `translate` / `scale` / `rotate`
   properties silently do not apply to SVG elements — a zero-drift that
   computed style reports as perfectly fine — cannot arise, because
   there is no SVG in this component. Recorded so the next reader knows
   it was considered rather than missed.

   THE DRAW IS clip-path, NOT scaleX. scaleX on a repeating-linear-
   gradient stretches the gradient with the box, so the dots of the
   dotted rule would grow from smears into circles as the segment draws.
   clip-path:inset() reveals the already-correct gradient left to right
   and leaves every dot the size it will end at.
   --------------------------------------------------------------------- */
/* --dot IS ONE VALUE DRIVING THREE PLACES (9d). The rail's height, the
   dot's box and the stacked marker below 1024 all read it, so the dot can
   be resized without the rail being left at an old height and dropping the
   segments off the dot centreline. 9d took it 18px -> 36px, which is 1.3846x
   the 26px node label — the design lead's mock reads about 1.4x.

   THE SEGMENT ENDPOINTS DO NOT DEPEND ON THIS VALUE AT ALL. The dots are
   grid items at justify-self:center in equal thirds, so their centres are
   at 1/6, 1/2 and 5/6 of the rail whatever the dot measures, and the
   segments are inset to those fractions. Doubling the dot moves no
   endpoint — measured, not assumed. */
.wl-conn{margin-top:40px;--dot:36px}
.wl-conn-rail{
  position:relative;
  display:grid;
  grid-template-columns:repeat(3,1fr);
  align-items:center;
  height:var(--dot);
}
.wl-cx-dot{
  grid-row:1;
  justify-self:center;
  width:var(--dot);height:var(--dot);border-radius:50%;
  background:var(--gold);
  /* above the segments, so a segment running under a dot cannot show
     through it. z-index alone is not enough on a static element — the
     dots are grid items in the rail's own stacking context and the
     segments are positioned, so both participate. */
  position:relative;z-index:1;
}
.wl-cx-1{grid-column:1}
.wl-cx-3{grid-column:2}
.wl-cx-5{grid-column:3}
.wl-cx-seg{
  position:absolute;
  top:calc(50% - 1.5px);
  height:3px;
  z-index:0;
  background-image:repeating-linear-gradient(
    to right,
    var(--gold) 0 3px,
    transparent 3px 8px
  );
}
.wl-cx-2{left:16.6667%;right:50%}
.wl-cx-4{left:50%;right:16.6667%}

/* The labels. A three-column grid on the same 1fr thirds as the rail,
   so each label is centred under its own dot by sharing the rail's
   column basis rather than by being positioned against it. */
.wl-conn-labels{
  list-style:none;margin:18px 0 0;padding:0;
  display:grid;
  grid-template-columns:repeat(3,1fr);
  column-gap:24px;
}
/* NODE LABELS, 16px -> 26px/700 (9d, design-lead revision).

   THE MEASURE IS CONSTRAINED ON PURPOSE AND THE WRAP IS THE DESIGN. At the
   full track width these labels set on one line at 26px and the column
   reads as a caption; the mock breaks each of them over two or three lines
   under its dot. **THE TARGET IS TWO LINES: three is a widow and one is a
   caption.** `max-width` on the label rather than on the track, so the grid
   keeps its equal thirds and only the text is narrowed.

   **290px, AND THE FIGURE THAT STOOD HERE WAS WRONG IN BOTH HALVES.** This
   comment documented 290px while the rule shipped 250px, and it claimed 290px
   was the value that puts node 2's "it" alone on a third line. Measured at
   B3: **290px puts node 2 on TWO lines — the widow occurs at 250px, the value
   that was actually shipping.** The comment described the fix as if it were
   the defect. Corrected 2026-08-17 and the rule moved to 290px in the same
   unit, so the documented value and the shipped value now agree. It remains a
   TYPESETTING value tuned against these exact strings, not a round number:
   change the copy or the face and re-measure. See WL-25.

   AT 26px/700 THESE CROSS WCAG's 18.66px BOLD BOUNDARY and reclassify from
   SMALL to LARGE, so the threshold drops 4.5 -> 3.0. They measure 13.9920
   either way; the ratio does not change with size. Recorded because the
   reclassification is real even though nothing here depends on it. */
.wl-node{
  text-align:center;
  font-size:26px;font-weight:700;line-height:1.28;
  color:var(--on-page);
  max-width:290px;
  margin-inline:auto;
}

/* THE BANDED REDUCTION — 768 to 939.98 ONLY, AND IT MUST STAY BELOW THE RULE
   ABOVE. §49: A MEDIA QUERY ADDS NO SPECIFICITY. This and `.wl-node` are both
   (0,1,0), so this wins on SOURCE ORDER ALONE. Move it above and it silently
   never applies — nothing errors, 1440 still looks right, and the widow just
   returns at 768.

   WHY A BAND AND NOT A GLOBAL SIZE. 768-939.98 is the only range where the
   three-column grid is active AND the track is narrower than the 290px cap, so
   the cap never binds there and font-size is the only lever. Below 768 the
   layout is single-column and 26px already gives two lines; from 940 up the
   cap governs again.

   WHY A CLAMP AND NOT A FLAT VALUE. The size needed rises with width —
   20px@768, 21@800, 22@830, 23@860, 24@880 — and a flat 20px OVERSHOOTS the
   band's own top, measured 2/2/1 at 939 with node 3 collapsing to one line.
   The clamp reaches 26px exactly at 940 and meets the base rule there.
   Same pattern as `.vm-band .vm-label` on our-approach. WL-25 has the figures. */
@media(min-width:768px) and (max-width:939.98px){
  .wl-node{font-size:clamp(20px, 3.49vw - 6.8px, 26px)}
}
/* ############################################################
   `.wl-node-sub` IS A DEAD RULE. IT STYLES NOTHING, ON ANY PAGE.
   MEASURED AT B3, 2026-08-17: **0 `.wl-node-sub` elements across all 20 built
   pages**, control `.wl-node` 3 on this page. The subordinate line it was
   written for — a span closing node 3 — was REMOVED BY CLIENT DIRECTION at
   9af and registered as deviation 17. **The comment that stood here described
   that line as a live "continuation of node 3's phrase", which it has not been
   since 9af.** Node 3's two-line measurement is two lines OF THE LABEL, not a
   label line plus a sub line — a reader who assumes otherwise will mis-derive
   every box height in this block.

   LOGGED AS AN R8 DEAD-CODE CANDIDATE AND DELIBERATELY NOT DELETED HERE. B3
   is a label-measure and animation unit; retiring rules is R8's, which already
   inherits 61 dark rules in this sheet. **Retiring it piecemeal is what that
   consolidation exists to prevent.** The original rationale is preserved below
   as the record of why it was authored, and it is accurate about the past.
   ############################################################

   ORIGINAL RATIONALE, as authored: Node 3's subordinate line. LIGHTER AND
   SMALLER, as a separate block inside the same list item — a continuation of
   node 3's phrase, not a fourth node, and putting it in its own <li> would
   have made the list four items long for a screen reader. */
/* 14px -> 18px/400 (9d), scaling with its label and staying lighter and
   smaller than it. STILL SMALL TEXT: the large-text boundary at weight 400
   is 24px, so this remains judged at 4.5, where it measures 4.9579 — a
   margin of 0.46 and the tightest non-accent foreground on the page. It
   would only reclassify above 24px, and going there to buy a lower
   threshold would be the wrong trade. */
/* DEAD RULE AS OF 9af, 2026-08-13 — RETAINED DELIBERATELY, NOT ORPHANED.
   Its last and only consumer was removed from why-longitude.html by
   deviation 17. Nothing on this page or any other page references it:
   verified by counting elements in the built DOM, not by grepping source.

   IT IS LEFT HERE ON THE .acc-eco-* PRECEDENT. A rule that loses its last
   consumer gets retired by a unit that is deliberately looking at dead
   rules, not by whoever happened to delete the markup — that way the
   removal is a decision with a record rather than a side effect. It joins
   the dead-rule backlog alongside .acc-eco-h, .acc-eco-b and .acc-meta*.

   IF THE SUBORDINATE LINE EVER RETURNS this is the treatment it had:
   18px/400, --on-page-soft, measured 4.9579 on the paper ground. */
.wl-node-sub{
  display:block;
  margin-top:8px;
  font-size:18px;font-weight:400;line-height:1.45;
  color:var(--on-page-soft);
}

/* ---------------------------------------------------------------------
   CONNECTOR REVEAL — FIVE ELEMENTS, ONE GATE, STAGGER IN CSS

   js/reveal.js observes `.wl-conn-rail` and adds `.on` once, then
   unobserves. The stagger is transition-delay here rather than timers
   there, so the whole sequence is one declaration per element and the
   reduced-motion branch below can cancel it without the script knowing.

   THE RAIL IS NOT .rv. Putting .rv on it would have run base.css's own
   opacity+translateY fade on the rail as a block at the same time as
   these five children ran their own — two animations on one component,
   one of them unintended. A dedicated hook was cheaper than overriding
   the primitive.

   IN REGISTER: in-place, fires once, settles, no scroll listener. The
   dots scale up from 0.4 and the segments draw left to right from their
   left dot toward their right dot, which is why transform-origin and
   the clip-path inset are both anchored on the left.
   --------------------------------------------------------------------- */
.wl-cx-dot{
  opacity:0;transform:scale(.4);
  transition:opacity .45s ease,transform .45s cubic-bezier(.22,1,.36,1);
}
.wl-cx-seg{
  clip-path:inset(0 100% 0 0);
  transition:clip-path .55s ease;
}
.wl-conn-rail.on .wl-cx-dot{opacity:1;transform:scale(1)}
.wl-conn-rail.on .wl-cx-seg{clip-path:inset(0 0 0 0)}
.wl-conn-rail.on .wl-cx-1{transition-delay:0ms}
.wl-conn-rail.on .wl-cx-2{transition-delay:140ms}
.wl-conn-rail.on .wl-cx-3{transition-delay:420ms}
.wl-conn-rail.on .wl-cx-4{transition-delay:560ms}
.wl-conn-rail.on .wl-cx-5{transition-delay:840ms}

/* ---------------------------------------------------------------------
   BAND 2 — LEDE LEFT, THREE ITEMS RIGHT
   --------------------------------------------------------------------- */
.wl-o2 > .in{
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  column-gap:5vw;
  row-gap:0;
  align-items:start;
}
/* THE SIZE OF THIS LEDE IS AN ACCESSIBILITY DECISION, NOT A
   TYPOGRAPHIC ONE, AND IT IS THE SAME ONE buttons.css MADE FOR
   .cta-line. THERE IS NO GROUND ON THIS SITE WHERE --accent CLEARS 4.5:
   paper 3.9310, cream 3.6759, white 4.1669, plum and ink 3.5594. So the
   emphasis phrase has to BE large text, which at regular weight means
   24px. The ground moved in 9e and this did not change — the sand
   ground reads 3.6759 against the dark ground's 3.5594, BETTER but
   still under 4.5, so the classification is still what carries it and
   the margin is still not what carries it.

   34px CARRIES A 10px MARGIN OVER THE 24px BOUNDARY. 9c set 28px for a
   4px margin; 9e raises the lede with the right column and the margin
   grows with it. At exactly 24px a future half-step down — a clamp, a
   rem change, a browser rounding a computed size — reclassifies the
   phrase as SMALL, the threshold jumps to 4.5, and 3.6759 fails with
   nothing visibly different on the page. DO NOT REDUCE THIS BELOW 24px,
   AT ANY WIDTH; below that it is the director's call, not a type
   decision. */
.wl-o2-lede{
  font-family:var(--serif);
  font-size:34px;font-weight:700;line-height:1.32;
  color:var(--on-alt);
  max-width:22ch;
}
.wl-o2-lede em{font-style:normal;color:var(--accent)}

/* 9e: 17px -> 26px/700, the connector node-label scale from 9d, so the
   two lists on this page read at one size. The measure is the grid track;
   these break to two lines at every three-column width, which is the mock.

   THE PADDING GOES 22 -> 26px WITH THE TYPE. It is the gap the hairlines
   sit in the middle of, so leaving it at 22 against 26px/700 copy would
   have crowded the rules against the descenders above them. */
.wl-o2-list{list-style:none;margin:0;padding:0}
.wl-o2-list li{
  font-size:26px;font-weight:700;line-height:1.4;
  color:var(--on-alt);
  padding:26px 0;
  /* N2: positioned so the hung numeral disc can anchor to it. li + li
     already carried this; li:first-child did not. */
  position:relative;
}
.wl-o2-list li:first-child{padding-top:0}
.wl-o2-list li:last-child{padding-bottom:0}
/* HAIRLINES BETWEEN THE ITEMS, NOT ABOVE THE FIRST OR BELOW THE LAST.
   `li + li` is what expresses "between" — a border-bottom on every item
   with the last one removed expresses the same picture and stops being
   true the moment the list is reordered or an item is added. Two rules
   for three items, at every width.

   9e INVERTS THEM AND THAT REPLACES A WORKAROUND WITH THE REAL TOKEN.
   On the dark ground this had to be --on-fill painted at .22, because
   --rule-hair is ink at 14% and a dark hairline is invisible on a dark
   band — the comment that used to sit here said exactly that. On the
   sand ground --rule-hair is the correct and intended reference, so the
   opacity workaround is gone with the ground that forced it. One token,
   no local alpha. */
.wl-o2-list li + li{position:relative}
.wl-o2-list li + li::before{
  content:"";position:absolute;left:0;right:0;top:0;height:1px;
  background:var(--rule-hair);
}

/* THE NUMERAL DISC. Added at N2, 2026-08-18, BugHerd #18.

   ⚠ THE RING IS LOAD-BEARING, NOT DECORATION. A bare gold disc measures
   **1.5925 on --ground-alt** and FAILS SC 1.4.11 by 1.4075 — the same
   figure G4 measured for the our-approach divider, and the same shape as
   R4. `--ink` measures **13.0839 against the ground and 8.2161 against the
   gold fill**, so the ring carries the 3:1 boundary from both sides and the
   fill no longer has to. Remove the ring and the disc fails. Same remedy
   9x applied to the violet button on gold.

   box-shadow inset, NOT border: it has no layout effect, so the box stays
   56px whatever box-sizing does.

   HUNG, NOT INDENTED. There is ~191px of free gutter left of this column;
   indenting would drop the measure 554 -> 482px, about 13%, adding lines to
   the longer items. -80px puts the disc's right edge 24px clear of the text.

   TOP-ALIGNED TO THE COPY, which is why :first-child needs its own value —
   it carries padding-top:0 while the others carry 26px, mirroring the
   existing li:first-child rule directly above. */
.wl-o2-list .wl-num{
  position:absolute;left:-80px;top:26px;
  width:56px;height:56px;
  display:flex;justify-content:center;align-items:center;
  font-size:28px;font-weight:700;line-height:1;
  border-radius:50%;
  background:var(--gold);
  color:var(--ink);
  box-shadow:inset 0 0 0 1.5px var(--ink);
}
.wl-o2-list li:first-child .wl-num{top:0}

/* ---------------------------------------------------------------------
   BAND 3 — CLOSING COPY LEFT, THE CTA RIGHT

   THE BUTTON IS components/buttons.css's .btn, THE HEADER'S OWN
   COMPONENT, UNMODIFIED. No button styling is authored here — only the
   cell it sits in. .cta-line, which this element used to be, is left
   entirely alone and is still in use elsewhere on the page.

   .btn ON THIS GROUND WAS CHECKED RATHER THAN ASSUMED, because there is
   a standing project finding that .btn may never sit on .band-plum:
   --pill-hover measures 2.8600 there against 1.4.11's 3.0. Band 3 is
   --ground-page, where --pill-hover measures 4.8922, and the label is
   --on-pill on --pill-hover at 5.1858. Both clear. The foreclosure is
   about the plum ground specifically and does not reach this band.
   --------------------------------------------------------------------- */
.wl-o3 > .in{
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  column-gap:5vw;
  row-gap:0;
  align-items:center;
}
.wl-o3-copy{
  font-family:var(--serif);
  font-size:19px;line-height:1.7;
  color:var(--on-page-body);
  max-width:50ch;
}
.wl-o3-cta{justify-self:end}

/* =====================================================================
   §6 — SPLIT INTO A COPY BAND AND A GOLD QUOTE BAND (9h)

   8v's two-column treatment of #proof is GONE, not overridden: the
   section no longer exists in that shape. It was h2 + paragraph + CTA in
   column 1 and the quote spanning column 2; it is now two sibling
   sections, each single-column at every width.

   #proof KEEPS ITS ID, ON THE COPY BAND. It is not an anchor target —
   the page's only in-page anchors are #the-model and #join — but the id
   is the section's identity in every prior checkpoint and moving it to
   the other half would silently invalidate those references.
   ===================================================================== */

/* ---------------------------------------------------------------------
   BAND A — COPY, ON THE PAGE GROUND

   --ground-alt, TAKEN IN 9i TO CLOSE AN ADJACENCY 9h OPENED. 9h built
   this band on --ground-page and recorded that it broke the band ground
   sequence approved 2026-08-08: NO TWO ADJACENT BANDS SHARE A GROUND.
   §5 above is the page ground and so was this, so the two merged into
   one continuous paper region with no boundary between them. 9h argued
   that was worth it to leave GOLD as the only ground change here; the
   director took the flag instead. Cream restores the property.

   IT IS AVAILABLE ONLY BECAUSE 9f MOVED #ecosystem OFF IT. Until then
   cream was §4's ground and using it here would have stuttered against
   it. Nothing else on this page carries --ground-alt now.

   2.65 dL* FROM PAPER IS THE WHOLE STEP AND IT IS DELIBERATE — the same
   marginal distinction 9e took for #origin's band 2, and the reason the
   sequence reads paper / cream / gold rather than paper / paper / gold.

   NO TEXTURE ON THIS BAND. It leaves the texture as the gold band's own
   signal.

   THE PARAGRAPH LEAVES .body FOR THE SERIF. .body is 16.5px sans at
   --on-page-body with a 56ch cap; the mock sets this in the serif at a
   larger size directly under the heading. It takes its own class rather
   than overriding .body, which is shared with every other body paragraph
   on the page.
   --------------------------------------------------------------------- */
/* --on-page, NOT --on-page-body, AND THAT IS THE MERGE'S ONE REAL HAZARD.
   Every other body paragraph on this page is --on-page-body. Measured on
   the rendered gold ground rgb(225.4,177.2,69.9) it reads **4.3276** and
   FAILS the 4.5 small-text threshold by 0.1724 — with nothing visible to
   show for it. --on-page reads 7.4916. Carrying the page's usual body
   colour onto this band would have shipped a silent SC 1.4.3 failure. */
.wl-proof-lede{
  margin-top:26px;
  font-family:var(--serif);
  font-size:21px;line-height:1.65;
  color:var(--on-page);
  max-width:56ch;
}
/* The lede's closing sentence, promoted to its own paragraph and bolded.
   Same colour, same measure — only weight and division changed. */
.wl-proof-close{
  margin-top:20px;
  font-family:var(--serif);
  font-size:21px;line-height:1.65;font-weight:700;
  color:var(--on-page);
  max-width:56ch;
}

/* ---------------------------------------------------------------------
   BAND B — THE FIRST GOLD GROUND ON THIS SITE

   --gold is used as a GROUND here for the first time. That is a
   reference swap and not a new value: no token was added, and --gold
   already exists as a foreground token used on four other bands.

   THE IDENTITY CHECK WAS RUN BEFORE ANYTHING WAS BUILT, because 9f found
   --ground-fill and --plum holding one value and pulling a name-written
   prohibition onto a differently-named band. Every LAYER-1 and role
   token was resolved through the live cascade and compared pairwise:
   --gold is rgb(240,184,63) and is THE ONLY TOKEN IN THE PALETTE WITH NO
   ALIAS. Nine other collision groups exist — --ink/--plum/--ground-dark/
   --ground-fill/--on-page/--on-alt/--on-field are all one value, as are
   --accent and --pill. Gold shares with nothing, so no standing ruling
   reaches this band by value.

   THERE IS NO --on-gold AND ONE WAS NOT AUTHORED. Foregrounds here
   reference existing tokens: --on-page for the quote and attribution,
   --accent for the decorative mark, --ground-fill / --on-fill for the
   button. The band sets `color:var(--on-page)` once and the type
   inherits it.
   --------------------------------------------------------------------- */
.wl-proof-quote-band{
  background:var(--gold);
  color:var(--on-page);
  padding:110px 34px;
}
/* TWO COLUMNS, PORTRAIT LEFT, QUOTE RIGHT (9i) — THE ADDITIVE CHANGE 9h
   NAMED. 9h shipped this centred, with no reserved cell, because the
   client original had not arrived; the note there said the portrait would
   change the band from a centred block to a two-column one rather than
   fill a slot left open. That is what happened.

   THE PORTRAIT COLUMN IS FIXED AND THE QUOTE TAKES THE REST. A fixed
   300px track matches the display size the other two portraits already
   use, so the quote's measure is whatever remains — which is why the
   quote re-wraps and why its line counts are reported before and after.
   align-items:center hangs the portrait against the quote's optical
   middle; the quote block is the taller element at every width. */
.wl-proof-quote-band > .in{
  max-width:1040px;
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  column-gap:5vw;
  align-items:start;
  text-align:left;
}
.wl-proof-main{min-width:0}
.wl-proof-q{min-width:0}

/* THE CIRCLE IS CSS AND THE FILE IS UNTOUCHED. border-radius on the
   wrapper plus overflow:hidden, with object-fit:cover on the image —
   the same construction quote-block.css uses for McCanna and Patel, and
   the reason the asset on disk is still the client's 800x1000 original
   byte for byte.

   DISPLAY STATE, recorded in the same form as the other two:

     McCanna       500x500  at 300 CSS px   1x 1.67   2x 0.83  SHORT at 2x
     Patel         200x200  at 300 CSS px   1x 0.67   2x 0.33  SHORT at 1x
     Childs        800x1000 at 300 CSS px   1x 2.67   2x 1.33  clears both

   THIS IS THE FIRST PORTRAIT ON THE PROJECT WITH HEADROOM AT DPR 2. The
   ceiling quote-block.css records — "if a later revision wants more than
   250, stop: at DPR 2 that exceeds the native file" — is a fact about
   McCanna's 500px file, not a rule about portraits. At 800px this one
   would still clear 300 CSS px at DPR 2 with 1.33x to spare. DO NOT read
   that across; re-derive per file.

   object-position IS PRESENTATION. cover on a square box windows 800 of
   the 1000 rows; at the default centre that window is rows 100-900 and
   the top of the head falls outside it. Anchoring to the top selects
   rows 0-800 instead. It changes WHICH pixels are visible, never what
   they are. */
/* min(300px,100%) + aspect-ratio, NOT a fixed 300x300 SQUARE. A flat
   300px overflowed at 320: the .in there is 252px, so the circle ran 48px
   past its own container and 14px past the viewport — measured, and it
   fired the unit's overflow stop on the first build. The narrow-width
   note below reasoned about not STRETCHING the circle and never checked
   that 300 is wider than the column it sits in.

   aspect-ratio IS WHAT HOLDS THE CIRCLE ROUND, not the height. With a
   width that can shrink, a fixed height would give an ellipse at 320;
   aspect-ratio:1 makes the height follow the width. (This project has
   already recorded that the flex half of the usual anti-distortion
   pattern is inert outside a flex item and that height+aspect-ratio is
   what actually holds an aspect — same lesson, other direction.)

   THE DISPLAY STATE IS THEREFORE A CEILING, NOT A CONSTANT: 300 CSS px
   wherever the column allows it, shrinking to the column below that.
   Shrinking only ADDS resolution headroom — at 320 the box is 252px and
   the 800px source gives 3.17x at 1x and 1.59x at 2x, against 2.67x and
   1.33x at the full 300. */
/* THE PORTRAIT RULES ARE GONE WITH THE PORTRAIT. T02 line 181 rules that
   no image of the quoted executive is to be sourced, generated, suggested
   or slotted; the 9i placement was a logged deviation against that line and
   this unit retires it. The asset stays in src/ and simply stops being
   referenced, so build.mjs no longer copies it — absence from dist/ is the
   8r precedent and is not a deletion.

   IN ITS PLACE, THE ONVIDA MARK, BOTTOM RIGHT OF THE QUOTE COLUMN.
   Client-supplied artwork, 1280x530, measured 100% rgb(255,255,255) across
   53,767 opaque sampled pixels — white on transparent.

   **WHITE ON THIS GROUND MEASURES 1.9798 AND THAT NUMBER IS RECORDED HERE
   SO IT IS NOT REDISCOVERED AS A DEFECT.** Gold is saturated but LIGHT
   (luminance 0.5317), so a white mark on it is faint. It is a LOGOTYPE and
   logotypes are exempt from SC 1.4.11 — the same exemption 8t recorded for
   the five wrap marks. Director ruling: it ships as supplied. Do not
   recolour it, do not add a plate behind it, and do not read 1.9798 as a
   failure to be fixed. */
/* THE FOOTER LOCKUP — NAME LEFT, MARK RIGHT, ONE ROW.
   ALIGNED TO THE BOTTOM, NOT THE BASELINE OR THE CENTRE. The attribution
   is two lines and the mark is a single wide glyph-block; there is no
   shared baseline between a two-line text block and an image, and centring
   would float the mark against the gap between the two lines. Bottom
   alignment puts the mark's lower edge on the attribution's last-line
   bottom, which is the edge a reader already perceives as the block's
   base. Measured gap is reported per width in the unit notes.

   IT WRAPS RATHER THAN CRUSHES. flex-wrap means the mark drops beneath the
   name when the row can no longer hold both, instead of the two competing
   for a shrinking track. Below that point the mark aligns left with the
   text rather than hanging off the right edge of nothing. */
.wl-proof-lockup{
  margin-top:30px;
  display:flex;flex-wrap:wrap;
  align-items:flex-end;
  justify-content:space-between;
  gap:24px 32px;
}
.wl-proof-lockup .attrib{flex:0 1 auto;min-width:0}
/* THE WIDTH IS ON THE WRAPPER, NOT THE IMAGE, AND THAT IS A BUG FIX.
   With `flex:0 0 auto` on the wrapper and the width on the <img>, the
   wrapper's max-content contribution is the image's INTRINSIC width —
   1280px — even though the image itself renders at 140. The wrapper then
   measured 1280 wide and pushed 596px of horizontal overflow onto the
   document at 1440, while every element I inspected looked correct because
   the IMG was the right size. Sizing the wrapper makes the flex basis
   definite and the image simply fills it. */
.wl-proof-logo{flex:0 0 auto;width:min(140px,45%)}
.wl-proof-logo img{
  display:block;
  width:100%;
  height:auto;
}

/* THE QUOTE MARK FLIPS TO --accent, AND IT IS FAINT BY INTENT.
   quote-block.css sets blockquote::before to --gold at 96px. On a gold
   ground that is invisible. --accent measures 2.3083 bare / 2.1048 inked
   here — below 3.0, and DELIBERATELY NOT GATED: the mark is decorative,
   the quotation is marked semantically by <blockquote> and reads
   correctly with the glyph absent, so it is neither a UI component nor a
   graphical object required to understand the content. Director ruling,
   with the figure recorded rather than compensated for. Do not "fix" it. */
/* THE MARK MATCHES THE REFERENCE BAND'S SIZE AND KEEPS THIS BAND'S
   COLOUR. utilities.html's .band-slate.u-quote overrides the shared 96px
   to 160px / line-height .42 / margin-bottom 10px; those three move
   together and are taken verbatim. The COLOUR does not transfer — that
   band's mark is --gold on violet, this one is --accent on gold at
   2.3083, ruled decorative in 9h. Scaling a decorative mark changes its
   size, not its ratio, and does not make it informational. */
.wl-proof-quote-band blockquote::before{
  color:var(--accent);
  font-size:160px;line-height:.42;margin-bottom:10px;
}

/* THE QUOTE. 8v RULED 26px ON A 42ch MEASURE AND THAT RULING'S BASIS HAS
   MOVED. It existed because Childs ran 86 words against McCanna's 25 and
   Patel's 28, and the shipped clamp rendered the band ~1,512px tall. 9h
   removes the opening sentence: 74 words -> 49. The length argument is
   weaker by a third, and with no portrait column the quote is the band's
   only object, so it carries more size than it did sharing a grid.

   30px IS STILL WELL ABOVE 8v's CLIFF. That ruling's hard floor was 24px
   — below it the quote reclassifies from LARGE to SMALL and the
   threshold jumps to 4.5. Here it clears 4.5 anyway at 7.4916, so the
   floor is no longer load-bearing FOR CONTRAST on this ground; it is
   still respected because the ruling was about reading, not only ratio.

   SCOPED SO quote-block.css STAYS BYTE-IDENTICAL. That sheet's
   blockquote, blockquote::before and .attrib selectors are UNSCOPED and
   it is linked by three pages; editing it would move the homepage and
   utilities quote bands. These selectors are (0,1,1) and (0,2,0) against
   its (0,0,1) and (0,1,0), so they win on specificity and link order
   cannot undo it. */
/* THE FONT-SIZE OVERRIDE IS GONE, AND THAT IS HOW THE SIZE MATCHES.
   components/quote-block.css already sets blockquote to
   clamp(24px,3.2vw,40px) — which IS the reference band's sizing, because
   that band overrides the mark and the portrait but never the quote. So
   the match is made by DELETING a rule rather than by copying a number,
   and the two bands cannot drift apart at any width: they are the same
   declaration, not two equal ones.

   9h's clamp(24px,2.4vw,30px) is therefore retired. Its 8v-derived 24px
   floor survives inside the component's own clamp, which has the same
   floor — below 24px the quote reclassifies LARGE -> SMALL. On this
   ground that is harmless (7.4916 clears 4.5) but the floor was a reading
   ruling as well as a contrast one, and it still holds.

   max-width STAYS AT 38ch AND STOPS BINDING AT THE WIDE END. The
   component's own cap is 26ch; 9h widened it here and that stands. At
   40px, 38ch is about 883px against a 682px track, so above roughly
   1000px the TRACK governs the measure and the cap does not — the flip
   this unit expected. Measured per width in the unit report. */
/* CAPPED AT 25px, 2026-08-12. The component's clamp(24px,3.2vw,40px) is
   re-declared here as clamp(24px,3.2vw,25px): the CEILING drops 40 -> 25
   and THE 24px FLOOR IS DELIBERATELY UNTOUCHED. Below 24 the quote
   reclassifies LARGE -> SMALL and is judged at 4.5 instead of 3.0 — on
   this ground 7.4916 clears both, so the symptom would be invisible, but
   the floor was a reading ruling as well as a contrast one and it stands.
   Same trap as the about-page heading at its 28px floor. */
.wl-proof-quote-band blockquote{
  font-size:clamp(24px,3.2vw,25px);
  max-width:38ch;
  color:var(--on-page);
}

/* THE ATTRIBUTION RESTYLE IS PRESENTATIONAL ONLY. quote-block.css sets
   .attrib mono / 10.5px / .14em / uppercase / --white; the mock sets
   italic serif, sentence case, small, dark. Every one of those is a
   rendering property — text-transform:uppercase does NOT alter
   textContent — so the string is byte-identical before and after and is
   verified as such in the unit report, not asserted.

   IT SCALES WITH THE BAND AND ITS FACE, STYLE AND CASE DO NOT MOVE (9j).
   17px -> 22px, the same 1.333 factor the quote takes going 30 -> 40, so
   the attribution keeps its established relationship to the quote at
   about 55%. THE REFERENCE BAND'S OWN RATIO WAS NOT TAKEN: its
   attribution is 10.5px against a 40px quote, 26%, because it is a mono
   uppercase micro-label. Applying 26% to italic serif sentence case
   would give 10.5px and be unreadable, and the italic-serif treatment is
   a deliberate 9h decision that this unit was told not to match away.
   Reported as a choice rather than made silently.

   22px KEEPS IT SMALL TEXT. The large-text boundary at weight 400 is
   24px, so the threshold stays 4.5 and the figure stays 7.4916.

   --white IS ABANDONED HERE AND THAT IS FORCED. quote-block.css carries
   a documented exception setting the attribution in --white because cream
   reads 4.3009 on the slate band. On gold, white measures 1.8052. The
   exception is a fact about the SLATE band and does not travel; this band
   takes --on-page at 7.4916. */
.wl-proof-quote-band .attrib{
  margin-top:0;
  font-family:var(--serif);
  font-size:17px;
  font-style:italic;
  letter-spacing:normal;
  text-transform:none;
  color:var(--on-page);
}
/* TWO LINES, AND THE BREAK IS TYPOGRAPHY RATHER THAN COPY. The source
   carries ONE space between the two spans, so the cite's textContent still
   joins to the original attribution byte for byte — sha-verified. Making
   the spans block-level breaks the line visually without touching the
   string; a <br> would have done the same but puts the break in the copy
   rather than in the sheet. The break falls after the comma so that the
   join needs no punctuation of its own — see T02 line 179. */
.wl-proof-quote-band .attrib-line{display:block}

/* THE CTA IS A DARK BUTTON, AND NO ACCENT-BEARING FORM WOULD HAVE WORKED.
   Measured on this ground against SC 1.4.11's 3.0 before building:

     .btn with --accent fill        2.3083 bare / 2.1048 inked   FAILS
     .btn with --pill-hover fill    2.8727 bare / 2.6194 inked   FAILS
     .cta-line, --accent text       2.3083 — and as 19px/700 it is
                                    LARGE text, so its threshold is
                                    also 3.0                     FAILS

   So the site's CTA convention has no compliant form on gold at all —
   there was no safe fallback to ship while the ruling was taken.
   --ground-fill fill measures 7.4916 with an --on-fill label at 13.0839.
   Director ruling; logged as deviation 17. This is a departure from the
   mock AND from the site convention, and it is a ruling, not an omission.

   THE COMPONENT IS buttons.css's .btn AND ONLY ITS FILL IS SWAPPED. Shape,
   padding, radius, weight and hover all come from the component; this
   rule changes two colour references and nothing else. */
/* ####################################################################
   THE CTA IS VIOLET NOW — DIRECTOR OVERRIDE OF 9h, 2026-08-12.
   9h's MEASUREMENTS STAND AND THIS OVERRIDES ITS CONCLUSION, NOT ITS
   NUMBERS. Re-measured today on the rendered ground and unchanged:
   --accent fill 2.1048, --pill-hover fill 2.6194, both under 3.0. 9h read
   that as "no violet CTA can exist here" and shipped a dark button. This
   unit adds a BORDER, which moves the boundary off the fill entirely.

     --ink border on the band ground      7.4916   <- carries the boundary
     --ink border on the --pill-hover fill  2.8600
     --pill-hover fill on the ground        2.6194  <- no longer load-bearing
     --on-pill LABEL on the fill            5.1858  <- the gating number

   THE FILL IS --pill-hover AND THAT IS FORCED BY THE LABEL, NOT CHOSEN.
   The label is 14.5px at weight 640 — 14.5 is under 18.66 and 640 is under
   700, so it classifies SMALL and is judged at 4.5 whatever the fill. On
   --accent the white label reads 4.1669 and FAILS by 0.3331. On
   --pill-hover it reads 5.1858 and clears. **--accent is not available for
   this button at this label size, and resizing the label was expressly
   barred.** So the button is buttons.css's own .btn, unmodified in fill
   and colour, plus a border — which is also why no new token was needed.

   THE 2.8600 BORDER-ON-FILL FIGURE IS THE SAME PAIR AS THE STANDING
   .band-plum RULING, INVERTED. --ink and --plum are one value, so
   "--pill-hover on plum 2.8600" and "--ink on --pill-hover 2.8600" are the
   same measurement read from either side. It is an internal edge, not the
   component boundary, and the boundary is the 7.4916.
   #################################################################### */
.wl-btn-edge{border:2px solid var(--ink)}
.wl-proof-cta{margin-top:34px}

/* =====================================================================
   §4 #ecosystem — FILLED DARK GROUND, TWO COLUMNS, TWO LISTS (9f)

   THIS CLOSES THE 9e SEAM. Between 9e and 9f, #origin's band 2 and this
   section were both --ground-alt and the page read paper / cream / paper
   / cream with #origin's band 3 as a thin strip between two creams.
   #origin band 2 STAYS SAND. This band goes dark. Do not close the seam
   from the other end.
   ===================================================================== */

/* ---------------------------------------------------------------------
   THE GROUND IS ONE DECLARATION AND THAT IS A REQUIREMENT, NOT A STYLE

   DIRECTOR RULING: the dark repeat against #fragmentation is PROVISIONAL
   and will be judged from staging, not from description. The reversal
   must therefore be a ONE-LINE change. Everything below inherits — the
   paragraphs, the list items and the closing line all take `color:
   inherit`, and nothing else in this section names a ground or a
   foreground token. Swap the two references on the line beneath this
   comment and the whole band follows. If it is swapped, that is Lane A.

   DO NOT reintroduce a foreground token on any child. The moment one
   child names --on-fill directly, the reversal stops being one line and
   nothing reports that it has.

   --ground-fill IS THE SEMANTICALLY CORRECT REFERENCE AND THAT IS THE
   WHOLE ARGUMENT — IT IS NOT A COLOUR DECISION. --ground-fill and
   --ground-dark resolve to the SAME VALUE today: both rgb(41,38,49),
   L* 15.8985, dL* 0, dE76 0, and identical again at 0 once each is
   composited with this page's texture. #fragmentation and this band are
   PIXEL-IDENTICAL right now. That was measured before this unit was
   built and ruled on rather than designed around.

   The name is the decision. tokens.css holds --ink and --plum as two
   names for one value precisely so they can diverge, and reserves --plum
   for "the problem band's ground and nothing else". This is a filled
   dark band, not the problem band, so it must NOT follow a future plum
   move. Same reasoning 9c used for #origin's band 2.

   THE REPEAT IS ACCEPTABLE BECAUSE THE FLAT GROUND IS A STAND-IN. The
   design lead's mock puts a PHOTOGRAPH behind this band; the asset does
   not exist and is not in scope. Once it lands it differentiates this
   band from #fragmentation on its own and the question disappears. That
   is the reason the provisional state is tolerable — record it, because
   a reader who does not know it will read the repeat as an oversight.

   THE VALUE IDENTITY IS A PATTERN NOW, NOT TWO INCIDENTS. It bound
   TWICE in this one unit. First it invalidated the premise of the ground
   ruling — three dark bands are fine because they do not touch — when
   the real problem was that two of them are pixel-identical; that cost a
   director ruling on band repetition. Then it reached the CTA: the
   standing bar on .btn over .band-plum applies here by value, and the
   button promotion this unit was briefed to make was measured and
   reverted at 2.8600 against 3.0.

   THE GENERAL FORM, WHICH IS WHAT TO CARRY FORWARD: **anything that
   reaches `.band-plum` by value now reaches `#ecosystem` too.** Every
   finding, prohibition and measured figure recorded against the plum
   ground applies to this band unchanged until the two tokens diverge.
   Search the project's plum rulings before adding anything to this band,
   and do not trust a name to tell you which band you are on.

   THE PREMISE THIS RULING REPLACED IS RECORDED SO IT IS NOT RE-DERIVED.
   The brief argued three dark bands were fine because they do not touch
   — paper / plum / paper / fill / paper / plum / paper alternates. That
   was answering the wrong question. Adjacency was never the issue; two
   of the three being indistinguishable is.
   --------------------------------------------------------------------- */
#ecosystem{background:var(--ground-fill);color:var(--on-fill)}

/* ---------------------------------------------------------------------
   THE TEXTURE, THIRD INSTANCE, IDENTICAL TERMS

   Same treatment as #fragmentation (8u) and #proof (8v), which are
   byte-for-byte identical to each other. Every longhand restated,
   prefixed and unprefixed: setting mask-size alone leaves cover /
   no-repeat / center surviving underneath and paints a single 18px tile.

   NOT MERGED INTO A SELECTOR LIST WITH THE OTHER TWO, for the reason 8v
   records: #proof re-grounds to the deep blue at some point and its paint
   token has to be re-derived there while the other two must not move.
   Three rules means that change touches one of them.

   THE .10 / --slate FIGURE TRANSFERS HERE AND ONLY BECAUSE EVERY TERM
   DOES: same ground value, same paint token, same artwork, same tile.
   It is not carried across on resemblance — the standing finding is that
   texture opacity does NOT transfer between bands in either direction.

   MASKS FAIL SILENTLY UNDER file://. This is verified over http and by
   pixel sample, never by reading the declaration.
   --------------------------------------------------------------------- */
#ecosystem{position:relative}
#ecosystem::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;
}
/* The copy rides above the overlay — it is a later sibling in paint
   order and would otherwise paint over the text. */
#ecosystem > .in{position:relative;z-index:1}

/* ---------------------------------------------------------------------
   LAYOUT — HEADING FULL WIDTH, THEN TWO COLUMNS

   The heading spans both tracks and the two wrapper divs take one each,
   so the grid has three items and no explicit rows. No row-gap is
   inherited here: this container is NOT .band-plum, so bands.css's
   `gap:5vw` shorthand never reaches it — measured `normal`, unlike
   #fragmentation and #proof which do inherit it. Verified, not assumed.
   --------------------------------------------------------------------- */
#ecosystem > .in{
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  column-gap:5vw;
  align-items:start;
}
.wl-eco-left{grid-column:1}
.wl-eco-right{grid-column:2}
/* THE HEADING IS A CHILD OF THE LEFT COLUMN, NOT A GRID ITEM (9g). It no
   longer spans both tracks, so `grid-column` is gone rather than set to a
   single track — a placement property on a non-grid-item is inert, and
   leaving it would read as though it still governed something.

   BOTH COLUMNS START LEVEL AND NOTHING IS TUNED TO ACHIEVE IT. The grid
   has exactly two items now and `align-items:start` puts both boxes on the
   row's start edge; the heading carries no margin-top and the right
   column's first label is already zeroed. The alignment is therefore a
   property of the structure and holds at every width by construction —
   no offset, no negative margin, no transform. Measured 0.00px box delta
   at both two-column widths.

   FIRST-LINE GLYPHS ARE NOT FLUSH, AND THAT IS LEADING, NOT A DEFECT. The
   46px heading and the 18px label have different half-leading, so their
   first ink sits about 3px apart inside boxes that start at the same y.
   Making the GLYPHS flush would need a per-size offset tuned to two fonts
   at two sizes — the magic number this unit was told to refuse. Box tops
   are what is aligned; both figures are in the unit report.

   THE WRAP CHANGED DELIBERATELY. In a 554px column instead of the full
   1180px, the heading sets 4 lines at 1440 where it set 3. That is the
   mock. Do not reintroduce the full-width measure to restore the old
   wrap. */
.wl-eco-left h2{max-width:20ch;margin-bottom:44px}

/* Serif, matching #origin's register. color:inherit is load-bearing —
   see the ground block above. .body is deliberately NOT used: base.css
   paints it --on-page-body, a LIGHT-ground body colour, and on this
   ground that would need its own override, which is exactly the extra
   foreground declaration the one-line rule forbids. */
.wl-eco-p{
  font-family:var(--serif);
  font-size:19px;line-height:1.7;
  color:inherit;
  max-width:46ch;
}
.wl-eco-p + .wl-eco-p{margin-top:20px}
.wl-eco-cta{margin-top:32px}
/* buttons.css gives .cta-line its own margin-top:22px, which would stack
   with the wrapper's and put the CTA 54px below the paragraph. Zeroed here
   so the gap is ONE number in ONE place. The component is not otherwise
   touched — this band uses .cta-line exactly as the two plum bands do. */
.wl-eco-cta .cta-line{margin-top:0}

/* THE GOLD LABELS SIT BELOW THE BOLD LARGE-TEXT BOUNDARY DELIBERATELY.
   18px/700 is under 18.66px, so these are SMALL text judged at 4.5 —
   and --gold on this composited ground measures 7.4336, which clears it
   with room. The brief originally floored these at 18.66px on a figure
   of 3.2181; that figure is --accent's on this ground, not --gold's, and
   the floor was struck once the transposition was found. The mock's
   hierarchy — label smaller than the items beneath it — is available
   because gold is genuinely strong on a dark ground.

   GOLD IS UNUSABLE ON EVERY LIGHT GROUND ON THIS SITE: 1.7030 on paper,
   1.5925 on cream, 1.8052 on white, against any threshold. This
   treatment can only ever live on a dark band. If this band is ever
   reverted to a light ground the labels must stop being gold in the same
   change — that is the one thing the one-line reversal does NOT carry. */
.wl-eco-label{
  font-size:18px;font-weight:700;line-height:1.4;
  color:var(--gold);
  margin-top:34px;
}
.wl-eco-right > .wl-eco-label:first-child{margin-top:0}

.wl-eco-list{
  list-style:disc;
  margin:14px 0 0;padding:0 0 0 22px;
  color:inherit;
}
.wl-eco-list li{
  font-size:21px;font-weight:400;line-height:1.5;
  margin-top:8px;
}
.wl-eco-list li:first-child{margin-top:0}

/* Light, not gold — the closing line is the band's conclusion and gold
   would read it as a third label. */
.wl-eco-close{
  margin-top:36px;
  font-size:21px;font-weight:700;line-height:1.5;
  color:inherit;
  max-width:34ch;
}

@media(max-width:920px){
  /* ONE COLUMN BELOW 920. The grid placements above must be RELEASED, not
     merely overridden column-wise: the explicit grid-row values would
     otherwise keep §6's CTA pinned to row 3 beneath empty cells, §3's
     heading stranded beside its own paragraphs, and §2's heading spanning
     three rows it no longer shares with anything. A MEDIA QUERY ADDS NO
     SPECIFICITY, so every selector is restated in full rather than
     relying on being later in the file.

     Stacked order is DOM order, which is T02's order: §2 runs heading and
     three paragraphs; §3 runs heading, five paragraphs, CTA; §6 runs
     heading, paragraph, quote, CTA.

     §2's TYPE IS NOT RELEASED HERE, ONLY ITS PLACEMENT. The 18.5/1.78
     prose, the 700 on the closing paragraph and the heading clamp all
     stay: they are the section's register at every width, and the clamp's
     own 34px floor is what handles narrow viewports. Only the two-column
     geometry is a wide-viewport decision. The first paragraph's zeroed
     margin-top IS released — at one column the heading sits above the
     prose rather than beside it, and the 20px is the rhythm again. */

  /* §3's BANDS 2 AND 3 GO TO ONE COLUMN (9c). The 8v releases for
     `.wl-origin .in` that used to sit here are GONE, not overridden:
     that grid no longer exists. Band 1 is centred at every width and has
     nothing to release. Band 3's CTA stops being end-justified — at one
     column `justify-self:end` would strand the button against the right
     gutter under left-aligned copy. */
  .wl-o2 > .in,
  .wl-o3 > .in{grid-template-columns:minmax(0,1fr);column-gap:0}
  .wl-o2-lede{max-width:none;margin-bottom:34px}
  .wl-o3-copy{max-width:none;margin-bottom:30px}
  .wl-o3-cta{justify-self:start}
  /* §4 GOES TO ONE COLUMN (9f). The heading's `grid-column:1 / -1` is
     harmless at one column — -1 is still the last line — but it is
     restated anyway so the section's placement is readable in one place
     rather than half here and half above. The two wrapper divs stack in
     DOM order: left column then right, which is heading, paragraphs,
     CTA, then the lists. */
  #ecosystem > .in{grid-template-columns:minmax(0,1fr);column-gap:0}
  /* The heading moved into .wl-eco-left in 9g, so the release follows it
     there. `#ecosystem > .in > h2` no longer matches anything and would
     have failed silently — a selector that stops matching reports nothing. */
  .wl-eco-left h2{margin-bottom:32px}
  .wl-eco-left,
  .wl-eco-right{grid-column:1}
  .wl-eco-right{margin-top:40px}

  /* §6's 8v grid is GONE, not released — 9h split the section into two
     bands, each single-column at every width, so there is no placement
     left to undo. Rules restating it here would have matched nothing,
     which is a silent no-op rather than an error. */
  /* THE PORTRAIT STACKS ABOVE THE QUOTE BELOW 920 (9i), which is the
     breakpoint every other two-column release on this page uses. One
     column, portrait first, matching DOM order. It CENTRES rather than
     stretching, and its width is capped by min(300px,100%) above so it
     can never exceed the column — see that block for the overflow this
     replaced. */
  .wl-proof-quote-band{padding-left:34px;padding-right:34px}
  .wl-proof-quote-band > .in{grid-template-columns:minmax(0,1fr);column-gap:0;row-gap:48px}
  .wl-proof-quote-band blockquote{margin-inline:auto}
  .wl-proof-lockup{justify-content:flex-start}
}

/* ---------------------------------------------------------------------
   THE CONNECTOR STACKS BELOW 768, AND THE SEGMENTS ARE SUPPRESSED

   THE CHOICE WAS ROTATE-TO-VERTICAL OR SUPPRESS, AND THIS IS SUPPRESS.
   Rotating them would mean a SECOND geometry: stacked, each segment has
   to span from one dot centre to the next dot centre, and the three
   stacked nodes are not equal in height — node 3 carries a subordinate
   line the other two do not. That length is a function of the node above
   it, so it cannot be expressed as the left/right percentage pair the
   horizontal form uses, and it would need either a per-node height or a
   measurement in script. Suppression is one declaration and cannot
   produce the orphaned horizontal fragment the brief rules out. The
   three dots and their labels still read as three ordered nodes; the
   list is an <ol>, so the order is in the document and not only in the
   picture.

   THE BREAKPOINT IS 767, NOT 768, SO THAT 768 IS STILL THREE-ACROSS.
   At 768 the .in is 700px and each third is 233px, which the labels
   carry. Below that they do not.

   THE WHOLE RAIL GOES, NOT JUST THE SEGMENTS, AND THE DOTS MOVE ONTO THE
   LABELS. Keeping the rail and hiding only its segments would leave three
   dots stacked in a column of their own ABOVE the three labels, related to
   them by nothing. Each label carries its own dot instead, directly above
   its own words, which is the same reading the wide layout gives. The rail
   is aria-hidden and decorative at both widths, so nothing announced
   changes when it is dropped.

   THE DOT IS DECLARED TWICE — once on .wl-cx-dot and once here. That is
   deliberate rather than a missed abstraction: they are different
   elements doing the same job at different widths, and folding them into
   a shared selector would couple the rail's reveal-gated dot to a marker
   that must be visible with no script at all. */
@media(max-width:767px){
  .wl-conn-rail{display:none}
  .wl-conn-labels{grid-template-columns:minmax(0,1fr);row-gap:30px}
  .wl-node{text-align:left;max-width:none;margin-inline:0}
  .wl-node::before{
    content:"";display:block;
    width:var(--dot);height:var(--dot);border-radius:50%;
    background:var(--gold);margin:0 0 14px;
  }
}

/* ---------------------------------------------------------------------
   REDUCED MOTION — THIS SHEET'S OWN BRANCH, RESTATING ITS OWN SELECTORS

   base.css's reduced-motion block restates `.rv` and nothing else. The
   connector is a reveal this file defines, so it needs its own branch
   here: A MEDIA QUERY ADDS NO SPECIFICITY, and `.wl-conn-rail.on .wl-cx-dot`
   is (0,3,0) against a bare `.wl-cx-dot`'s (0,1,0) — so the settled state
   below is restated at the SAME shape as the rule it has to beat, not at
   a weaker one, and wins on source order.

   ALL FIVE ELEMENTS ARE PRESENT IN THEIR FINAL STATE, WITH NO SEQUENCE
   AND NO DRAW. The delays are zeroed as well as the transitions: a
   transition-delay with no transition is inert today and would come back
   to life the moment anything re-introduced a transition. */
@media(prefers-reduced-motion:reduce){
  .wl-cx-dot,
  .wl-conn-rail.on .wl-cx-dot{
    opacity:1;transform:none;transition:none;transition-delay:0s;
  }
  .wl-cx-seg,
  .wl-conn-rail.on .wl-cx-seg{
    clip-path:inset(0 0 0 0);transition:none;transition-delay:0s;
  }
}

/* =====================================================================
   MOVED FROM css/pages/home.css BY R1 (2026-08-13)

   These three groups style the two sections that R1 moved onto this page
   from index.html — the dark dot-field band (#problem) and the pivot band
   (.pivot), which now sit between .wl-hero and #fragmentation.

   THEY WERE PORTED, NOT SHARED. Linking home.css here was expressly ruled
   out: that sheet also carries the homepage hero, the stat band and the
   utility rows, and a <link> would have imported all of them. Only rules
   that NO surviving index.html element still matches were moved — verified
   by element on the built tree, never by grepping selector text.

   THE KEYFRAMES CAME WITH THEM. fwIn/fwOut/fwTrav/fwColl and sorbit had no
   consumer outside this dot field, and this sheet defined no @keyframes at
   all, so nothing collides. Animation names are GLOBAL once a sheet loads —
   check for a clash before adding another.

   THE TWELVE DOTS MUST STAY IN ONE FLAT GROUP. The transition-delay and
   sorbit rules below select by :nth-of-type within the parent, so splitting
   the circles across two <g> parents by colour silently hands three dots
   another three dots' timings. That already happened once.
   ===================================================================== */

/* the copy column rides above the overlay. WITHOUT THIS the ::before
   paints over the text — it is a later sibling in paint order. */

/* ---------------- PROBLEM BAND — copy fragments into the dot field ----
   The words are decorative-transitional only. The settled state is the
   scattered dot field. Fragments stay inside the left column. */

.dots .fwrap{
  position:absolute;inset:0;
  display:flex;align-items:center;justify-content:center;
  flex-wrap:wrap;align-content:center;gap:.06em .28em;text-align:center;
  font-family:var(--serif);font-weight:700;
  font-size:clamp(16px,2.1vw,28px);line-height:1.22;letter-spacing:.02em;
  text-transform:uppercase;color:var(--ink);
  z-index:2;pointer-events:none;opacity:1;
}

/* Each word runs FOUR animations, one per property, so `translate` and
   `scale` keep their own durations and curves. They are expressed as
   animations rather than transitions because opacity needs two phases
   (in, then out) and one transition cannot do that. translate 0.30s and
   scale 0.16s remain SEPARATE DECLARATIONS ON SEPARATE TIMINGS and are
   NOT to be recombined into a `transform` shorthand — that recombination
   is the defect this mechanism was built to undo.
   --t-in / --t-out are per word, set inline. */
@keyframes fwIn  {from{opacity:0}to{opacity:1}}
@keyframes fwOut {from{opacity:1}to{opacity:0}}
@keyframes fwTrav{to{translate:calc(var(--dx) * var(--dd)) calc(var(--dy) * var(--dd))}}
@keyframes fwColl{to{scale:0.16;letter-spacing:0;color:var(--ink)}}

.dots .fw{display:inline-block;transform-origin:50% 50%;opacity:0}
.dots.built .fw{
  animation:fwIn .5s ease-out var(--t-in) both,
            fwOut .16s ease-out var(--t-out) forwards,
            fwTrav .30s cubic-bezier(.22,.85,.3,1) var(--t-out) forwards,
            fwColl .16s cubic-bezier(.3,.9,.4,1) var(--t-out) forwards;
}

/* the two dot colours. IN THE SOURCE CONCEPT THESE WERE FILL ATTRIBUTES
   ON TWO SEPARATE <g> PARENTS, AND THAT SPLIT CAUSED A MEASURED DEFECT —
   see the nth-of-type note below. They are classes on a single flat
   group now, so colour and stagger are independent of each other. */
.dots .sd-c{fill:var(--ink)}
.dots .sd-m{fill:var(--mark)}

/* Beat 2 — the twelve emerge one at a time, each just after the word it
   came from breaks. The mapping is geometric, not allocated: every dot is
   assigned to whichever word's outward vector points closest to it,
   measured from the field centre. That yields 4 / 2 / 1 / 3 / 2 across
   the five words — uneven, because breakage is uneven. Because the words
   break at different moments, their fragments interleave in time rather
   than arriving in five blocks.

   THE TWELVE CIRCLES SIT IN ONE FLAT <g>, AND THAT IS A CORRECTION, NOT A
   STYLE CHOICE. In the source concept they were split across two <g>
   parents — nine cream, three accent — and nth-of-type counts WITHIN A
   PARENT. Dots 10, 11 and 12 therefore had type-position 1, 2 and 3 and
   silently took dots 1-3's delays and drift parameters. MEASURED IN THE
   CONCEPT: nine distinct delays and nine distinct drift timings across
   twelve dots, with three pairs left exactly in phase — the precise thing
   the drift comment says is avoided. Six of the twenty-four authored
   rules matched nothing at all.

   Flattening the group restores the authored intent exactly. If these
   ever need regrouping, USE AN EXPLICIT PER-DOT CLASS, not a positional
   selector. */
.dots .sd{
  opacity:0;transform:translate(var(--ox),var(--oy)) scale(.35);
  transform-box:fill-box;transform-origin:center;
  transition:opacity .45s ease-out,transform .45s cubic-bezier(.2,.8,.3,1);
}
.dots.built .sd{opacity:1;transform:none;transition-duration:.22s}

.dots.built .sd:nth-of-type(1){transition-delay:2.20s}
.dots.built .sd:nth-of-type(2){transition-delay:2.47s}
.dots.built .sd:nth-of-type(3){transition-delay:2.34s}
.dots.built .sd:nth-of-type(4){transition-delay:2.38s}
.dots.built .sd:nth-of-type(5){transition-delay:2.43s}
.dots.built .sd:nth-of-type(6){transition-delay:2.80s}
.dots.built .sd:nth-of-type(7){transition-delay:2.48s}
.dots.built .sd:nth-of-type(8){transition-delay:2.85s}
.dots.built .sd:nth-of-type(9){transition-delay:2.62s}
.dots.built .sd:nth-of-type(10){transition-delay:2.29s}
.dots.built .sd:nth-of-type(11){transition-delay:2.71s}
.dots.built .sd:nth-of-type(12){transition-delay:2.76s}

/* THE DEPARTURE. OPACITY ONLY — `transform` is owned by `sorbit` from the
   moment `.built` lands, and an animation beats a transition on the same
   property, so a transform here would be silently overridden by the drift.
   `sorbit` never touches opacity, so the two do not contend.

   ⚠ `:nth-of-type(n)` AND THE POSITION BELOW ARE BOTH LOad-BEARING, AND THIS
   RULE SHIPPED WRONG ONCE WITHOUT THEM. Written as `.dots.leaving .sd` it is
   (0,3,0), while the TWELVE arrival rules directly above are (0,3,1) — so they
   won `transition-delay` and every dot inherited its own 2.20-2.85s ARRIVAL
   delay as its DEPARTURE delay. The departure window is ~1.1s, so the fade was
   scheduled to begin after the cycle had already restarted and NO DOT EVER
   FADED. Nothing errored; the rule simply lost. `:nth-of-type(n)` matches every
   dot and raises this to (0,3,1), equal to the arrival rules, and being BELOW
   them it wins on source order. **Move it above them, or drop the pseudo-class,
   and the fade silently stops happening again.**

   `--fd` IS WRITTEN BY js/reveal.js, ONE NUMBER PER DOT, RESHUFFLED EVERY
   CYCLE. It arrives as a CUSTOM PROPERTY consumed by this rule, which keeps it
   INSIDE THE CASCADE. **JS must never set style.opacity or an inline
   transition-delay on `.sd`: an inline style outranks the
   prefers-reduced-motion block below, and would re-enable motion for a reader
   who asked for none.** The fallback `0s` means a missing `--fd` degrades to an
   unstaggered fade rather than to no fade.

   `transition-duration` is inherited from `.dots.built .sd` — .22s — because
   the departure rides the same transition the arrival does. See WL-27. */
.dots.leaving .sd:nth-of-type(n){opacity:0;transition-delay:var(--fd,0s)}

/* Beat 3 — ambient drift. A CLOSED elliptical loop, linear and
   non-alternating, so there is no turn point and no seam: 0% and 100% are
   the same coordinate. An `alternate` loop with ease-in-out decelerates
   to a full stop and reverses at both extremes — a perceptible loop point
   twice a cycle. The ellipse is centred at (--rx, 0) so it PASSES THROUGH
   the dot's settled position at 0%/100%, which keeps the settled
   coordinates canonical and means the animation can start from
   `transform:none` with no jump. It drives the `transform` SHORTHAND,
   never individual translate — individual transform properties compute to
   `none` on SVG circles in Chrome. Per-dot radii, periods and delays are
   all distinct so no two dots stay in phase. Time-based only: nothing
   here reads scroll position. */
@keyframes sorbit{
  0%  {transform:translate(0,0)}
  25% {transform:translate(var(--rx),var(--ry))}
  50% {transform:translate(calc(var(--rx) * 2),0)}
  75% {transform:translate(var(--rx),calc(var(--ry) * -1))}
  100%{transform:translate(0,0)}
}
.dots.built .sd:nth-of-type(1){--rx:6.30px;--ry:5.70px;animation:sorbit 11.30s linear 3.30s infinite}
.dots.built .sd:nth-of-type(2){--rx:5.85px;--ry:6.60px;animation:sorbit 12.70s linear 3.42s infinite}
.dots.built .sd:nth-of-type(3){--rx:6.90px;--ry:5.25px;animation:sorbit 9.80s linear 3.54s infinite}
.dots.built .sd:nth-of-type(4){--rx:6.15px;--ry:6.15px;animation:sorbit 13.40s linear 3.66s infinite}
.dots.built .sd:nth-of-type(5){--rx:5.70px;--ry:6.90px;animation:sorbit 10.60s linear 3.78s infinite}
.dots.built .sd:nth-of-type(6){--rx:6.75px;--ry:5.55px;animation:sorbit 14.20s linear 3.90s infinite}
.dots.built .sd:nth-of-type(7){--rx:6.45px;--ry:6.30px;animation:sorbit 9.30s linear 4.02s infinite}
.dots.built .sd:nth-of-type(8){--rx:6.00px;--ry:5.10px;animation:sorbit 12.10s linear 4.14s infinite}
.dots.built .sd:nth-of-type(9){--rx:7.20px;--ry:6.00px;animation:sorbit 15.10s linear 4.26s infinite}
.dots.built .sd:nth-of-type(10){--rx:5.55px;--ry:6.75px;animation:sorbit 10.90s linear 4.38s infinite}
.dots.built .sd:nth-of-type(11){--rx:6.60px;--ry:5.85px;animation:sorbit 13.90s linear 4.50s infinite}
.dots.built .sd:nth-of-type(12){--rx:6.10px;--ry:6.45px;animation:sorbit 11.70s linear 4.62s infinite}

/* ambient drift pauses off-screen — motion only where it can be seen */
.dots.paused .sd{animation-play-state:paused}

@media(prefers-reduced-motion:reduce){
  .dots .fwrap{display:none}          /* transitional words never render */
  .dots .fw{animation:none !important}
  .dots .sd{opacity:1;transform:none;transition:none;animation:none !important}
}

/* ---------------- PIVOT ---------------- */

/* tightened here only — the copy column is shorter than the badge, so the
   section read loose once the bordered paragraph came out. Badge size and
   centring untouched. */
.pivot{padding-top:78px;padding-bottom:78px}
.pivot .in{display:flex;gap:5vw;align-items:center}
.pivot .copy{flex:1 1 auto;max-width:620px}
@media(max-width:920px){.pivot .in{flex-direction:column;align-items:flex-start}}

/* ---------------------------------------------------------------------
   §1 · THE PIVOT BAND TURNS PLUM, AND IT DOES NOT TAKE .band-plum (R4)

   ID-SCOPED GROUND, ON THE #film PRECEDENT. Taking `.band-plum` would have
   handed this section components/bands.css's UNSCOPED
   `.band-plum .in{display:flex;gap:5vw;align-items:center}` — which would
   have overwritten this band's own measured gap. R1 retired an unscoped
   rule on a shared class for causing exactly that collision, and R2 chose
   an id-scoped ground on the homepage for the same reason. Same choice
   here. NOTE: after R4 this page carries NO .band-plum element at all.

   THE TEXTURE IS COPIED, NOT RE-DERIVED — the same declaration #film
   carries on the homepage, which was itself copied byte-for-byte from
   #fragmentation's before that section was deleted in this unit.

   FOREGROUNDS, ALL MEASURED AGAINST #292631 BEFORE BEING WRITTEN:
       h2        --on-dark       13.0839  vs 4.5
       .body     --on-dark-body   8.6943  vs 4.5
       .blabel   --white         14.8318  vs 3.0 (35.9px/700 = LARGE)
       .cta-line --accent  UNCHANGED  3.5594 vs its applicable 3.0 at
                 19px/700 — the identical case recorded as HOME-1 in
                 pages/home.css. Not re-derived here.
       .bring    --gold    UNCHANGED  8.2161 vs 3.0 graphical
       .bd       --mark    UNCHANGED  3.5594 vs 3.0 graphical

   .blabel NEEDS AN EXPLICIT RULE. It sets no colour of its own and
   inherited --slate here; on plum that would have shipped slate-on-plum
   with nothing to show it.

   THE FLIP IS row-reverse, NOT `order`. It reverses the VISUAL order and
   leaves source order — and therefore reading and tab order — copy-first.
   --------------------------------------------------------------------- */
#pivot{background:var(--ground-dark);color:var(--on-dark);position:relative}
#pivot::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;
}
#pivot > .in{position:relative;z-index:1}
/* THE FLIP IS GATED TO THE TWO-COLUMN RANGE, AND THAT IS NOT DECORATION.
   `#pivot > .in` is (1,1,0) and out-specifies the existing
   `@media(max-width:920px){.pivot .in{flex-direction:column}}` at (0,2,0),
   so an ungated row-reverse WINS AT EVERY WIDTH and the stack never
   happens. MEASURED before this gate existed: at 390 the badge landed at
   x=-35, 437px wide, off the left edge of a 390px viewport, with nothing
   in the console. Reversing a row only means anything while there IS a
   row. */
@media(min-width:921px){
  #pivot > .in{flex-direction:row-reverse}
}
#pivot > .in > .copy > h2{color:var(--on-dark)}
#pivot > .in > .copy > .body{color:var(--on-dark-body)}
#pivot .blabel{color:var(--white)}
#pivot > .in > .copy > .cta-line{color:var(--gold)}

/* ---------------------------------------------------------------------
   THE HERO IS TWO COLUMNS NOW, AND THE DOT FIELD MUST BE SIZED (R4)

   THE SIZING RULE IS NOT OPTIONAL AND IS NOT TIDINESS. .dots arrived from
   a .band-plum section, where components/bands.css sized it
   `flex:0 0 min(30vw,340px)`. The hero is not .band-plum, so that rule
   cannot reach it, and MEASURED without a replacement the .fwrap box
   inflates 340x302.88 -> 1040x909.55 — 3.06x. js/reveal.js observes
   .fwrap at a 0.9 intersection threshold to add `built`, which is what
   lifts every dot off opacity 0; at that size the box is marginal at
   1440x900 and reaches only 0.835 at 1440x760, so the field would render
   INVISIBLE with nothing in the console. That is the 9an defect exactly,
   and this rule is what prevents it.

   HERO-SCOPED, NEVER A BARE .dots RULE — §46. The value is the one that
   restores 340x302.88 at ratio 1.0, measured, not chosen.

   COPY FIRST WHEN IT STACKS. 920px is this page's own breakpoint — the
   pivot band, the model grid and bands.css all turn at it — so the hero
   turns with them rather than introducing a fifth number.
   --------------------------------------------------------------------- */
.wl-hero > .in{display:flex;gap:5vw;align-items:center}
.wl-hero .wl-hero-copy{flex:1 1 auto;min-width:0}
.wl-hero .dots{flex:0 0 min(30vw,340px);position:relative}
.wl-hero .dots svg{width:100%;height:auto}
@media(max-width:920px){
  .wl-hero > .in{flex-direction:column;align-items:flex-start}
  .wl-hero .dots{flex:0 0 auto;width:min(260px,60vw);align-self:center}
}
