/* ==========================================================================
   HOMEPAGE 4.0 — SCALED AI (shell), 10-01
   ==========================================================================

   ⚠️ THIS WHOLE FILE IS ON TRIAL. DELETE IT TO REMOVE THE SECTION.
   It is enqueued after homepage-v4.css and depends on it, so every override
   below wins on load order rather than on specificity. That is deliberate:
   NOTHING IN homepage-v4.css WAS EDITED to make room for this section, so a
   week of unrelated homepage work cannot conflict with the revert.

   Removal is this file, template-parts/homepage-v4/section-scaled-ai.php, the
   get_template_part() line in template-homepage-v4.php, and the
   wp_enqueue_style() line in functions.php. Four deletions, one commit.

   WHAT IT HAS TO DO, AND WHY EACH PIECE EXISTS:

   1. Hide #hv4-conditions' bottom wave. The two sections are now the same
      navy, so that wave would be navy running into navy — invisible, and 70px
      of dead space inside a colour field. A wave takes the ground of the
      section it OPENS ONTO, and what this one opens onto has changed.
   2. Give this section the same wave at ITS foot, where the navy-to-white
      change actually happens now.
   3. Re-space the seam #hv4-conditions no longer has a wave to fill.
   ========================================================================== */

/* *** NO WAVE AT THIS JOIN. ASKED FOR DIRECTLY: "we don't need a wave here." ***

   This rule has now been all three things, and the history is worth keeping
   because each state was the right answer to a different page:

     background: --paper   the original, from homepage-v4.css. Correct while
                           #hv4-conditions ran straight into #hv4-correction.
     display: none         for one afternoon, when #hv4-conditions and
                           #hv4-scaled were both navy — a navy wave on navy is
                           invisible and costs 70px.
     background: --navy    when #hv4-conditions went teal, because there was a
                           real colour change to carry again.
     display: none         NOW, and this one is a design call, not a deduction.
                           There IS still a colour change here. The wave was
                           working. It is not wanted: teal meets navy on a
                           straight edge.

   TWO THINGS GO WITH IT AND BOTH ARE SILENT IF MISSED:
   1. The seam below has to be re-measured from scratch. The whole of the
      arithmetic in that block was "13.1px of ground under the ink plus the
      padding"; there is no ink and no box now, so the padding IS the gap.
   2. #hv4-conditions .wave-bottom comes OUT of the path-fill selector at the
      foot of this file. Painting a hidden element teal is dead code that reads
      like a live decision.

   The wave in the partial is untouched. That one closes #hv4-scaled into
   #hv4-correction's white, which is a different join with a different reason,
   and these two were never a matched pair. */
#hv4-conditions .wave-bottom {
    display: none
}

/* The background is byte-identical to homepage-v4.css:759-763, which puts this
   wave on #hv4-correction's flat white. The section below is still
   #hv4-correction and is still flat white, so the join into it is UNCHANGED by
   this section — only the element carrying it moved. If #hv4-correction is ever
   recoloured, this line moves with it exactly as the original would have.

   *** THE MASK IS WHAT MAKES THE TOPO WRAP IN THE WAVE, 10-01: "topo isn't
   wrapping in the wave at the bottom." ***

   Same mechanism as #hv4-why .wave-top (homepage-v4.css:88), and the reasoning
   there is the full version. The short form: a FILL and a MASK put the colour
   in opposite places, and only the mask leaves the other half transparent.

     filled   the <path> paints flat navy above the curve. The section's topo
              is a ::before at z-index -1, so the path covers it and the
              texture stops at a 70px rectangle.
     masked   the ELEMENT paints white below the curve and nothing above it,
              so the section's own navy and its topo run up through the band.

   The path is therefore DELETED FROM THE MARKUP — see the partial. This is the
   complement of what was there: same control points, closed DOWN to y=90
   instead of up to y=-5.

   WHY THE MASK CAN STRETCH AND THE BACKGROUND CANNOT. A wave is meant to
   stretch, which is what preserveAspectRatio="none" on the viewBox is for, but
   stretching a viewBox also smears anything PATTERNED inside it. Separating
   the two means the mask takes the stretching and the background it reveals
   does not — which matters here because #hv4-correction's white is flat today
   and the page's other whites are a noise tile.

   ⚠️ -webkit-mask IS NOT OPTIONAL and is not legacy. Safari still needs it for
   mask on an inline <svg> element, and without it the whole band goes white —
   an unmasked element paints its background everywhere, so the failure is the
   wave disappearing rather than the texture not wrapping. */
#hv4-scaled .wave-bottom {
    background: var(--white);
    -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 90' preserveAspectRatio='none'><path d='M0,50 C180,80 360,80 540,55 C720,30 900,15 1080,22 C1260,32 1350,48 1440,55 L1440,90 L0,90 Z' fill='white'/></svg>") no-repeat 0 0/100% 100%;
    mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 90' preserveAspectRatio='none'><path d='M0,50 C180,80 360,80 540,55 C720,30 900,15 1080,22 C1260,32 1350,48 1440,55 L1440,90 L0,90 Z' fill='white'/></svg>") no-repeat 0 0/100% 100%
}

/* ── THE SEAM ─────────────────────────────────────────────────────────────
   *** EVERY NUMBER THAT WAS EVER SET HERE WAS SET AGAINST A WAVE, AND THE
   WAVE IS GONE. *** This join has been measured four times. The first three
   are below as a record of what each one was answering, because three of the
   four were right at the time:

     192px  6rem + 6rem, the page's figure for a join BETWEEN SECTIONS. Right
            everywhere else on this page because every other join has a colour
            change at it. At the time this one did NOT — both sections were
            navy — so it read as a hole, not a join: "the space between the
            two is too much."
      96px  3rem + 3rem, on the argument that a seam inside one dark band is a
            step between blocks rather than a door between rooms.
     109px  3rem of #hv4-conditions + a 70px wave + 6rem here. Measured from
            the wave's INK rather than its box: the deepest point sits 56.9px
            into the 70px, so only 13.1px of it was ever ground. 13.1 + 96.

   *** NOW THE PADDING IS THE WHOLE GAP. *** There is no wave and no 70px box,
   so nothing is being paid for by anything else, and the two-section join is
   just the two paddings added up. That puts it back on the page's own number
   — .hv4-section's 6rem a side, 192px, which homepage-v4.css:797 records as
   running at EVERY other join on this page with "one number, no exceptions."

   AND THE 192 VERDICT APPLIES AGAIN. The reason 192 failed the first time was
   that there was no colour change, which homepage-v4.css:806 flags in as many
   words: that verdict "does NOT transfer to a colour-change join." Teal
   against navy is a colour change — a harder one now than it was through a
   curve, because the eye gets a straight edge across the full width.

     #hv4-conditions bottom   3rem -> 6rem   its 3rem was a WAVE figure, set
                                             in homepage-v4.css for a join
                                             that had 70px of curve in it
     #hv4-scaled     top      2rem -> 6rem   and see the note below on why the
                                             2rem base was never for this
     #hv4-scaled     bottom   3rem -> none   deleted, and see THE LEGEND END
                                             below. That end still has its
                                             wave, into #hv4-correction

   *** THE 2rem BASE IS FOR A WAVE-TOP, AND THERE ISN'T ONE HERE. *** Worth
   keeping even though the arithmetic above no longer runs through it, because
   it is a trap in .hv4-waveband-inner that any future section built on that
   class will hit. Every other user of the 2rem carries its own
   <svg class="wave-top"> as a sibling, and a wave-top's ink is at the TOP of
   its box with solid section colour below — so the inner's 2rem is sitting on
   up to 70px of ground the wave already paid for. #hv4-scaled has no wave-top
   and never did. */
#hv4-conditions .hv4-waveband-inner {
    padding-bottom: 6rem
}

/* THE LEGEND END — "the legend feels too close to edge."
   *** MEASURE A WAVE FROM ITS INK, NOT ITS BOX, AT THE BOTTOM EDGE TOO. ***
   This is the same standing rule as the top of the section and it gets missed
   at this end, because at the bottom the relevant point is the curve's
   HIGHEST one — where it first cuts into the band — and on this curve that is
   y=15 of a 90 viewBox, so 11.7px into the 70px box. The padding said 48 and
   the real clearance under the legend was 59.7.

   The fix is a DELETION. .hv4-waveband-inner's own 5rem bottom is the page's
   figure for a band that has a wave under it, and it was being overridden to
   3rem for no reason that survives — 3rem was copied from #hv4-conditions
   back when this section was being built to sit where that one sat. Letting
   the base through gives 80 + 11.7 = 91.7px, and it also makes ≤991 and ≤767
   inherit correctly instead of needing two more restatements. */
#hv4-scaled .hv4-waveband-inner {
    padding-top: 6rem
}

/* ≤991 and ≤767 are restated rather than inherited because the rules being
   overridden are ID selectors inside media queries, and an ID beats a class
   whatever query the class sits in: without these lines this section would
   keep its desktop padding all the way down. That trap is documented twice in
   homepage-v4.css and it has caught this stylesheet.

   Both halves track .hv4-section, which is what the 192 is made of:

     width   .hv4-section padding   each side here   the seam
     1440    6rem                   6rem             192
      991    4rem                   4rem             128
      767    4rem                   2rem              64

   ⚠️⚠️ *** 767 USED TO BREAK THE PATTERN AND IT WAS WRONG, 10-08: "this needs
   more bottom padding too", pointing at the ground under Capabilities Are the
   Unit of Decision. *** It was 2rem a side — a 64px seam where the page's
   plain join at that width is 128. Exactly half.

   The old reasoning is left here because the SHAPE of the error is the one
   this stylesheet keeps making: "homepage-v4.css flattens EVERY waveband to
   2rem top and bottom at that width, and that is the page's own figure for a
   waveband join on a phone." Every clause of that is true and the conclusion
   is still wrong, because ⚠️ THE 2rem IS HALF A JOIN AND A WAVE IS MEANT TO BE
   THE OTHER HALF. The rule's own note says so in its arithmetic — "31px of ink
   + 32px of padding = 63px of visible ground, against the page's own 64px."
   THIS SEAM HAS NO WAVE: the first thing this file does is hide
   #hv4-conditions .wave-bottom. So 2rem + 2rem never had 62px of ink to add to
   it and the join came out at half size.

   ⚠️ THAT IS THE THIRD TIME THIS PAGE HAS BEEN CAUGHT BY IT. #hv4-why's bottom
   is split out of the same shared rule for the same reason, twice over
   (homepage-v4.css ≤991 and ≤767), and both of those notes say the same
   sentence: the padding is the whole join when there is no wave. ⚠️ BEFORE
   TAKING A WAVEBAND NUMBER, CHECK THERE IS ACTUALLY A WAVE AT THAT EDGE.

   4rem a side at ≤767 makes it 128 — the plain join — and it makes the whole
   ladder read straight off .hv4-section with no exception to remember:

     width   .hv4-section padding   each side here   the seam   plain join
     1440    6rem                   6rem             192        192
      991    4rem                   4rem             128        128
      767    4rem                   4rem             128        128

   ONLY THE TOP OF #hv4-scaled IS RESTATED AT ≤991. Its BOTTOM is a wave edge
   and takes the waveband's own 5rem / 3.5rem ladder — see the rule below ≤767
   for the one width where that ladder does not describe it. */
@media(max-width: 991px) {

    #hv4-conditions .hv4-waveband-inner {
        padding-bottom: 4rem
    }

    #hv4-scaled .hv4-waveband-inner {
        padding-top: 4rem
    }
}

@media(max-width: 767px) {

    #hv4-conditions .hv4-waveband-inner {
        padding-bottom: 4rem
    }

    #hv4-scaled .hv4-waveband-inner {
        padding-top: 4rem
    }

    /* *** #hv4-scaled's BOTTOM WAVE IS THE MIRROR OF THE ONE EVERY PHONE
       FIGURE ON THIS PAGE WAS DERIVED AGAINST, 10-08: "on homepage this
       padding is too small at the bottom", under Explore the Methodology. ***

       homepage-v4.css's ≤767 waveband rule sets 2rem on the strength of "31px
       of ink + 32px of padding = 63px of visible ground". ⚠️ THE 31px IS
       #hv4-conditions' OLD BOTTOM WAVE, WHICH THIS FILE HIDES. Its boundary
       sat at 73.2 of the 90-unit viewBox — deep, so it left 31px of ground.
       The wave that is actually at this edge now is the mirrored curve, whose
       boundary runs the other way: 20.3 at its thinnest, which at the 38px box
       a phone draws is 8.6px, not 31.

       ⚠️ AND THE MIRROR PUT THE THIN POINT UNDER THE CONTENT. On the old curve
       the thin end was off at x≈1050 of 1440, past the right edge of a desktop
       container. Mirrored and reflowed to 375, where the button runs the full
       column, it lands directly beneath the button. Measured there: 32 + 8.6 =
       40.6px of visible teal against the page's 64, and a join to
       #hv4-correction of 104 against 128.

       ⚠️ A WAVE IS NOT INTERCHANGEABLE WITH ANOTHER WAVE EVEN WHEN IT IS THE
       SAME CURVE. Flipping one moves its trough across the page, and every
       padding derived from its old trough is stale the moment it flips.

       3.5rem is the ≤991 value, which is the one rung of the waveband ladder
       derived against THIS curve: 56 + 8.6 = 64.6px of ground against the
       page's 64, and the join lands at 128.6 against 128. Desktop (80 + 15.8 =
       95.8 against 96) was already right for the same reason and is untouched. */
    #hv4-scaled .hv4-waveband-inner {
        padding-bottom: 3.5rem
    }
}

/* ── THE TOPO ─────────────────────────────────────────────────────────────
   The page's existing topo component, not a new one. It is a MASK, not an
   image: Topo-bright.svg supplies only the shape and the colour is chosen
   here, which is the whole reason the same asset works on dark green, bright
   blue and now navy. Copied from .pa-intro-bg::after (styles.css:2975) and
   #fa-intro::before (styles.css:4231), which are byte-identical to each other
   apart from colour and opacity.

   The url is relative to the STYLESHEET, and this file sits in the same
   assets/modern/ directory as styles.css, so the path is verbatim.

   WHY DARK TEAL AND NOT A LIGHT INK. The topo has to pass behind the diagram,
   whose layer fills are semi-transparent — rgba(14,77,100,.45) and
   rgba(255,255,255,.06) — so whatever is drawn here shows THROUGH the boxes
   as well as around them. A light ink would have put contour lines across the
   inside of every panel and competed with the 1px borders that are the
   diagram's entire drawing. Dark teal on navy is a tonal shift rather than a
   second drawing: it moves the ground and leaves the lines alone.

   isolation + z-index:-1 is what keeps it behind the content. The trap it
   avoids is documented at homepage-v4.css:4171 — a positioned pseudo-element
   at z-index 0 paints OVER ordinary block content, so the band would have
   covered its own copy. overflow:hidden is for the scale(1.15), which pushes
   15% of the artwork outside the section on every side. */
/* ⚠️ overflow:CLIP, NOT HIDDEN, AND THE DIFFERENCE IS NOT COSMETIC.
   Both clip the scale(1.15) topo identically. But `hidden` makes the section
   a SCROLL CONTAINER — scrollable, just without a visible scrollbar — and the
   scaled pseudo-element gives it 102px of scrollable overflow to work with.
   Anything that scrolls a descendant into view then scrolls the SECTION
   instead of the page, and the whole band slides up inside its own background
   while the wave stays put.

   This diagram is the worst possible content for that: ~25 tabindex="0"
   elements inside the box, so a keyboard user tabbing into it would make the
   section jump. Caught here by a scripted scrollIntoView() producing a 102px
   band of ground below the wave that looked like a padding bug.

   `clip` is the same visual result with no scroll container, so there is
   nothing to scroll. It needs no fallback worth writing: in a browser without
   it the declaration is dropped and the overflow:hidden on the line above
   stands, which is exactly today's behaviour. */
#hv4-scaled {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    overflow: clip
}

#hv4-scaled::before {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--dark-teal);
    -webkit-mask: url("psd_assets/Topo-bright.svg") center/cover no-repeat;
    mask: url("psd_assets/Topo-bright.svg") center/cover no-repeat;
    transform: scale(1.15);
    transform-origin: center;
    opacity: .5;
    pointer-events: none;
    z-index: -1
}

/* ══════════════════════════════════════════════════════════════════════════
   THE SPLIT — copy on the left, the model as a picture on the right
   ══════════════════════════════════════════════════════════════════════════

   10-05. *** THIS REPLACES THE INTERACTIVE DIAGRAM THAT WAS BUILT HERE. ***
   Not a design revision — a scope decision taken on the October 2 marketing
   call and recorded in the Scaled AI handoff (README section 6): the homepage
   carries a stylized, simplified PICTURE of the model with a few lines and a
   button, and the live interactive version stays at scaledai.liminalarc.co.
   Jess, 10-05: "we don't want to put the whole graphic system on the homepage
   because it's too much happening."

   So ~630 lines of layer / card / box / legend / hover-card CSS came out, and
   the inline JS came out of the partial with it. None of it was wrong. All of
   it was the wrong amount of page. It is recoverable from git if the decision
   is ever revisited — commit 099a721a is the last one that has it.

   *** 60/40, NOT THE 2/3–1/3 THAT WAS ASKED ABOUT, AND THE IMAGE'S SHAPE IS
   WHY. *** The asset is 2560 x 3618 — PORTRAIT, half again as tall as it is
   wide. A column's width therefore BUYS HEIGHT at 1.41x, so the wider the
   picture gets the worse the mismatch with the copy beside it:

     split     image col   forced height   copy column   chars per line
     2/3–1/3     738px        1043px          369px          ~42
     60/40       655px         926px          436px          ~50

   The leftover air is about 300px either way, so height is not the decider.
   THE COPY COLUMN IS. 42 characters a line is under the 45–75 band and is
   precisely the "feels kind of tight" complaint this page has produced before
   — and here it could not have been answered the usual way, by fixing the
   type, because the width would genuinely have been the constraint. 60/40
   gives about 50 and reads.

   *** align-items:start, AND THAT IS A REVERSAL. *** It was `center` for one
   build, on the argument that splitting the leftover air above and below the
   copy reads as a decision rather than as a column that ran out. Jess, 10-05:
   "I want the text higher up top aligned with the graphic." ⚠️ DO NOT RE-OFFER
   CENTRING — the argument for it was about the AIR, and it lost to the only
   thing that actually matters here, which is that the HEADLINE and the TOP OF
   THE PICTURE are the two things the eye pairs. Centring a 459px block against
   a 930px one drops the headline 235px below the top of the thing it names,
   and no amount of balanced air buys that back.

   ⚠️ IT ALSO MEANS THE LEFTOVER AIR IS ALL AT THE BOTTOM, UNDER THE BUTTON,
   and that is now load-bearing rather than a leftover: at 1440 it is ~470px,
   which is most of the column. If the copy ever grows enough to fill it, the
   two columns will meet at the bottom by accident and the button will sit on
   the picture's baseline — that will look deliberate and will not be. It is
   the kind of thing to re-check after any copy change, not after a CSS one.

   ⚠️ minmax(0, …) ON BOTH TRACKS, NOT BARE fr. An fr track floors at
   min-content, and this cell's min-content is a 2560px image — it would push
   the grid wider than .la-container and leave the copy whatever was left.
   Same trap as the min-width:0 that .sai-head's flex row needed.
   ────────────────────────────────────────────────────────────────────────── */

/* ⚠️⚠️ 1/3 COPY ÷ 2/3 GRAPHIC, 10-07 — SETTLED AFTER SEEING ALL THREE.
   "how about we give the graphic a tiny bit more breathing room and let it go
   2/3 the way? then have the copy the other 1/3", and then, having looked at
   full width and at 50/50 beside it, "I like it better 2/3".

   ⚠️ THE OTHER TWO WERE BUILT AND MEASURED, NOT GUESSED AT, AND BOTH LOST ON
   THE SAME POINT — the drawing's SHAPE. Numbers, all at 1440:

     1/3 ÷ 2/3   732 × 846   run layer 4 across, every label on one line
     50/50       550 × 949   run layer 2×2, layer sentences wrap, titles break,
                              TALLER than full width in half the width, and the
                              copy track empties out halfway down the drawing
     one column 1155 × 846   true scale at every viewport, but a very tall section

   Going narrow does not shrink this picture, it RESHAPES it: below about 620 of
   drawing the run layer cannot hold four across and three labels start wrapping,
   so the thing gets taller as it gets narrower. 732 is the narrowest width that
   keeps all of it on one line each.

   ⚠️ THE 57px GAP IS ARITHMETIC, NOT SPACING. The drawing's type is only real
   pixels while the svg's rendered width equals its viewBox width, so the wide
   track has to land on a whole number: (1155 − 57) × 2/3 = 732 exactly. Change
   the gap and you have changed W, the viewBox and every size in the drawing.

   ⚠️ AND THE PRICE OF THAT, KNOWINGLY PAID: the factor is 1.0 only at 1440+.
   Below it the container narrows, max-width:100% takes over from the 732 cap and
   everything scales down. Judge type sizes at 1440 and nowhere else. The
   one-column version is the only one that was 1.0 everywhere, and it is kept
   whole at /tmp/sai_teaser_1155_1col.py and /tmp/hv4-scaled-ai_1155_1col.css;
   the 50/50 generator is /tmp/sai_teaser_half.py.

   ⚠️ NOTHING SORTS AT THIS WIDTH. Side by side the order is the DOM's own —
   copy and button on the left, the drawing on the right. ⚠️ IT DOES SORT BELOW
   991, where the picture goes BETWEEN the lead and the button; that costs
   display:contents on .sai-copy plus order:1 on .sai-action, because
   .sai-action is NESTED and `order` only sorts siblings. The full working is in
   the ≤991 block at the foot of this file — it is not a one-line change.

   ⚠️⚠️ THERE IS NO margin-top HERE, 10-16, AND PUTTING ONE BACK MOVES THE
   SECTION'S OPENING GAP. *** "this what Ai section looks low is that consistent
   with other sections on mobile?" *** — it was not, at any width. This rule
   carried `margin-top: 2.5rem` (and `2rem` at ≤767) from the section's first
   commit, where it was the gap BELOW the h2: the h2 was a direct child of
   .la-container and .sai-split held only the picture. The 10-05/10-07 split
   work moved the h2 INSIDE .sai-copy, and from that moment the margin was no
   longer a gap between two things — it was pure offset on top of
   .hv4-waveband-inner's padding, i.e. the section's opening spacing, and
   nobody re-derived it. Measured top edge → first headline, the flat-top
   sections of this page all run 96 at 1200 and 64 at 390 (#hv4-problem,
   #hv4-cost, #hv4-correction, #hv4-delivery); this one ran 136 and 96.

   ⚠️ A MARGIN ON A GRID THAT HOLDS THE HEADING IS SECTION PADDING WEARING A
   LAYOUT NAME. .sai-copy > :first-child { margin-top: 0 } below strips the h2's
   own margin, so with nothing here the headline sits exactly on the waveband's
   padding, which is what every other section does. If the opening ever needs
   changing it is .hv4-waveband-inner's padding that changes, not this. */
.sai-split {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
    gap: 57px;
    align-items: start
}

.sai-action {
    margin-top: 2rem
}

/* The h2 and the lead are the page's own and are left inherited. The only
   thing done to them is removing the h2's top margin: it is sized for a
   full-width section opening, and in a grid cell it is pure offset.

   ⚠️ SINCE align-items:start THIS RULE IS WHAT MAKES THE TOP ALIGNMENT TRUE —
   the h2's own margin would push the headline straight back down off the
   picture's top edge, and the result would look like the alignment simply did
   not take. It is not tidying; delete it and the 10-05 request is undone. */
.sai-copy>:first-child {
    margin-top: 0
}

/* ⚠️⚠️ THE max-width:none OVERRIDE IS BACK IN, 10-07, BECAUSE THE SECTION IS
   TWO EQUAL COLUMNS. It has now been added, removed, re-added and removed and
   added again as the layout went split → one column → split → one column →
   split again, which is exactly the point of the standing note: THE OVERRIDE AND THE
   COLUMN COUNT ARE ONE DECISION and they change in the same edit, always. If
   you are reading this because you just changed .sai-split, this is the other
   half of your edit.

   .hv4-lead carries max-width:66.67% of its own. That figure is WRITTEN FOR a
   lead running the full 1155 container. The copy track here is 366, so 66.67%
   of it is 244 — a cap on top of a cap, and a measure of about 30 characters.
   none lets the lead use the track it was already given.

   ⚠️ THIS RULE IS UNCONDITIONAL AND THE COLUMNS ARE NOT. Since 10-08 the
   section is one column from 1199 down, where there is no 366px track and so
   nothing for `none` to rescue — it just uncaps the lead against the full
   container. The 992–1199 block at the foot of this file puts the cap back for
   that band. Read the two together; neither makes sense alone. */
#hv4-scaled .sai-copy .hv4-lead {
    max-width: none
}

/* *** THE HAIRLINE AND THE RADIUS CAME OFF, 10-05. ***
   "can you remove the blue border on the graphic so we can get more space
   back." It was `1px solid hsla(0,0%,100%,.14)` with a 4px radius and
   overflow:hidden — 1px and 4px being the figures the deleted diagram's own
   boxes used, so the picture read as continuous with the thing it replaced.

   The argument FOR it is still true and is why it is written down rather than
   just deleted: the asset's own ground is #0E4D64, which is this section's
   ground exactly, so with no edge of its own the picture does not END
   anywhere — it just stops having content in it. ⚠️ If the simplified artwork
   arrives on a transparent or a different ground, that stops being a trade and
   the hairline is simply not needed.

   The radius and the overflow went with it: a 4px corner cut into a rectangle
   that is the same colour as the page behind it is invisible, so once the
   border is gone they are two rules doing nothing.

   ⚠️ AND THE SPACE IT GIVES BACK IS 2px, WHICH IS NOT THE SPACE THAT WAS
   ASKED FOR. The air around the drawing is baked INTO the PNG — the export
   carries its own margin. That is a crop in the artwork, not a change here,
   so it goes on the list for the simplified asset rather than being chased
   with negative margins in CSS. */
/* Zero — the grid gap above carries the separation from the button now, so a
   margin here would double it. */
.sai-figure {
    margin: 0
}

/* ⚠️ THE <img> IS GONE, 10-06 — the rule that used to be here styled a 2560px
   PNG export of the full methodology drawing. The picture is now an inline
   <svg> built in section-scaled-ai.php; the viewBox gives the aspect ratio, so
   the box is still reserved before anything paints and the section cannot jump.

   ⚠️⚠️ 732 IS `W` IN /tmp/sai_teaser.py AND THEY STILL MOVE TOGETHER — but it
   is now the MAX-WIDTH'S BASIS, not the width. The svg is width-constrained, so
   its scale factor is rendered width ÷ viewBox width; at 732 that is exactly
   1.0, which is the only reason `font-size: 10px` in the drawing renders at 10px
   and can be judged against the site's type scale at all.

   ⚠️⚠️ IT WAS A FLAT `width: 732px` AND THAT WAS A BUG, FIXED 10-07: "edges
   still aren't lined up", with a crop showing the band ending short of the
   section above it.
   732 is the 2/3 track of this grid AT A 1440 WINDOW AND ONLY THERE. The
   container's padding is clamp(1.5rem, 9.9vw, 9rem), so the content width — and
   therefore the track — GROWS WITH THE WINDOW, while a flat 732 does not:

       1440 window   track 731.9   flush, 1px to spare   <- the width I tested at
       1456 window   track 740.7   9px short             <- the crop
       1552 window   track 805.0
       1728 window   track 916.7   186px short

   ⚠️ THE OLD COMMENT HERE CLAIMED THE FACTOR WAS 1.0 AT EVERY VIEWPORT. It is
   true BELOW 1440 and false above it, and it was written while testing below
   1440. A claim about every viewport has to be checked at the TOP of the range
   as well as the bottom — the same lesson as the breakpoint ramps.

   ⚠️⚠️ STRETCH WITH A CAP, AND THE CAP IS A TYPE DECISION, 10-07. Asked which
   mattered more, the right edge or the type sizes: "Stretch, but cap it."
   width:100% makes the drawing fill the track at any width, which also scales
   every label in it — so max-width is the most type growth we will accept, and
   it is written as 732 × 1.10 rather than as 805 so it reads as what it is.

   10% was chosen because it covers the real window sizes (the cap is not reached
   until a ~1552 window) while holding .sai-h — the biggest type in the drawing
   at 13.5 — to 14.8. ⚠️ BRANDON'S MEASURED BAND ON THIS SITE IS 12–13.6, so 10%
   is already over it and there is no case for 15% or 20%. Above a 1552 window
   the drawing stops growing and a gap returns on the right; that is the trade,
   taken knowingly, and it is the smaller of the two defects.

   ⚠️ BELOW 1440 NOTHING CHANGED — the track is narrower than 732, so width:100%
   does exactly what max-width:100% used to do and the drawing shrinks with the
   column. The factor has always been under 1.0 down there.

   ⚠️ THE LITERAL IS STILL THE ASSERTION. Writing the cap as a bare 805, or
   dropping it for width:100%, both render plausibly today and keep rendering
   "correctly" after someone changes the container, the column count or the
   padding — at which point the drawing is silently off scale with nothing to
   compare against. Keep 732 visible in the expression.

   ⚠️ IT WAS 1155 AND 550 LATER ON 10-07, and 380, 480, 550 before that. Every one of
   those moves had to be made in two files at once. If you are about to change
   one of these numbers, change the other in the same edit. */
.sai-svg {
    display: block;
    width: 100%;
    max-width: calc(732px * 1.1);
    height: auto
}

/* ⚠️⚠️ THE NARROW DRAWING, 10-07 — A SECOND SVG, NOT A RESTYLED ONE. SVG does
   not reflow: the three unit cards are three x offsets inside a viewBox and no
   media query can turn them into two rows. Both drawings are in the markup and
   exactly one is painted at any width; see the long note in the partial for why
   that is the cheap option.

   ⚠️ 380 IS THE OTHER HALF OF A NUMBER IN /tmp/sai_teaser.py, exactly as 732 is
   — it is `W` on the SAI_NARROW=1 pass. THEY MOVE TOGETHER, and the cap is
   written as 380 × 1.1 for the same reason the wide one is written as 732 × 1.1:
   the literal is the assertion.

   ⚠️⚠️ NO max-width — IT FILLS THE COLUMN, 10-07: "needs to stretch across
   still too", with the drawing sitting visibly narrower than the full-width
   button directly above it. It was capped at 380 × 1.1 = 418, which left 128px
   of air either side at 767 and read as a drawing that had failed to load
   properly rather than as a considered inset.

   ⚠️⚠️ THE CAP WAS A TYPE CEILING AND REMOVING IT SPENDS THAT CEILING. The ≤767
   band runs from a 330px container on a 375 phone to 675 at 767 — 2.05× — and
   the drawing's type is a fixed share of its width, so filling means the type
   scales with it:

       375   container 330   ×0.87   .sai-h 10.9px   .sai-lbl  8.7px
       480             422   ×1.11          13.9           11.1
       600             528   ×1.39          17.4           13.9
       767             675   ×1.78          22.2           17.8

   Brandon's measured band on this site is 12–13.6px, so everything above about
   a 480 viewport is over it, and 767 is at 22px against the SAME heading's
   12.5px on desktop.

   ⚠️ THAT IS ARITHMETIC, NOT A TUNING MISS, AND NO VALUE HERE FIXES IT. A
   container range of 2.05× cannot be filled by one drawing whose type is
   allowed to move 8.7 → 13.6px, which is 1.56×. Only three things can give:
   the air (gone, by request), the type ceiling (what this spends), or the
   RANGE — a third drawing, or a swap point between 480 and 767. The ladder has
   no number there (1199/1024/991/767/480), so a swap point in that gap would be
   a breakpoint invented for one element. ⚠️ Re-deriving a multiplier here is
   re-running work that is already recorded as impossible; the lever is the
   range.

   ⚠️ 380 IS STILL THE OTHER HALF OF A NUMBER IN /tmp/sai_teaser.py — it is `W`
   on the SAI_NARROW=1 pass, as 732 is on the wide one. Lowering `W` would buy
   back some of the top end at the cost of the phone end, 1:1. */
.sai-svg-n {
    display: none
}

/* ── THE TEASER DRAWING ─────────────────────────────────────────────────────

   ⚠️ EVERY NUMBER BELOW IS A REAL PIXEL. The viewBox is 732 wide and so is the
   width cap on .sai-svg above, so the scale factor is 1.0 and `font-size: 12px`
   renders at 12px. This is the opposite of the methodology page, where the
   viewBox scales by 0.9624 and every size has to be divided before it can be
   compared to the site's type scale. KEEP THE TWO 380s EQUAL and this stays
   true; break them and every size below becomes a lie.

   ⚠️⚠️ THE DRAWING'S JOB IS "A PICTURE OF HOW MUCH THERE IS", 10-07, and that
   is a direct quote. Everything in it stays — every box, every tree, every
   label — and the size comes out of the TYPE instead:

     "we need all the info that's currently there. I think the move is just
      tightening it all. I think the main big labels stay at their font size,
      but we can let lower levels things in the hierarchy be much smaller."

   So there is a real hierarchy here rather than a flat set a half-pixel apart.

   ⚠️⚠️ AND THERE ARE NOW TWO TIERS, 10-07, SET BY THIS: "you can go smaller on
   text if you need as long as we keep the 3 layer text easy to read and the
   lorem ipsum easy to read." That is a permission AND a floor in one sentence,
   and the two halves are not tradeable against each other:

     READ — comfortable, and these are the two that went UP at full width
     .sai-h         13.5   the three layer names, brandon   was 11.5, 12.5
     .sai-sub       12     the layer's line of copy        was 10
     .sai-line-l    12     "The Line" — a seam, not a layer   was .sai-h caps

     RECOGNISE — marks, not prose, and under the site's 11px floor on purpose
     .sai-card-t    12.5   unit and portfolio names        was 13, 10.5, 11.5
     .sai-strip-l   10     the two strips, = .sai-lbl       was 12.5, 9.5, 10.5
     .sai-lbl       10     most box labels                 was 12 then 9
     .sai-lbl-sm    9      the tree's Team boxes only      new 10-07
     .sai-note      10     the return-path annotation      DELETED 10-07

   ⚠️⚠️ TWO SIZES WENT UP AGAIN LATE ON 10-07, AT THE 2/3 WIDTH, AND NEITHER IS A
   REVERSAL OF THE CUT ABOVE. "let's make the brandon text a tad bigger" and
   "the first layer of text on all the boxes can be a tad bigger too."

     .sai-h       12.5 → 13.5   ⚠️ 13.5 IS THE TOP OF BRANDON'S MEASURED BAND ON
                                THIS SITE (12–13.6) AND THERE IS NOWHERE LEFT TO
                                GO. If "a tad bigger" is asked a third time the
                                answer is NOT 14 — brandon never gets to be big
                                here. Make the things around it smaller, or
                                change the weight, or say so.
     .sai-card-t  11.5 → 12.5   The CARD TITLE only — "Business Unit A",
                                "Capability Portfolio 1". ⚠️ NOT .sai-lbl, which
                                is the label inside every ordinary box and stays
                                at 10. "the first layer of text on all the boxes"
                                meant the TOP ROW of each card, not all text in
                                all boxes, and the screenshot that came with it
                                was the three portfolio titles.

   This widens the step between the card title and the labels under it from 1.5
   to 2.5, which is the hierarchy the tier table was after in the first place.

   ⚠️ TIER TWO SITS UNDER THE SITE'S 11px FLOOR AND THAT IS THE POINT, NOT AN
   OVERSIGHT. The floor governs type a reader is expected to READ. These are not
   that: a box label is a mark saying "a named thing lives here, and there are
   eighteen of them." The reading version of this picture is /methodology/, one
   click away, and the full content is in the svg's aria-label for anyone who
   cannot see it. ⚠️ DO NOT "FIX" THESE BACK UP on the strength of the floor rule
   — 12/13 was tried and the answer was "the text feels really big" and then
   "it's just too big for a homepage."

   ⚠️ THE GAP BETWEEN THE TIERS IS THE POINT, NOT ANY ONE NUMBER IN IT. Flatten
   the ladder and the picture just reads uniformly small again, which is the
   thing that already failed twice. The second tier may go lower; the first may
   not.

   ⚠️ THESE MOVE WITH THE RUNGS IN /tmp/sai_teaser.py, ALWAYS. Shrink the type
   on its own and the picture does not get smaller — the white space grows. Every
   gap in the generator is a share of the type size for exactly this reason, and
   "too tall" and "the text feels big" have turned out to be one request every
   single time they have been raised.

   ⚠️ brandon is ALWAYS uppercase with letter-spacing — standing brand rule, and
   it is applied here in CSS rather than in the content because these are
   LABELS, not copy anyone will read out of the markup.

   ⚠️⚠️ THE TRACKING IS 0.1em BECAUSE THAT IS THE SITE'S BUTTON STANDARD, 10-07:
   "is the kerning consistent with the site too. maybe look at what we do for
   buttons and try that." It was .12em, which is 20% looser than everything the
   site actually ships. Measured off the live page:

     .btn-teal            11.52px / 700 / 0.1em    the primary CTA
     .btn-orange          13.6px  / 700 / 0.1em
     .button, cookie btns 12–14px  / 400 / 0.1em
     .insights-nav-text   13.12px / 700 / 0.22em   ⚠️ the one outlier — do not
                                                   copy this one, it is a nav
                                                   flourish, not the standard

   ⚠️ TRACKING IS A SIZE LEVER TOO. Dropping .12 → .1 takes ~5px off "BUSINESS
   UNIT LAYER" and the whole label reads smaller without the font-size moving at
   all. If "a tad too big" comes back after this, THEN move the size — brandon's
   band here is 12–13.6 and the site's own button sizes bracket it. */

/* ⚠️ THE GROUNDS ARE /methodology/'s TOKENS, VALUE FOR VALUE — the same four
   literals that file sets on :root (methodology.css:91-95). They are restated
   rather than shared because the two pages do not load each other's CSS, and
   they have to stay in step: this drawing is the teaser for that one, and
   someone who clicks through should land on the same picture, not a cousin.

     --ai-surface  #0B3E50   the two AI bands        darker than the ground
     --card        #083341   a business unit card    darker still
     --ai-box      #0E4D64   a box inside a layer    THE PAGE GROUND EXACTLY
     --cap-surface #1C576D   the capability band     lighter than the ground

   A BOX IS ALWAYS THE PAGE GROUND AND THE BANDS MOVE AWAY FROM IT. That is not
   decoration — it is the claim the drawing makes: added layers standing against
   a foundation that was already there. */
.sai-band-ai {
    fill: #0b3e50;
    stroke: rgba(108, 224, 181, .45);
    stroke-width: 1
}

.sai-band-cap {
    fill: #1c576d;
    stroke: hsla(0, 0%, 100%, .28);
    stroke-width: 1
}

/* A business unit card — darker than the band around it, so the three steps
   inside it (which are the page ground) read as sitting on top of it. */
.sai-card {
    fill: #083341;
    stroke: hsla(0, 0%, 100%, .18);
    stroke-width: 1
}

.sai-box,
.sai-cap-box {
    fill: var(--dark-teal);
    stroke: hsla(0, 0%, 100%, .3);
    stroke-width: 1
}

/* Unit Run is the one box drawn as an outline with nothing in it. Dashed and
   short on purpose: it is what a unit still runs for itself, not a standing
   part of the model, so it does not span the card either. */
.sai-box-dash {
    fill: transparent;
    stroke: hsla(0, 0%, 100%, .35);
    stroke-width: 1
}

/* The two full-width strips — Coordination at the foot of the business unit
   layer, Data at the foot of the capability layer. Same shape; the dashed
   border is set per element in the generator because only Coordination takes
   it. Coordination is a practice, data is a thing you own. */
.sai-strip {
    fill: transparent;
    stroke: hsla(0, 0%, 100%, .35);
    stroke-width: 1
}

/* The capability trees. ⚠️ NO ARROWHEAD, EVER — a spine is containment, not
   movement, and the moment it grows a head it competes with the green arrows
   for the same meaning. Thinner than any arrow for the same reason.
   ⚠️ fill:none is load-bearing: a <polyline> fills itself by default, so an
   L-shaped spine would paint a solid triangle across the box it points at. */
.sai-spine {
    fill: none;
    stroke: hsla(0, 0%, 100%, .3);
    stroke-width: 1
}

/* ⚠️⚠️ THE LAYER NAMES ARE TIER ONE — "keep the 3 layer text easy to read". They
   held at 11.5 through the tightening pass while everything under them dropped a
   fifth, and then went UP to 12.5 when the drawing went full width. 12.5 is
   inside brandon's measured band on this site (12–13.6); 11 is the site's floor
   anywhere and these are tracked caps, which read smaller than their size, so
   there is no room under this regardless.
   ⚠️ IF THE DRAWING HAS TO GET SMALLER AGAIN it comes out of the GAPS in
   /tmp/sai_teaser.py and out of tier two. Not out of this number.

   ⚠️⚠️ 13.5 → 12.5, 10-07, AND THAT IS THE FLOOR. The size went 11.5 → 12.5 →
   13.5 → 12.5 in one day, which looks like thrashing and is not: 13.5 was chosen
   at .12em tracking and the tracking then came down to the site's .1em button
   standard. Loosening tracking makes caps read SMALLER, so 13.5 had been
   compensating for it; once the tracking was correct the compensation showed up
   as bulk. "I actually think I want the brandon a tad smaller."
   ⚠️ DO NOT GO BELOW 12. Brandon's measured band on this site is 12–13.6 and 12
   is also the site's small-type floor for tracked caps. Under that it stops being
   the site's heading voice and starts being a different typeface's problem.

   ⚠️ H_CAP IN /tmp/sai_teaser.py MOVES WITH THIS, ALWAYS. The band's top padding
   is written as BAND_TOP (the gap to the TOP OF THE CAPS) and the baseline is
   derived as BAND_TOP + H_CAP, so a stale H_CAP silently changes the padding she
   asked for this morning rather than erroring. Measured, not scaled: 13.5 → 9.45,
   12.5 → 8.75. Re-measure with
       c.font='700 12.5px "brandon-grotesque", Arial, sans-serif';
       c.measureText('T').actualBoundingBoxAscent
   ⚠️ NOT getBBox on the <text>, which returns the em box. */
.sai-h {
    font-family: "brandon-grotesque", "Helvetica Neue", Arial, sans-serif;
    font-size: 12.5px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .1em
}

/* ⚠️⚠️ "THE LINE" IS NOT A LAYER AND NO LONGER DRESSES LIKE ONE, 10-07.
   "I just don't love the text here" → the caps treatment.

   It had been `class="sai-h sai-h-cap"` — BYTE-IDENTICAL to the three layer
   names. Same family, size, weight, tracking, colour, uppercase. So the picture
   had FOUR things typeset as layers and only three of them were layers; and
   because the real three each carry a sentence underneath and this one does not,
   it also read as a layer whose copy had gone missing. It is the SEAM between
   two layers, so it is set in the drawing's reading serif instead and steps out
   of the heading voice entirely.

   ⚠️ THE UPPERCASE WAS IN THE CSS, NOT THE CONTENT, so dropping .sai-h dropped
   it automatically and the label renders "The Line" — Title Case, which is the
   standing rule for titles anyway. Do not add a text-transform back.

   ⚠️ THIS INVALIDATED BOTH MEASURED CONSTANTS IN /tmp/sai_teaser.py. LINE_CAP
   and LINE_INK were measured for brandon 700 13.5 WITH .12em tracking; the serif
   at 12 is a completely different ink box (8.4 vs 9.6 tall, 46.8 vs 68.8 wide).
   Changing the font here without re-deriving them there puts the rule through the
   word again. The two files are one decision.

   ⚠️ MEDIUM ITALIC, 10-07: "let's make the line text medium italic." 500 IS THE
   HEAVIEST REAL ITALIC AVAILABLE — leo loads italic 300/400/500 only. Asking for
   600 or 700 gets a SYNTHESISED oblique, which measures 53.63 wide against the
   real face's 45.85 and drops the cap height to 8.31; it looks heavier because it
   is a different, wrong shape, not because the face got bolder. If this ever
   needs more weight, the answer is a different family, not a higher number.

   Italic is not a new voice here — .sai-cta in this same section is already leo
   italic — and it finishes the job the family swap started: the seam label now
   shares nothing with the three layer names.

   ⚠️ LINE_INK IN /tmp/sai_teaser.py MOVED WITH THIS: 46.8 → 45.85. LINE_CAP did
   NOT — the italic 500 cap measures 8.42, the same as the roman. Only the width
   changed, so only the dash start moved. */
.sai-line-l {
    font-family: "leo", Georgia, "Times New Roman", serif;
    font-size: 12px;
    font-style: italic;
    font-weight: 500;
    fill: #eae6e2
}

/* Green names the AI side of the model, off-white names the ground it stands
   on — the same two-value split the methodology drawing uses. */
.sai-h-ai {
    fill: var(--bright-green)
}

.sai-h-cap {
    fill: #eae6e2
}

/* ⚠️ THE .sai-ft* RULES ARE DELETED, 10-06: "we don't need the from to on the
   layers on the homepage."

   They styled the one FROM/TO line that survived under each layer name — four
   rules for .sai-ft, .sai-ft-k, .sai-ft-f and .sai-ft-t. They are gone rather
   than left behind because a rule that matches nothing is indistinguishable
   from a rule that is broken, and the next person would have no way to know.

   What they encoded is still true and still lives on /methodology/, which is
   where the from/to prose now exists exclusively: FROM vs TO is a VALUE step,
   not a colour change — #EAE6E2 against #FFFFFF is 1.24:1 and reads as a
   rendering error, so FROM carries 0.78 alpha for 1.78:1, and 0.78 is the AA
   floor across all four grounds. ⚠️ IF ANY FROM/TO EVER COMES BACK HERE, it
   comes back as ONE line for the whole drawing, not one per layer, and it
   copies those values from methodology.css rather than re-deriving them. */
.sai-lbl {
    font-family: "leo-small-text", "leo", Georgia, serif;
    font-size: 10px;
    font-weight: 400;
    fill: var(--white);
    text-anchor: middle
}

/* ⚠️ THE TREE'S THIRD RUNG, 10-07: "third layer like teams could go smaller."
   The capability tree is the only place in the drawing that is three deep, so
   it is the only place that needs a third size:

     .sai-card-t  12.5   Capability Portfolio 1
     .sai-lbl     10     Domain
     .sai-lbl-sm  9      Team

   ⚠️ IT IS A SEPARATE CLASS RATHER THAN A SMALLER .sai-lbl ON PURPOSE. .sai-lbl
   also sets the domains, the four run boxes and all nine unit steps; taking it
   to 9 would have shrunk two thirds of the drawing to answer a note about the
   bottom row of one layer. If the teams ever need to match the domains again,
   delete this rule and the lcls argument in /tmp/sai_teaser.py together — the
   class is referenced from the generator, so an orphan here renders at the
   inherited size and looks like the change silently failed. */
.sai-lbl-sm {
    font-family: "leo-small-text", Georgia, serif;
    font-size: 9px;
    font-weight: 400;
    fill: var(--white);
    text-anchor: middle
}

/* ⚠️ THE LINE OF COPY UNDER EACH LAYER NAME, 10-07: "my boss wants a line of
   copy with each layer." The treatment is settled and this rule is live, but
   ⚠️ NOTHING CURRENTLY USES IT. The three slots held lorem ipsum and were
   emptied on 10-07 rather than shipped to the live site, so the drawing has no
   .sai-sub elements at all right now. The rule stays because the WORDS are
   pending, not the design: put a sentence into LAYER_SUB in /tmp/sai_teaser.py
   and the line draws itself at this size.
   ⚠️ An empty slot costs ZERO height — layer_head() only adds SUB_DROP to the
   chain when the string is non-empty. Do not reserve space for the copy, here
   or in the generator, while it is pending; the band grows when the words land.

   ⚠️ 0.78 ALPHA IS NOT A TASTE CALL. It is the figure derived on /methodology/
   for the subordinate value step, where #EAE6E2 at full strength against the
   white labels measured 1.24:1 and read as a rendering error. 0.78 is the AA
   floor across all four grounds in this drawing (worst case 4.62:1 on
   --cap-surface). Do not round it to .75 or .8 without re-measuring.

   ⚠️ IT IS A VALUE STEP, NOT A COLOUR CHANGE — same off-white as the capability
   layer name, turned down. Introducing a second hue here would make it look like
   it encoded something, and it does not: it is prose, not part of the model.

   ⚠️ LEFT-ALIGNED, SO text-anchor IS NOT SET. .sai-lbl sets middle and these two
   rules sit on different elements, but if this ever gets folded in with the box
   labels the anchor is the thing that will break — the line starts at the band's
   inner edge, under the layer name, and both are x=CX in the generator. */
.sai-sub {
    font-family: "leo", Georgia, "Times New Roman", serif;
    font-size: 12px;
    font-weight: 300;
    fill: rgba(234, 230, 226, .78)
}

/* A business unit's name and a capability portfolio's name are the same thing
   one level up from a step box, so they are one rule: leo proper, one point
   above the step labels. ⚠️ The step up is SIZE AND
   FAMILY, not weight — everything in this picture stays at 400 or below, and a
   bold serif here would outshout the brandon layer names above it. */
.sai-card-t {
    font-family: "leo", Georgia, "Times New Roman", serif;
    font-size: 12.5px;
    font-weight: 400;
    fill: var(--white);
    text-anchor: middle
}

/* ⚠️⚠️ THE TWO STRIPS NOW MATCH THE ORDINARY BOX LABEL, 10-07: "the boxes here
   text could be a tad bigger like what we use for box 2 font size", pointing at
   "Data — Clean, Owned, Available Per Capability".

   ⚠️ THE NOMINAL SIZE WENT DOWN AND THE TEXT GOT BIGGER, WHICH IS NOT A
   CONTRADICTION AND IS THE WHOLE POINT OF THIS NOTE. It was leo 10.5 / 300 and
   is now leo-small-text 10 / 400, i.e. byte-identical to .sai-lbl except the
   fill. THREE things changed and only one of them was the size:

     family  leo → leo-small-text   the OPTICAL CUT for small sizes: taller
                                    x-height and sturdier strokes at the same
                                    nominal px, so it reads larger
     weight  300 → 400              leo 300 at 10px is the thinnest ink anywhere
                                    in this drawing and was ghosting on the
                                    ground
     size    10.5 → 10              the only one that went down, and it is
                                    invisible next to the other two

   ⚠️ SO "IT LOOKS SMALL" IS NOT RELIABLY A SIZE PROBLEM AT THIS SCALE. Below
   about 11px, family and weight move apparent size more than px does. Reach for
   the size last. This is the same lesson as the methodology drawing's "loose
   leading is usually a SIZE problem", pointing the other way.

   THE FILL IS THE ONE REMAINING DIFFERENCE and it is deliberate: #eae6e2 against
   .sai-lbl's pure white keeps the strips a half-step under the boxes they run
   beneath, which is what they are. If they are ever asked to match outright,
   this is the line to change — but check it against the ground first, because
   the strips sit on both --ai-surface and --cap-surface.

   ⚠️⚠️ 10 → 11.5, 10-07, AND THIS DELIBERATELY BREAKS THE MATCH WITH .sai-lbl.
   "this still feels a little small to me" — the SECOND note on this strip in a
   row, arriving after the family and weight swap above had already been tried.
   So this is the case the note above says is rare: a real size problem.

   ⚠️ THE STRIP IS NOT A BOX LABEL, AND MATCHING THEM WAS THE MISTAKE. The boxes
   are items INSIDE a layer; a strip runs the full width UNDERNEATH a whole layer
   and names what it stands on. It is a peer of the band, not a child of the
   boxes. Setting it at the box labels' size made the picture's widest, longest
   line also its smallest type, which is why it kept reading as a caption someone
   had forgotten to finish.

   ⚠️ DO NOT "RESTORE CONSISTENCY" BY RAISING .sai-lbl TO MATCH. The widest box
   label, "Solution Product Management", is ~121 units inside a 136.8-unit run
   box; at 11.5 it would be ~139 and would not fit at all. The strip has the full
   619-unit band for a 233-unit line and can afford the size. The run boxes
   cannot. Same number, two different amounts of room — and the fill difference
   above still carries the hierarchy without needing the size to. */
.sai-strip-l {
    font-family: "leo-small-text", "leo", Georgia, serif;
    font-size: 11.5px;
    font-weight: 400;
    fill: #eae6e2;
    text-anchor: middle
}

/* ⚠️⚠️ .sai-note AND .sai-note-g WERE DELETED HERE, 10-07: "or no arrow actually
   just remove that part for the homepage", then "I think getting the space back
   and better filling the 3 layers is more important than including that arrow".

   They set the return-path label that ran up the right-hand rail — the only text
   in the teaser that was ever set on its edge. The rail is gone from this drawing
   (the reasoning, and the three attempts at making it legible, are at the top of
   /tmp/sai_teaser.py under THE RETURN PATH IS NOT IN THIS DRAWING), so the rules
   went with it rather than sitting here unused.

   ⚠️ THE RULES DIED, THE FINDINGS DID NOT, and both are still live on
   /methodology/, which still draws its return path through .ret-l:
     — WEIGHT 400, NOT THE SITE'S 300. A 300 serif turned 90 degrees is the
       thinnest ink in the picture and ghosts against the ground.
     — ROTATED TEXT MUST BE ONE LINE. Rotation costs the reader a head tilt
       once; tracking back down and across for a second line costs it again, and
       that second tilt is what made the two-line version unreadable. Raising the
       size was tried first and did not fix it.
     — 11 IS THE SITE'S SMALL-TYPE FLOOR, so a rail label has nothing underneath
       it to give back when the channel needs to narrow. That is the whole reason
       this one could not be made to fit.

   ⚠️ IF A RAIL EVER COMES BACK TO THE TEASER IT NEEDS SHORTER COPY, NOT THESE
   RULES BACK. 44 characters did not fit at any angle or size. */

/* ⚠️⚠️ THE ARROW ENCODING IS THE CEO'S, NOT OURS. Verified 10-07 against his own
   file — ai-at-scale-big-picture-dark-combined.html, the source this whole model
   is ported from — by dumping every arrow in it and reading its colour, its
   direction and the two boxes it joins. His drawing has SIXTEEN arrows, SEVEN
   green and NINE white, and the split is not decorative:

     GREEN (7) — THE ONE JOURNEY THE MODEL IS ABOUT, a single loop:
       3  Fusion Team(s)   -> Coordination strip    what gets PROVEN leaves the unit
       3  Coordination     -> AI Run Layer          proven work is promoted
       1  up the far right -> back to every unit    returned as a reusable service

     WHITE (9) — EVERYTHING THAT IS LOCAL OR STANDING, i.e. true but not the story:
       3  Unit AI Strategy -> Fusion Team(s)        a step inside ONE unit's own box
       3  Fusion Team(s)   -> Unit Run              a step inside ONE unit's own box
       3  across The Line  (2 down, 1 up)           a standing two-way relationship

   So: GREEN IS MOVEMENT THROUGH THE MODEL, WHITE IS STRUCTURE THAT STAYS PUT.
   Follow it when adding an arrow — ask whether the thing travels.

   ⚠️ THE TWO ARROWS ACROSS THE LINE ARE WHITE ON PURPOSE AND THAT WAS QUERIED.
   It looks wrong at first because the lead paragraph singles The Line out, so
   the eye expects the accent there. It is right: The Line is a RELATIONSHIP, not
   a journey — the run layer and the capability foundation holding each other up.
   Making it green would say work flows across it, which is the opposite of the
   claim. ⚠️ DO NOT "FIX" THIS.

   ⚠️ OUR DRAWING IS 7 GREEN / 8 WHITE, NOT 9. The one missing white is a second
   downward crossing of The Line that this simplification does not draw. That is
   a STRUCTURE difference, not a colour one; the encoding matches his exactly.

   ⚠️ 1.2 ON BOTH, 10-07 — AND THE WHITE WAS 1.0 UNTIL TODAY. It had been cut to
   0.8x on the theory that white blooms against a dark ground and needs to be
   thinner to look equal. His file sets BOTH to 1.2 and renders at F=0.9624, so
   both land at 1.15 real pixels, deliberately identical. "Everything he did was
   intentional so let's follow his choices." The bloom is real but it was our
   correction to his drawing, not his decision, and the two arrow families are
   meant to read as the same kind of mark in two colours.
   ⚠️ /methodology/ STILL CARRIES THE OLD 1.05/0.85 PAIR and is now out of step
   with both this file and his original. Flagged, not changed — it is a different
   page and a separate call. */
/* ⚠️⚠️ THE ROUND CAP IS PART OF THE ARROWHEAD CHANGE, 10-07: "I feel like the
   arrow we use on the button is more our vibe. can we get the ones on the graphic
   more consistent." The heads became open chevrons in the <defs> (the reasoning
   is in /tmp/sai_teaser.py, next to the marker source) — but the site's button
   arrow is round-capped AND round-joined, and a round-jointed chevron on a
   square-capped shaft is visibly two different instruments meeting at a point.
   The cap belongs to the same decision as the head.
   ⚠️ IT ALSO MOVES WHERE ARROWS LAND. A round cap adds half a stroke width of ink
   at each end, so every arrow in the drawing now reaches 0.6 units further into
   the gap it crosses than its coordinates say. That is under a pixel and nothing
   was re-measured for it — but if an arrow ever looks like it is touching a box
   it should be clear of, this is why, and the fix is the coordinate, not the cap. */
.sai-arw-g {
    stroke: var(--bright-green);
    stroke-width: 1.2;
    stroke-linecap: round;
    marker-end: url(#sai-ag)
}

/* ⚠️ rgba(255,255,255,.7) IS HIS VALUE, EXACTLY — hsla(0,0%,100%,.7) is the same
   colour written the way the rest of this file writes it, and it was checked by
   computed style, not by eye. Same for the green: his is rgb(108,224,181), which
   is --bright-green. The colours were already right; only the width was not. */
.sai-arw-w {
    stroke: hsla(0, 0%, 100%, .7);
    stroke-width: 1.2;
    stroke-linecap: round;
    marker-end: url(#sai-aw)
}

/* ⚠️⚠️ THE NARROW DRAWING POINTS AT ITS OWN MARKERS, 10-07: "also the arrows are
   messed up" — every arrowhead in the phone drawing was missing.
   `url(#sai-ag)` resolves against the WHOLE DOCUMENT, to the FIRST element with
   that id. Both drawings are in the markup at all times with one display:none,
   and the wide one comes first, so at ≤767 the visible arrows were referencing a
   marker inside a hidden svg — which does not render. Eleven headless lines.
   ⚠️ NEITHER FILE WAS WRONG ON ITS OWN. The defs are fine, the rules above are
   fine; it only breaks because the page holds two copies of the drawing. The
   generator suffixes the narrow pass's ids with `-n` (see MK in sai_teaser.py)
   and these two rules are the other half of that — ANY id ever added to this
   svg needs both halves. */
.sai-svg-n .sai-arw-g {
    marker-end: url(#sai-ag-n)
}

.sai-svg-n .sai-arw-w {
    marker-end: url(#sai-aw-n)
}

.sai-dash {
    stroke: hsla(0, 0%, 100%, .32);
    stroke-width: 1;
    stroke-dasharray: 5 4
}

/* ⚠️ THE .sai-figure-link RULES ARE DELETED, 10-07, because the anchor they
   styled is gone: "the arrows are doing a weird thing on hover on the homepage
   graphic ... let's remove that." The reasoning is in section-scaled-ai.php,
   next to the markup.

   The short version, because it is the kind of thing that gets re-added: these
   two rules set display:block and a focus ring, and that was ALL they set. The
   anchor's colour, text-decoration and transition were never authored here, so
   Bootstrap's defaults had them — including `transition: all`, which animated
   the hover. ⚠️ A WRAPPER ANCHOR AROUND A DRAWING IS A HOVER TARGET THE SIZE OF
   THE DRAWING. If one ever goes back, it is styled completely on arrival, not
   partially. */

/* ── THE ACTION LOCKUP — one line of copy and the button ────────────────── */

/* 10-05. The nudge and the button are ONE THING and they move as one thing, so
   they get a wrapper. The wrapper carries no spacing of its own: the lead's
   own 1.5rem bottom margin still sets the distance down to the nudge, and
   .sai-cta's 2rem still sets the distance down to the button, so adding this
   element changed no existing measurement. ⚠️ Keep it that way — a margin here
   would double up with one of those two and the drift would read as the button
   "coming loose" from the paragraph.

   Its whole reason to exist is `order` in the narrow block below. */

/* .hv4-body p one size down, re-stated because this section has no .hv4-body.
   The .78 is the page's dark-ground body tint (homepage-v4.css:261) — one step
   back from the lead's .85, which is what makes it read as the subordinate
   line it is rather than as a second paragraph. */
.sai-nudge {
    margin: 0;
    font-size: 1.05rem;
    line-height: 1.7;
    color: hsla(0, 0%, 100%, .78)
}

/* ── THE BETA NOTICE, 10-16 ──────────────────────────────────────────────
   "we need to add some sort of copy that says this content (for this section)
   is still in beta and under development."

   ⚠️ THESE TWO RULES ARE ONE EDIT. The h2's 20px bottom margin was the whole
   of the h2 → lead seam; with a paragraph between them it has to be SPLIT, not
   duplicated, or the title block grows by a clear 20px twice over:
       h2 → notice    10   the cut below, so the notice reads as attached
                           to the title instead of floating mid-column
       notice → lead  20   the original seam, now carried by the notice
   Remove the notice and BOTH rules go with it; leaving the margin cut behind
   pulls the lead up under the headline.

   ⚠️ IT IS ITALIC, AND THAT IS THE WHOLE DEVICE. The page cannot give it an
   eyebrow (one only, on #hv4-why) and brandon tracked caps here would be an
   eyebrow in all but name, so what marks this as an editorial aside rather
   than a third sentence of the argument is the italic — the site's existing
   idiom for a line ABOUT the content rather than part of it.
   ⚠️ 400 ON PURPOSE: leo's italic 600/700 are not loaded and 500 is the
   heaviest real italic, so anything above that is a synthesised oblique.

   .95rem is the page's own small-copy size (template-homepage-v4.php:1414) and
   .78 is the shared dark-ground body tint, matching .sai-nudge. Over this
   section's #0E4D64 that composites to 6.35:1, which clears AA for small type
   with room to spare — checked rather than assumed, because the tint was
   chosen on a different ground.

   ⚠️ IF THE SECTION COMES OUT OF BETA, THIS PARAGRAPH AND THE THREE RULES BELOW
   ARE THE DELETION, and the h2's margin-bottom goes back to the page default. */
/* *** "I think I want a little more spacing between headline and beta tag."
   *** 10 → 16. ⚠️ IT CANNOT GO TO 20: the notice's own bottom margin is 20, so
   at 20/20 the line floats between the headline and the lead belonging to
   neither. 16/20 keeps it attached upward, which is the point of putting it
   under the h2 in the first place. ⚠️ AND THE TAG SITS LOWER THAN THE BOX GAP
   SAYS — the chip's ink is 18px centred in a 24.3px line box, so it starts
   ~3.2px below .sai-beta's top edge; the gap the eye reads is 19, not 16, and
   against the 23 below it that is as close as the two can get. */
#hv4-scaled .sai-copy h2 {
    margin-bottom: 16px
}

.sai-beta {
    margin: 0 0 20px;
    font-size: .95rem;
    line-height: 1.6;
    font-style: italic;
    font-weight: 400;
    color: hsla(0, 0%, 100%, .78)
}

/* *** "could I see an option where we make that beta tag a bit more
   noticeable." *** The italic sentence alone was doing the whole job quietly;
   this puts a drawn tag in front of it and takes the word "beta" OUT of the
   sentence, which would otherwise say it twice in six words.

   ⚠️ A BORDERED PILL IS NOT AN EYEBROW, AND THAT IS THE ONLY REASON THIS IS
   ALLOWED TO BE BRANDON CAPS. The one-eyebrow rule is about a bare tracked
   label floating above a headline; this is a bounded object sitting INSIDE a
   sentence, which is a different thing and reads as a status chip. ⚠️ Lose the
   border and the fill and it becomes an eyebrow again — the box is load
   bearing, not decoration.

   ⚠️ YELLOW AND NOT GREEN, AND THAT IS SEMANTIC. --bright-green is the
   DRAWING's encoding in this very section — green is movement through the
   model, white is structure that stays put — so a green chip beside it would
   be reading as part of that vocabulary. --bright-yellow is already this
   section's accent (the CTA arrow keeps it, as Why LiminalArc's does) and
   carries no meaning inside the picture. #f5b939 on #0E4D64 is 5.25:1.

   ⚠️ font-style MUST be re-declared: the parent is italic and a chip in a
   synthesised oblique brandon is not a thing this site has anywhere.
   11px is the site's type floor, reached on purpose — a tag is the smallest
   thing on the page and brandon never gets to be big. */
.sai-beta-tag {
    display: inline-block;
    margin-right: .4rem;
    padding: 3px 7px 2px;
    border: 1px solid rgba(245, 185, 57, .45);
    border-radius: 3px;
    background: rgba(245, 185, 57, .12);
    font-family: "brandon-grotesque", "Helvetica Neue", Arial, sans-serif;
    font-size: 11px;
    font-style: normal;
    font-weight: 700;
    letter-spacing: .12em;
    line-height: 1;
    text-transform: uppercase;
    color: var(--bright-yellow)
}

/* ── THE CTA ────────────────────────────────────────────────────────────── */

/* *** "this button can match the why liminalarc button exactly now." ***
   And the reason it CAN is the colour swap: this section is --dark-teal, which
   is #hv4-why's ground. The two buttons now sit on the same colour, so the
   same treatment produces the same result and there is nothing left to
   reconcile.

   SO THIS IS A DELETION, NOT A RESTYLE. Everything below used to be an
   override and is now gone:

     background: --light-green      the hero's green. It existed because the
     color: --dark-navy             section was navy and the ask was "green
                                    like the hero"
     .btn-arrow { currentColor }    because --bright-green's hard-coded
                                    --bright-yellow arrow is 1.09:1 on green
     :hover { --bright-green }      because the inherited --dark-teal hover
                                    put a navy label at 1.37:1

   Every one of those was solving a problem created by the green shape, and
   the green shape was solving a problem created by the navy ground. Remove
   the ground and the whole chain goes. ⚠️ THAT IS THE LESSON: four coupled
   overrides disappeared because one upstream value changed. When a ground
   moves, re-ask whether the workarounds on it are still earning their place
   — they will not announce that they have stopped.

   WHAT IS LEFT IS EXACTLY #hv4-why .hv4-why-cta (homepage-v4.css:6285-6291),
   restated because that rule is ID-scoped and cannot reach this section:

     margin-top: 2rem               same figure, not a rounded version of it
     :hover  --dark-green + white   the ONE override #hv4-why also carries,
                                    because .btn-outline-light's own
                                    --dark-teal hover is invisible on a
                                    --dark-teal section
     ≤767 full width                see the narrow block

   The arrow keeps its stock --bright-yellow, which is what Why's does. */
.sai-cta {
    margin-top: 2rem
}

.sai-cta:hover {
    background: var(--dark-green);
    color: var(--white)
}

/* ── NARROW ─────────────────────────────────────────────────────────────── */

/* ⚠️⚠️ THE COLLAPSE MOVED FROM 991 TO 1199 ON 10-08. Everything below this
   paragraph is the 10-07 note that established the block; only the number
   changed, and it changed for a reason the 10-07 note could not have known.

   ⚠️⚠️ THE DRAWING WAS AT ITS SMALLEST ON LAPTOPS, NOT ON PHONES. It lives in
   the 2fr track, so the 992–1199 band gave it two thirds of an already narrow
   container. Measured 10-08, drawn width and the smallest label in the picture:

       1440    731.9px   ×1.000    9.00px
       1199    657.4px   ×0.898    8.08px
        992    537.4px   ×0.734    6.61px
        991    805.2px   ×1.100    9.90px

   One pixel of extra window took it from 805 to 537 and its type from 9.9 to
   6.6. ⚠️ THE SECTION WAS WORST EXACTLY WHERE A LAPTOP SITS. One column from
   1199 down puts the whole container behind the figure, where .sai-svg's own
   `max-width: calc(732px * 1.1)` catches it at 805.2px — so 992–1199 now draws
   the picture the same size 991 already did, instead of two thirds of it.

   ⚠️ THE SAME EDIT MOVED /methodology/'s .d-view to 1200 (methodology.css, "THE
   LAYOUT SWITCH"). It is ONE decision about where a wide drawing stops being
   offered, not two coincidental breakpoints, and it was taken in one pass:
   "what makes sense for tablet?" / "let's do what you recommend", 10-08.

   ⚠️⚠️ AND THE LEAD'S MEASURE CAP CAME BACK FOR 992–1199 — see the block
   directly below this one. That is the standing "the override and the column
   count are one decision" rule firing, and it is not optional.

   ⚠️⚠️ 1440 WAS PROPOSED AND KILLED BY THE REST OF THE PAGE, NOT BY THIS
   SECTION. One column caps the figure at `732 × 1.1` = 805.2px. The 2fr track
   only reaches 805.2 when the container is 805.2 × 1.5 + 57 = 1264.8, i.e. a
   ~1577px viewport — so THE SIDE-BY-SIDE LAYOUT NEVER REACHES THE ONE-COLUMN
   SIZE AT ANY REAL WIDTH, and every collapse point has a step down on its wide
   side. On that arithmetic alone, stacking to 1440 looked like the clean fix.

   "my biggest focus is consistency ... when does the rest of the page switch?"
   Measured, every multi-column grid on this page:

                             1440  1200  1024   992   991
       .hv4-rg                  3     3     3     3     1
       .hv4-cost-grid           2     2     2     2     1
       .sai-split               2     2     1     1     1
       .hv4-order               3     3     1     1     1
       #hv4-conditions cards    4     4     2     2     2
       .hv4-steps               2     2     2     2     2
       .hv4-why-grid            2     2     2     2     1
       .cta-learning-grid       2     2     2     2     2

   ⚠️ TWO SECTIONS ALREADY CHANGE AT 1199 (conditions 4→2, order 3→1) and this
   one now moves with them. ⚠️⚠️ NOTHING ON THE PAGE CHANGES AT 1440 — not one
   grid — so 1440 would have been the only breakpoint of its kind on the site.
   1199 STANDS, and 1200–1439 stays slightly tight on purpose.

   ⚠️ THE RULE THAT CAME OUT OF THIS: a new breakpoint is justified by the
   SIBLINGS, not by the element's own arithmetic. Sweep them first —
   `getComputedStyle(el).gridTemplateColumns.split(' ').length` per section, at
   each rung of 1199/1024/991/767/480.

   ── the 10-07 note that set this block up, kept whole ──────────────────────

   ⚠️⚠️ ONE COLUMN, 10-07 — AND BEFORE THIS THE SECTION NEVER COLLAPSED
   AT ALL. The ≤1024 stacking block was deleted on 10-06 with a comment saying
   "the ≤767 block below is what collapses them". That block contained no
   grid-template-columns and never had: the section stayed 1fr / 2fr all the way
   down, so at a 375 viewport the copy ran in a 91px track and the drawing in a
   182px one. Measured, at 767 / 991 / 1199:

     767    205.98px  411.98px      drawing scaled 0.56, box labels at 5.6px
     991    279.33px  558.67px      0.76
     1199   328.71px  657.43px      0.90

   ⚠️ A COMMENT ASSERTING THAT ANOTHER BLOCK DOES SOMETHING IS NOT A TEST. Read
   the grid out of getComputedStyle before believing one.

   991 and not 767, because that is where this page already turns .hv4-lead's
   66.67% measure cap off (homepage-v4.css, "Global responsive") — the copy and
   the layout change shape in the same breath. Below it the drawing has the whole
   container, which puts the wide drawing back at roughly true scale: 795px of
   container at 991 against a 732 viewBox.

   ⚠️⚠️ THE ACTION LOCKUP SORTS PAST THE DRAWING, 10-07: "actually let's put
   'the whole model...' copy and the button under the graphic on mobile." The
   first version of this block was title → copy → button → graphic, which is the
   DOM's own order and needed no sorting at all. It is title → copy → graphic →
   nudge + button now.

   ⚠️ `order` ONLY SORTS SIBLINGS, AND .sai-action IS NESTED one level inside
   .sai-copy while .sai-figure is its uncle. The only way to sort across that is
   display:contents on .sai-copy, which drops its box and promotes h2, .hv4-lead
   and .sai-action to grid items in its place.

   ⚠️⚠️ AND THAT IS WHY THE GAP IS 0. Once the copy's three children are grid
   items, a row gap applies BETWEEN THEM TOO — 2.5rem would land under the h2 on
   top of its own 20px bottom margin. The spacing is all margins instead:
       h2 → notice      16       the h2's own margin (10-16: was 20 before the
                                 beta notice went in between)
       notice → lead    20       .sai-beta's own margin
       lead → figure    24 + 8   the lead's own margin plus .sai-figure's, = 32
       figure → action  32       .sai-action's own 2rem base, NOT overridden
   ⚠️ Put a gap back and every one of those doubles.

   ⚠️⚠️ BOTH OF THOSE SEAMS WERE 40 AND 40 IS NOT A NUMBER THIS SITE USES, 10-07:
   "this feels a little low" on the gap above the drawing and "same here - low"
   on the gap below it. 40 was not a spacing decision at all — it was whatever
   the two-column grid gap happened to contribute at this width, carried over by
   reflex when the layout stopped having columns. Measured across the mobile
   homepage, a lead followed by its block runs:

       #hv4-problem     circles grid   48
       #hv4-cost        chart grid     24
       #hv4-conditions  cards          32
       #hv4-correction  order grid     48

   32 is the value where what follows is a block of boxes, which is what the
   drawing is. ⚠️ THE SEAM BELOW THE FIGURE IS THE SAME SIZE AS THE ONE ABOVE IT
   ON PURPOSE — the drawing is one object sitting in a column of copy, and an
   object with uneven margins reads as belonging to whichever side is tighter.
   Both were complained about in the same breath for that reason.

   ⚠️ display:contents DOES NOT CHANGE SELECTOR MATCHING — `.sai-copy > :first-
   child { margin-top: 0 }` and the `.hv4-lead` max-width override above both
   still apply, because selectors run on the DOM and this only removes a box. */
@media(max-width: 1199px) {
    /* The 57px gap is arithmetic for the COLUMNS — it is the figure that lands
       both tracks on whole pixels. There are no columns here, and no gap either;
       see the note above for where the spacing went instead. */
    .sai-split {
        grid-template-columns: minmax(0, 1fr);
        gap: 0
    }

    .sai-copy {
        display: contents
    }

    /* 8 + the lead's own 24 = 32. ⚠️ .sai-action is deliberately NOT given a
       margin here — its own 2rem base is already the 32 that matches. */
    .sai-figure {
        margin-top: .5rem
    }

    .sai-action {
        order: 1
    }
}

/* ⚠️⚠️ 992–1199 ONLY, AND IT IS THE OTHER HALF OF THE COLLAPSE ABOVE.
   `#hv4-scaled .sai-copy .hv4-lead { max-width: none }` exists because the lead
   was running in a 366px track where .hv4-lead's own 66.67% would have capped
   it twice. One column removes that track — but .hv4-lead's 66.67% is still
   LIVE on the rest of the page at these widths (homepage-v4.css only turns it
   off at ≤991), so leaving `none` in place would run this section's lead at the
   full 1140px container while every other lead on the page ran 760px. The cap
   comes back for exactly the band where the page still has one.

   ⚠️ IT DOES NOT EXTEND BELOW 992. There the page has already dropped the cap
   everywhere, and this section matching it is the shipped behaviour. */
@media(min-width: 992px)and (max-width: 1199px) {
    #hv4-scaled .sai-copy .hv4-lead {
        max-width: 66.67%
    }
}

/* ⚠️ THE DRAWING SWAPS, IT DOES NOT SHRINK. Below here the wide drawing would be
   running under a factor of 0.84 and falling, which is where its box labels stop
   being readable; the narrow drawing is the same picture reflowed two across.
   ⚠️ 767 IS ALSO THE LAST LADDER NUMBER ABOVE 480, which matters now that the
   narrow drawing fills its column: everything between those two is where its
   type runs over brandon's ceiling. See .sai-svg-n above. */
@media(max-width: 767px) {
    /* ⚠️ .sai-split's 2rem margin-top was here and is GONE, 10-16 — it was the
       mobile half of the opening-offset bug written up on the base rule. The
       section now opens at the waveband's own 64, like every other flat-topped
       section at this width. Do not re-add it here either. */
    .sai-svg {
        display: none
    }

    .sai-svg-n {
        display: block
    }

    /* Byte-identical to #hv4-why .hv4-why-cta's own ≤767 block, including the
       absence of a margin change. display:flex rather than inline-flex
       because a width on an inline-flex box still sits in a line box and will
       not fill the column. */
    .sai-cta {
        display: flex;
        width: 100%;
        justify-content: center
    }
}


/* ══════════════════════════════════════════════════════════════════════════
   COLOUR TRIAL — 10-01. NAVY ON TOP, TEAL BELOW.
   ══════════════════════════════════════════════════════════════════════════

   *** "what if the ai scaled and the section above swapped bkg colors? so
   navy at the top teal at the bottom." ***

   So #hv4-conditions goes BACK to navy and #hv4-scaled becomes teal. That is
   a straight swap of the pair — the dark band still runs across two sections
   and still changes colour once in the middle of it; only the order flips.

   HISTORY, because this rule has moved three times today and each state was
   answering a different question:
     both navy       the original. The join read as a hole, not a join.
     teal / navy     "how does it look if Four Conditions and the capabilities
                     section are the same colour as Why LiminalArc", plus
                     "what ai at scale looks like section should be navy
                     still" when the first reading took both.
     navy / teal     NOW. The swap.

   *** ⚠️ #hv4-conditions GOING BACK TO NAVY IS THE FREE HALF. #hv4-scaled
   GOING TEAL IS NOT, AND THE FILE SAID SO IN ADVANCE. ***

   The previous version of this block carried the warning verbatim: "The
   diagram is drawn FOR navy and four of its values are teal #0E4D64 or a wash
   of it ... so on a teal ground every one of them becomes the ground and the
   diagram goes blank. IF #hv4-scaled IS EVER MADE TEAL, THEY COME BACK." It
   has been made teal. They are back, in the block below.

   A SECTION BACKGROUND IS NEVER ONE DECLARATION when anything is drawn on it.
   The audit that has to run on any ground change here is: every fill in the
   section that is the NEW ground colour or a wash of it, plus every wave that
   runs INTO the section, plus any knockout that repaints the ground, plus the
   texture layer. Seven things, below, and all seven fail silently.

   THE CLASS STAYS .hv4-section--navy ON BOTH. It is what gives white
   headings, an .85 lead tint and a bright-green eyebrow, and all of that is
   correct on either ground — #hv4-why is teal and carries the --teal twin of
   every one of those rules. Swapping the class would move eight text colours
   to make one background change.

   TO REVERT THE WHOLE TRIAL: delete this block to the end of the file. Both
   sections return to navy, the diagram's own values are already right for
   navy, and #hv4-conditions .wave-bottom at the top of this file is already
   display:none and stays that way.
   ────────────────────────────────────────────────────────────────────────── */

/* ⚠️ #hv4-conditions IS NOT LISTED HERE AND THAT IS THE POINT. Its navy is
   .hv4-section--navy's own, so going back to navy is a DELETION, not an
   override — and so is its .wave-top path, which is hardcoded #062935 in the
   markup and only ever needed the CSS fill while the section was teal. Both
   rules are gone rather than restated as navy. A rule that paints a thing the
   colour it already is reads like a live decision forever after. */
#hv4-scaled {
    background: var(--dark-teal)
}

/* THE TOPO MOVES WITH THE GROUND — AND IT ONLY EVER MOVES ONE WAY.
   It was --dark-teal on navy; on a teal section that is the ground painting
   itself, so it had to change.

   *** ⚠️ "topo always goes LIGHTER not darker." A STANDING RULE, 10-01. ***
   The first attempt at this was --dark-navy on teal, on the reasoning that
   navy-on-teal is just teal-on-navy upside down. IT IS NOT. A topo is a light
   source raking across a dark ground, not an arbitrary tonal offset, and
   inverting it turns the contour lines into cracks. Every instance of this
   component in the codebase already obeyed the rule and it was there to read:

     .pa-intro-bg::after    --light-green   on dark   styles.css:2979
     .pa-person.is-active   --light-green   on dark   styles.css:3325
     #fa-intro::before      --bright-blue   on dark   styles.css:4235
     .cn-engagement-bg      #4abd92         on dark   styles.css:6745
     #hv4-scaled, on navy   --dark-teal     LIGHTER than navy — it obeyed too

   So: --light-green, which is what three of those four use.

   ⚠️ THE OPACITY IS NOT INHERITABLE BETWEEN GROUNDS AND MUST BE RE-DERIVED.
   .5 was tuned for --dark-teal on navy, a near-neighbour pair; --light-green
   on teal is a far bigger jump and .5 would put a green net over the whole
   section. Matched on measured luminance delta instead of by eye: the navy
   build landed the textured ground at L=.0373 against a .0195 base, a delta
   of .0177. On teal (L=.0632), --light-green at .10 gives L=.0813 — delta
   .0181. Same strength of texture, different ink and ground.

   Then raised to .18 by eye, 10-01 ("increase opacity of top so it shows up
   more"). Matching the navy build's delta turned out to UNDER-shoot: the navy
   build's texture sat against a much darker page, so the same delta reads as
   less here. The derivation was a sane starting point, not the answer. */
#hv4-scaled::before {
    background: var(--light-green);
    opacity: .18
}

/* ── THE RE-GROUNDED FILLS ARE GONE WITH THE DIAGRAM ──────────────────────
   Four rules used to live here, re-grounding the layer, legend and knockout
   fills from navy to teal. Every one of them targeted an element that the
   10-05 rewrite deleted, so they went with it.

   ⚠️ THE LESSON THEY LEAVE IS STILL LIVE, because the next graphic will have
   the same problem: a fill is not a colour, it is a RELATIONSHIP to whatever
   it sits on. The rules re-grounded `.sai-layer--ai` but deliberately left
   `.sai-box` and `.sai-card` alone — the boxes sat inside the layer, not on
   the section, and the layer had just moved, so the nesting still read. Check
   what a fill actually sits ON, not what section it happens to be in.

   THE PICTURE NOW CARRIES ALL OF THIS INTERNALLY and is baked at the teal
   build's values. ⚠️ So if this section's ground is ever moved again, the
   image does NOT follow — it will sit as a teal rectangle on whatever the new
   colour is. The ground and the asset are now one decision. */

