/* marketing-motion.css — THE MOTION LAYER. One sibling sheet per concern; the pinned
   marketing.css and design-system.css are never edited (authorisation 3).

   Created 2026-09-02 for W5 of docs/EXECUTION-PLAN-2026-09-02.md. Everything in this file
   is built to the operator's WALK (docs/eye-gate/EYE-GATE-2026-09-02.pdf), which the
   standing ruling makes FULL AUTHORITY wherever it speaks. Where the walk contradicts an
   approved frame or a prior ruling, the walk is built and the result is labelled
   INTERIM DEVIATION · UNRATIFIED and listed for ratification. No compromise is offered.

   Every rule below is proven by p10-gates/motion (npm run motion), whose own falsifiers
   were proven to fail first (npm run motion:redfirst).
   ────────────────────────────────────────────────────────────────────────────────────── */

/* ═══ RC-10 · NOTHING OPEN AT REST ═══════════════════════════════════════════════════════
   INTERIM DEVIATION · UNRATIFIED — operator ruling R-1, 2026-09-02. THE FRAME DRAWS ITEM 1
   OPEN. The walk asks for nothing open at rest and the walk governs; this is recorded, not
   re-litigated.

   WHAT IT OVERRIDES: marketing.css:199-201 and :206 give `.acc.cat-1` the open treatment
   whenever no card is hovered. Each rule below is the SAME SELECTOR at the SAME specificity
   (0,5,1 / 0,4,0), so it wins on ORDER — this sheet is linked after marketing.css. Verified
   2026-09-02 that no later sibling touches `.acc`, `.msc-*` or `.jgrid` outside a media
   query: marketing-interaction.css matches only `.acctcard`, marketing-responsive.css only
   `.jgrid` columns and `.acctcard`.

   ⛔ SUPERSEDED 2026-09-02 BY THE D6 REVISION, STRUCK IN PLACE (S9) SO THE CHANGE IS
   AUDITABLE. The struck paragraph read:
     ~~"MEASURED CONSEQUENCE, STATED AS A FINDING RATHER THAN AS A COMPROMISE: at rest the
     left stage `.mockswap` (340 px tall) now shows NO scene. Its ink at rest is measured and
     printed in the W5 evidence. The walk rules the text side and the scene follows it."~~
   ⚠ IT WAS REPORTED HONESTLY AND IT WAS STILL THE WRONG BUILD. Stating a consequence
   plainly is not the same as being right about whether the ruling reached that far: R-1
   binds the ACCORDION, and the stage was never in its scope. The operator's revision is
   below, and the blank stage is a DEFECT against it, not a consequence of it.
   ⭐ WHAT SURVIVES UNCHANGED: hovering item 1 now animates, which is what dissolves the
   first half of walk issue 16 (`hovering the first card does nothing`).                     */

.jgrid:not(:has(.acc:hover)) .acc.cat-1 h3   { color: var(--mut); }
.jgrid:not(:has(.acc:hover)) .acc.cat-1 p    { max-height: 0; opacity: 0; margin-top: 0; }
.jgrid:not(:has(.acc:hover)) .acc.cat-1 .ico { transform: none; color: #9a9aa0; }

/* ⛔ THE FOURTH RULE IS DELETED, 2026-09-02, BY THE D6 REVISION — struck here rather than
   quietly removed, because the deleted line is the whole lesson. It read:

       .jgrid:not(:has(.acc:hover)) .msc-1  { opacity: 0; }

   R-1 was read as binding the WHOLE BAND. It binds the ACCORDION ONLY. The operator's
   revision: the left stage at rest shows the stacked cards exactly as the approved frame
   draws them — Analytics, Jobs, Affiliates on top of one another, FULL EMPHASIS, not
   dimmed, not blank (Issue 9, "cards on top of one another"; S13 branch 1 — the frame
   draws it). Hovering an item still switches the stack, unchanged.

   ⭐ NOTHING HAD TO BE INVENTED TO SATISFY THIS. The scene was already in the DOM the whole
   time: `.msc-1` holds exactly those three overlapping `.shot` cards — measured 2026-09-02,
   labels `Affiliates` / `Jobs` / `Analytics` at x 219 / 297 / 358, y 1462 / 1457 / 1424.
   The rule above was suppressing a correct scene. With it gone the PINNED
   `marketing.css:206 .jgrid:not(:has(.acc:hover)) .msc-1{opacity:1}` governs again, so the
   resting stage is the approved one and no lane-authored rule stands in its place.

   ⚠ IT SHIPPED BLANK FOR ONE WAVE AND NO METRIC I HAD COULD SEE IT — the accordion probe
   measured the accordion and reported 77/77 clean while 45% of the band's width was empty
   ground. `stage-ink-at-rest` was added to the motion gate in the same commit as this cure,
   with red-first leg L19 planting this exact deleted rule. S16: a cure that removes its
   subject from measurement is not closed. */


/* ═══ D7 · TOUCH AND KEYBOARD INPUT FOR THE ACCORDION ════════════════════════════════════
   Operator ruling, 2026-09-02: "on touch, tap does what hover does; on keyboard, focus+Enter
   does what hover does. Nothing opens without a user action, so the resting ruling is
   untouched." D7 and R-1 are consistent BY CONSTRUCTION — both require a user action first.

   State lives in `data-open` on the `.jgrid`, set by components/marketing/home/JourneysInput.tsx.
   That file owns semantics and state; every pixel below is CSS.

   ⭐ THE SPECIFICITY IS THE DESIGN, so it is written down rather than discovered later:
     pinned hover        `.jgrid .acc:hover p`                              (0,3,1)
     pinned rest-open    `.jgrid:not(:has(.acc:hover)) .acc.cat-1 p`        (0,5,1)
     RC-10's close       same selector, later sheet, wins on ORDER          (0,5,1)
     selection, below    `.jgrid[data-open="N"]:not(:has(.acc:hover)) …`    (0,6,1)
   So a SELECTION beats RC-10's closed default, and a HOVER beats a selection — because every
   rule below is scoped `:not(:has(.acc:hover))` and simply drops out while a pointer is on a
   card. That is deliberate: hover PREVIEWS, and the selection is still there when the pointer
   leaves. Nothing here can open anything on its own.

   NO FRAME draws a selected/keyboard state — the frames draw hover only — so this is
   INTERIM DEVIATION · UNRATIFIED, correctness governing (S13 branch 2). It invents no colour:
   every value below is the pinned hover treatment reused verbatim. */

.jgrid[data-open="1"]:not(:has(.acc:hover)) .acc.cat-1 h3   { color: var(--ink); }
.jgrid[data-open="1"]:not(:has(.acc:hover)) .acc.cat-1 p    { max-height: 240px; opacity: 1; margin-top: 8px; }
.jgrid[data-open="1"]:not(:has(.acc:hover)) .acc.cat-1 .ico { transform: rotate(90deg); color: var(--brand); }
.jgrid[data-open="1"]:not(:has(.acc:hover)) .msc-1          { opacity: 1; }

.jgrid[data-open="2"]:not(:has(.acc:hover)) .acc.cat-2 h3   { color: var(--ink); }
.jgrid[data-open="2"]:not(:has(.acc:hover)) .acc.cat-2 p    { max-height: 240px; opacity: 1; margin-top: 8px; }
.jgrid[data-open="2"]:not(:has(.acc:hover)) .acc.cat-2 .ico { transform: rotate(90deg); color: var(--brand); }
.jgrid[data-open="2"]:not(:has(.acc:hover)) .msc-2          { opacity: 1; }

.jgrid[data-open="3"]:not(:has(.acc:hover)) .acc.cat-3 h3   { color: var(--ink); }
.jgrid[data-open="3"]:not(:has(.acc:hover)) .acc.cat-3 p    { max-height: 240px; opacity: 1; margin-top: 8px; }
.jgrid[data-open="3"]:not(:has(.acc:hover)) .acc.cat-3 .ico { transform: rotate(90deg); color: var(--brand); }
.jgrid[data-open="3"]:not(:has(.acc:hover)) .msc-3          { opacity: 1; }

.jgrid[data-open="4"]:not(:has(.acc:hover)) .acc.cat-4 h3   { color: var(--ink); }
.jgrid[data-open="4"]:not(:has(.acc:hover)) .acc.cat-4 p    { max-height: 240px; opacity: 1; margin-top: 8px; }
.jgrid[data-open="4"]:not(:has(.acc:hover)) .acc.cat-4 .ico { transform: rotate(90deg); color: var(--brand); }
.jgrid[data-open="4"]:not(:has(.acc:hover)) .msc-4          { opacity: 1; }

.jgrid[data-open="5"]:not(:has(.acc:hover)) .acc.cat-5 h3   { color: var(--ink); }
.jgrid[data-open="5"]:not(:has(.acc:hover)) .acc.cat-5 p    { max-height: 240px; opacity: 1; margin-top: 8px; }
.jgrid[data-open="5"]:not(:has(.acc:hover)) .acc.cat-5 .ico { transform: rotate(90deg); color: var(--brand); }
.jgrid[data-open="5"]:not(:has(.acc:hover)) .msc-5          { opacity: 1; }

/* An explicit selection replaces the resting stack; the stack returns when the selection is
   cleared (Escape, or tapping the open card again). (0,6,0) beats the pinned (0,4,0). */
.jgrid[data-open]:not([data-open="1"]):not(:has(.acc:hover)) .msc-1 { opacity: 0; }

/* The keyboard affordance must be VISIBLE or it is not an affordance. `.acc h3` becomes
   role=button tabindex=0 on mount, so it needs a focus ring; `--brand` is the same token the
   dialog and the field already focus with, at the same 2px/2px geometry. */
/* EG-24 remainder (plan B7, 2026-09-06, Lane S): the accordion's focus ring migrates to --cta-fill with the ring family. The .ico
   colour rules above are NOT migrated: they mirror the PINNED .jgrid .acc:hover .ico{color:var(--brand)} (marketing.css:198) and
   moving the copy alone would split hover from open. INTERIM DEVIATION · UNRATIFIED. */
/* ⛔ SELECTOR RE-KEYED 2026-09-06 (ITEM E), same declarations, struck in place (S9):
     ~~.jgrid .acc h3[role="button"]:focus-visible~~ — the h3 no longer carries the role; the real
   <button> inside it does, and it is the element that takes focus. Values transcribed, not re-derived. */
.jgrid .acc h3 > .acc-btn:focus-visible {
  outline: 2px solid var(--cta-fill);
  outline-offset: 3px;
  border-radius: 4px;
}

/* ── D7 residue · THE ANNOUNCED CONTROL WAS 14 px UNDER THE S1 FLOOR ─────────────────────
   Found 2026-09-02 by the blind verifier, outside its brief, in code shipped the same turn.

   MEASURED: `.acc h3` — the element that carries `role="button"` and `tabindex="0"`, i.e. the
   control a keyboard or screen-reader user is TOLD about — is 374.5 x 30.0 px at 1440. S1's
   floor is 44 x 44 "regardless of clickability", so that is a 14.0 px shortfall, 68.2% of floor.
   At 390 it is 230 x 30.0 for the two cards whose titles do not wrap.

   ⚠ THE VERIFIER'S AGGRAVATING CLAIM IS REPORTED AND NOT ADOPTED, BECAUSE IT DID NOT REPRODUCE.
   It read the surrounding 494.5x72 `.acc` box as a FALSE affordance — `cursor:pointer` over an
   area 2.4x the real target, with taps 3 px inside the top and bottom edges leaving
   `aria-expanded` unchanged. Re-measured here at four points with `elementFromPoint` confirming
   the hit each time — 3 px below the top edge, 3 px above the bottom edge, on the glyph, and on
   the h3 — ALL FOUR set `data-open=3` and open the card. Pointer activation covers the whole
   72 px box and `cursor:pointer` is honest. Its reading is not explained here; the likeliest
   cause is a different scroll offset behind its absolute y coordinates, which is a hypothesis,
   not a finding. Both measurements are on the record (S9, §4).

   THE CURE: give the announced control the floor's height WITHOUT moving anything. 30 + 7 + 7 =
   44, and an equal negative margin returns the space, so the band's rhythm is byte-identical.
   This does not invent a treatment — it changes no colour, no radius and no spacing that renders. */
/* ⛔ SELECTOR RE-KEYED 2026-09-06 (ITEM E): ~~.jgrid .acc h3[role="button"]~~ → the button, which IS
   the announced control now. 30 + 7 + 7 = 44 exactly as before; the negative margin still returns the
   space. `width:100%` and `text-align:inherit` keep the box the same width the h3 had, so the 44 px
   target does not shrink to the text run (an S1 floor is a BOX, not a word).                        */
.jgrid .acc h3 > .acc-btn {
  padding-block: 7px;
  margin-block: -7px;
}

/* ═══ RC-07 · THE HERO SHUFFLE ═══════════════════════════════════════════════════════════
   Walk issue 5, the operator's words: the shuffle is "not smooth", the cards are "slanted",
   "the word fades". What he asks for: OVERHAND — the front card peels DOWN and goes BEHIND
   the stack — straight cards, no fade, visible depth.

   INTERIM DEVIATION · UNRATIFIED. This SUPERSEDES the E23 founder ruling carried in the pinned
   sheet for this element, on the standing full-authority ruling: where the walk contradicts a
   frame or a prior ruling, the walk is built, labelled, and listed for ratification. No
   compromise is offered in its place. The pinned `@keyframes shuf-cycle` and `hl-word` are not
   edited — only `animation-name` is redirected, so the originals stay readable beside these.

   The keyframes below are the plan's spec VERBATIM (docs/EXECUTION-PLAN-2026-09-02.md §W5
   RC-07) — the pinned timing with the rotation removed. They were VALIDATED BY INJECTION
   against the live page before being written to disk.

   BEFORE (measured this session, one 10.8 s cycle, ~649 frames, `/` and `/ar`):
       slant                       maxAbs 3.998 deg   (min -3.500, max +4.000)   floor 0.5
       fractional-opacity frames   141 (/) · 142 (/ar) of 1,944-1,947            floor 0
       longest blank window        734.3 ms (/) · 733.4 ms (/ar)                 floor 50 ms
       translate-step              1.883 px  ·  1.807 px                         floor 2 px  (already clean)
       depth-order-changes         9 distinct z-orders                           floor >1    (already clean)

   ⚠ WHAT THE WALK DOES *NOT* CHANGE, SAID SO IT IS NOT MISREAD AS UNTESTED: the shuffle was
   already smooth and already had depth. Two of the five falsifiers were passing before this
   commit and must still pass after it — a cure that fixed the slant by breaking the step size
   would score three greens and be worse. */

.hl-card { animation-name: eg-shuf; }
/* ⛔ THE STEPPED CYCLE IS STRUCK IN PLACE, 2026-09-06 (S9) — D2, operator: "make the animation much more smoother". It read:
     ~~0%,26% (0,0) z3 · 30% (0,22px) z3 · 33.3% (7,7) z1 · 34%,59% hold · 67%,93% (3,-4) z2 · 100% (0,0) z3~~
   The 30→33.3 % leg moved the card from (0,22) to (7,7) in 360 ms WHILE its z-index popped 3→1 — a position change with a
   simultaneous integer z step, seen as the jerk. The keyframes above it (D1's visibility) are carried into the new cycle.

   ═══ D2 · ONE CONTINUOUS PATH PER CARD (INTERIM DEVIATION · UNRATIFIED; no frame can draw a transition) ══════════════════
   Three slots, unchanged from the pinned geometry: FRONT (0,0) z3 · MIDDLE (3,−4) z2 · BACK (7,7) z1. The cycle stays 10.8 s
   and the cadence 3.6 s per word (pinned delays 0 / −7.2 s / −3.6 s ⇒ c1 → c2 → c3). Each 3.6 s slot = 2.4 s HOLD + 1.2 s MOVE
   (22.22 % + 11.11 %), and ALL THREE cards move in the SAME 1.0 s window on the same ease-in-out — offsets interpolate, never snap:
     FRONT card   24.07→28.70 % peels DOWN and slightly AWAY  translate(0,36px) scale(.96)   (500 ms, still z3 — it is on top)
                  28.70→33.33 % travels UP BEHIND to BACK      → translate(7px,7px) scale(1)  (500 ms)
     MIDDLE card  24.07→33.33 % advances to FRONT              (3,−4) → (0,0)                  (1000 ms)
     BACK card    24.07→33.33 % advances to MIDDLE             (7,7) → (3,−4)                  (1000 ms)
   THE z STEP happens ONCE, for all three cards at the SAME instant — 31.02 % of the front card's timeline, the midpoint of its
   travel leg, when it is under the advancing card (front 3→1, middle 2→3, back 1→2; in each card's own timeline 31.02 / 97.69 /
   64.36 %, which are the same wall-clock instant under the pinned delays). Fills are identical and no word is visible on a
   moving card (D1), so the step changes only which identical fill is on top; measured by pixel in D2's evidence.
   WORDS (D1): visible from the top-z instant (97.69 %) through the FRONT hold, hidden from the peel's first frame (24.08 %).
   No opacity keyframe anywhere; no rotation ("straight cards"); no leg shorter than 500 ms. */
@keyframes eg-shuf {
  /* ⛔ D1 CORRECTED 2026-09-06 (hand-check, charter §4): `visibility:hidden` on `.hl-card` hid the WHOLE CARD — fill and all —
     for the entire move window; the frozen frame f02900 and the /ar mid-peel showed no cards. The word is the card's own
     text node, so the word alone is hidden by `color: transparent` (§9b: `--ink` is in scope on `.hl-card`, the rule above
     already uses it). Adjacent keyframes 0.01 % (≈1 ms) apart make the colour change ONE frame at most — not a fade. */
  /* RE-TIMED 2026-09-06 after the native per-frame read: with a 500 ms peel-down the peak translate step was 2.17 px/frame
     (ease-in-out peaks at ~1.87× the mean), over the ≤ 2 px cap. MOVE window 1.0 s → 1.2 s (600 + 600 ms), HOLD 2.6 s → 2.4 s;
     the 3.6 s slot, the 10.8 s cycle and the single simultaneous z step (now at 30.56 % of the front card's timeline) are unchanged. */
  0%, 22.22%  { transform: translate(0,0) scale(1);        z-index: 3; color: var(--ink); }      /* FRONT hold  2.4 s     */
  22.23%      { color: transparent; }                                                            /* the peel begins      */
  27.78%      { transform: translate(0,36px) scale(.96); }                                       /* down and away 600 ms */
  30.55%      { z-index: 3; }
  30.56%      { z-index: 1; }                                                                    /* under the next card  */
  33.33%      { transform: translate(7px,7px) scale(1); }                                        /* settled at BACK      */
  55.56%      { transform: translate(7px,7px) scale(1);    z-index: 1; }                         /* BACK hold            */
  63.88%      { z-index: 1; }
  63.89%      { z-index: 2; }
  66.67%      { transform: translate(3px,-4px) scale(1); }                                       /* settled at MIDDLE    */
  88.89%      { transform: translate(3px,-4px) scale(1);   z-index: 2; color: transparent; }     /* MIDDLE hold          */
  97.22%      { z-index: 2; color: transparent; }
  97.23%      { z-index: 3; color: var(--ink); }                                                 /* front: word on       */
  100%        { transform: translate(0,0) scale(1);        z-index: 3; color: var(--ink); }
}

/* The word SLIDES UNDER A CLIP instead of fading: opacity is 1 at every keyframe and the glyphs
   travel out of the box. ⚠ THE CLIP IS TIGHT AND THE NUMBER IS RECORDED RATHER THAN ASSUMED —
   measured at deviceScaleFactor 2 with the word frozen at its resting position, the h1 made
   transparent so only the word paints, and the ground DERIVED from the capture: ink spans device
   rows 22-120 inside a 121-device-px line box, i.e. the descender bottom clears the box floor by
   ONE device pixel (0.5 CSS px). It fits, and it fits by half a pixel. */
.hl-words { overflow: clip; }
/* ROW 135-B · the clip's INLINE margin only — NO FRAME — correctness governs (S13-VERDICT.md 135-B). The reel above is
   the ruled INTERIM DEVIATION; this rule does not touch its timing, its keyframes, or the block axis.
   MEASURED 2026-09-05 on :4320 (reel frozen at rest, pixel diff of the .hl-words box +40 px, clip ON vs `overflow:visible`,
   capture scale 1 and 2): the final glyph tail of the RESTING word `.hl-w.w1` on /ar (ر of أكبر — rtl, so inline-end is the
   LEFT edge) was cut by 2.0 px × 5 px (scale 1: 7 px differing at x −2.0..0, rows 46–51) and 2.5 px × 4.5 px (scale 2: 23 px),
   AT the S1 2 px floor, identical at 1920/1440/1280 (fixed 1200 px canvas). The range rects read this cut as 0 — it is ink
   beyond the glyph advance, so only a pixel read sees it.
   THE CURE: `overflow: clip` clips at the PADDING edge, so 4 px of inline padding widens the clip box; the same 4 px is given
   back as negative inline margin, so the margin box, the line layout inside `.hl`, the `.hl-card` stack (absolute in `.hl`) and
   every word position are unchanged — measured: `.hl` rect, `.hl-w.w1` rect and its text box byte-identical on 10/10 cells;
   `.hl-words` x −4, w +8. 4 px = the 2.5 px cut + 1.5 px headroom for other scripts' tails.
   AFTER (same probe): /ar 0 px differing at both scales; / UNCHANGED at 7/16 px — a 0.53 px descender row at the BOTTOM,
   below floor, recorded (block axis, not this row); the parked reel words w2/w3 leak 0 px on /ar / /es /hi /mr and are
   UNCHANGED on /bn (52/232 px, pre-existing at rest — OWED, separate row).
   REJECTED BY MEASUREMENT: `overflow-clip-margin: 4px`. Chromium 152 supports only the ALL-SIDES form (`overflow-clip-margin-inline`
   is unsupported: CSS.supports false), and all sides re-exposed the parked words — /bn 52→162 px (×1), 232→652 (×2); /mr 0→49 / 0→224.
   ALSO FOUND, NOT CURED HERE: /hi and /mr are cut at the TOP by 4.0 px (×1) / 3.0 px (×2) across ~260 px (Devanagari upper
   marks) — above floor, block axis, its own row. §9b: no var() used (`--tint` / `--brand` do resolve on `.hl-words`, measured). */
.hl-words { padding-inline: 4px; margin-inline: -4px; }
/* ⛔ SUPERSEDED 2026-09-02 — `eg-word` is struck in place (S9) and its keyframes are kept in the
   comment because the DEFECT they caused is the reason the reel exists. It read:
     ~~@keyframes eg-word{0%{translateY(110%)} 4%,26%{translateY(0)} 31%,100%{translateY(-110%)}}~~
   It cured the fade — 141 fractional-opacity frames -> 0 — and left an ABSENCE in its place: a
   word is >=50% inside its box for only 26.50% of the cycle while three words offset by 33.33%
   need 33.33% each, so the box emptied for 465-600 ms, three times a cycle, in 12 of 12 measured
   cells. The blind verifier, given only the operator's words, called it "worse than what he
   objected to".

   ═══ THE REEL — remedy (b), operator ruling 2026-09-02 ═══════════════════════════════════════
   His reasoning, recorded because it is the reason this shape was chosen over remedy (a):
   BOTH remedies put two partial words in the box during the crossing, so (a) buys the same
   visual event with no directional logic behind it; a reel moves ONE direction, so the box shows
   the TAIL of one word leaving and the HEAD of the next arriving, which reads as motion rather
   than as two words competing for one slot.

   ⚠ NO FRAME. A static export cannot specify a transition, so the approved corpus is
   STRUCTURALLY SILENT here — this is S13 branch 2 and correctness governs, bounded by Issue 5's
   words. No frame was searched for; there is none to defer to. INTERIM DEVIATION · UNRATIFIED.

   THE CONSTRUCTION, and it is arithmetic rather than taste. The words are offset by exactly 1/3
   of the cycle (delays 0s / 3.6s / 7.2s of 10.8s). For the box never to empty, word k's slide-OUT
   must occupy exactly the interval of word k+1's slide-IN. Word k+1's slide-in is [0, A] of its
   own timeline = [33.33, 33.33+A] of word k's. With A = 4% — the EXISTING slide duration, so the
   word's velocity is unchanged and only its exit TIMING moves — the crossing is [33.33, 37.33].
   During it, k sits at -110*e(f) and k+1 at +110*(1-e(f)) for the same easing: k has ink while
   e < 0.909, k+1 while e > 0.091, and those cover e in [0,1] with NO GAP.

   ⭐ AXIS, MEASURED PER LOCALE AND NOT INHERITED FROM en: `.hl-words` is `direction: rtl` on /ar
   and ltr elsewhere, but `writing-mode` is `horizontal-tb` in both, and the measured translate is
   IDENTICAL — tx [0,0], ty [-66.516, 0] on / and on /ar. `direction` mirrors the INLINE axis; the
   reel travels the BLOCK axis. So the ar reel direction is UPWARD, the same as en: the outgoing
   word exits through the TOP and the incoming enters from the BOTTOM. Nothing here uses a
   physical horizontal offset, so there is no left/right to mirror. */
/* ⛔ THE REEL IS STRUCK IN PLACE, 2026-09-06 (S9) — SUPERSEDED BY THE OPERATOR'S NEWER WORD (EG-5 REOPENED, 14:0x CT):
   "the card moves like a shuffle and then the word fades out and next words fade in, not following my overhand shuffle
   criteria". Remedy (b) above was ruled 2026-09-02 and it is honoured here as history; the cards' `eg-shuf` and this
   reel were TWO INDEPENDENT ANIMATIONS on one phase, which reads as "card moves, THEN the word changes". The keyframes
   below are kept, unused, so the struck construction stays auditable. The line read:
     ~~.hl-w { animation-name: eg-reel; }~~
   The cure — the word RIDES the card — is the EG-5b block at the end of this sheet. */
@keyframes eg-reel {
  0%      { opacity: 1; transform: translateY(110%); }    /* below the box                        */
  4%      { opacity: 1; transform: translateY(0); }       /* arrived                              */
  33.33%  { opacity: 1; transform: translateY(0); }       /* held 29.33% of the cycle, was 22%    */
  37.33%  { opacity: 1; transform: translateY(-110%); }   /* exits the TOP as the next arrives    */
  100%    { opacity: 1; transform: translateY(-110%); }   /* parked off-box                       */
}

/* Reduced motion: the pinned sheet already stops both animations and pins w1 visible. Restated
   here because `animation-name` above would otherwise re-arm them at this sheet's later order. */
@media (prefers-reduced-motion: reduce) {
  .hl-card, .hl-w { animation: none; }
  .hl-w.w1 { opacity: 1; transform: none; }
}
/* ⚠ the reduced-motion arm above is AMENDED by the EG-5b block at the end of this sheet: w1 is no longer the
   painted word (the card c1 carries it), so `.hl-w.w1 { opacity: 1 }` there is overridden later at equal specificity. */

/* ── ROW 109, 2026-09-04 — THE TOGGLE'S 200 ms CROSS-FADE RAN UNDER prefers-reduced-motion: reduce ────
   MEASURED on :4320 before this rule, per animation frame at NATIVE speed (16.7 ms frames), 10 cells
   (/ + /ar × 1920/1440/1280; /bn /es /hi /mr × 1440), pointer parked and verified:
     · HOVER enter/leave, either label: 0 frames below 4.5 on 10 of 10 cells. The hover cross-fade the row
       describes no longer exists — RC-13 (2026-09-03) deleted the display-swap that produced it.
     · The CLICK SWAP (`:checked` moving between the radios) is where the trough lives now: BOTH labels
       fall to 1.11–1.38:1 for 6–7 frames — sub-4.5 window bounded 83–102 ms (inner) / 108–135 ms (outer),
       ease-model 111.4 ms (checked label) / 100.9 ms (unchecked) — on 10 of 10 cells, both directions.
     · With `prefers-reduced-motion: reduce` emulated the transition still read `background 0.2s, color 0.2s`
       and the same trough ran. Nothing in the 15 sheets disarmed `.th-lab`; this block (:242-245) covered
       only .hl-card/.hl-w. Under §S1 a trough of ANY duration is a finding when reduced motion is set.
   THIS RULE CURES THE REDUCED-MOTION ARM ONLY. Same selector and specificity (0,2,0) as marketing.css:260
   (and its inlined copy in marketing-critical.css); this sheet is linked LATER (layout.tsx:209 vs :151), so it
   wins on order — verified in the browser, not assumed: computed `transition` reads `none`/`all 0s` under reduce.
   ⚠ THE NO-PREFERENCE ARM IS UNTOUCHED — S13 DISAGREEMENT, REPORTED NOT CHOSEN: marketing.css is vendored
   byte-identical from the approved Home.html <style>, and :260 specifies the .2s cross-fade. The frame
   specifies the transition; §S1 measures it below the floor for ~100 ms. Recorded in the row; not decided here. */
@media (prefers-reduced-motion: reduce) {
  .toggle .th-lab { transition: none; }
}

/* ── ROW 109 ALWAYS-ON ARM / OWED-BV-3, 2026-09-04 — THE CLICK-SWAP CROSS-FADE TROUGH, NO-PREFERENCE ARM ─────────
   MEASURED on :4320 (sheets worktree, 14959a8c) BEFORE this rule, per animation frame at NATIVE speed, pointer parked
   at (0,0) and VERIFIED (`.toggle .th-lab:hover` count 0 on 20 of 20 per-frame cells), 10 cells (/ + /ar ×
   1920/1440/1280; /bn /es /hi /mr × 1440), no-preference arm, 4 scenarios × 2 labels = 80 label-scenarios:
     · CLICK SWAP (`:checked` moving between the radios): sub-4.5 trough on 40 of 40 click label-scenarios, both
       labels, both directions — worst 1.052:1, 4–7 frames below the floor, sub-floor window inner 50.0–102.4 ms /
       outer 82.5–134.2 ms. Against the §S1 100 ms line: 5 label-scenarios BOTH windows > 100 ms, 25 STRADDLE
       (inner < 100 < outer), 10 BOTH < 100 ms. The trigger is the CLICK, not hover.
     · HOVER enter / leave: 0 of 40 label-scenarios below the floor (the row's filed "on every hover" is REFUTED).
     · Reduce arm (regression leg): 0 of 40; computed transition-property `none` 20 of 20 — the :264-266 cure holds.
     · CASCADE: computed transition-property `background, color` on 60 of 60 label-cells (6 routes × 5 vp × 2).
   ROOT: 1 declaration — marketing.css:260 `transition:background .2s,color .2s` (PINNED) and its inlined copy in
   marketing-critical.css (generated, regenerated by INT #4, never typed). 12 label occurrences on 6 routes; 30
   route-cells of the 600-cell sitemap set; demo path 6 of 30 (/ + /ar × 3 desktop); the other 8 demo routes
   render 0 `.th-lab`.
   RULING APPLIED — INFERRED operator ruling, phase.json inferred_rulings_2026-09-04_1800[0], verbatim:
     "(b) transition:none for .toggle .th-lab OUTSIDE the reduced-motion query, in marketing-motion.css (sibling
      sheet; marketing.css:260 pinned) — labelled S13 INTERIM DEVIATION · UNRATIFIED (the frame specifies the .2s
      cross-fade); founder may override"
   S13 INTERIM DEVIATION · UNRATIFIED — frame specifies the .2s cross-fade (marketing.css:260 pinned; the frame is
   Candidate/Home to Apply Jobs/Home.png → /, frames-to-routes.tsv:6). The founder reverses it by deleting this block.
   No var() — nothing to §9b scope-check. Same selector and specificity (0,2,0) as :260 and its inlined copy, no
   !important on either side; ~~this sheet is linked LAST (layout.tsx:209, after <CriticalCss/> :150 and marketing.css
   :151)~~ — STRUCK IN PLACE 2026-09-04 (S9), found FALSE by the blind verifier: layout.tsx links marketing-alignment.css
   :218, marketing-lift.css :225 and marketing-target.css :229 AFTER this sheet (:209). The cure still holds because NONE
   of those three declares a `.th-lab` transition — `grep -n 'th-lab' marketing-{alignment,lift,target}.css | grep -c
   transition` → 0 / 0 / 0 (positive control: this sheet → 3). So this rule is the LAST `.th-lab` transition declaration
   in cascade order, after <CriticalCss/> :150 and marketing.css :151, and wins on ORDER over :260 and its inlined
   copy — verified as the COMPUTED value in the browser (cascade leg, 60 label-cells), never assumed from the text.
   The cure makes the > 100 ms sub-question MOOT (trough duration 0 ms); it does not ANSWER it — NOT PROVEN stands.
   The reduce-arm block above (:264-266) is CLOSED evidence, now redundant; left in place (R6). */
.toggle .th-lab { transition: none; }


/* ═══ EG-10 · B8 · THE TRANSFORM BAND'S FEATURE ROWS ARE DROP-TABS ═══════════════════════════
   Lane C2 (component-surgeon), 2026-09-06. Appended as a DELIMITED BLOCK AT THE END of this sheet:
   it is the sheet that already carries the journeys accordion's D7 mechanism, which these rows
   reuse (S14, one technique); lane S owns -interaction / -pricing / -critical this batch, and the
   pinned marketing.css:276-278 (`.sell`, `.sell .si`, `.sell .si .sic`) is never edited.

   AUTHORITY: the operator's walk, Issue 10 + references 1-4 (docs/eye-gate PDF pp. 7-9) — "drop
   tabs similar to the design and animation of Building Career Journeys … when you hover over a
   card, it opens, expands, and shows the arrow moving". The 09-05 ruling makes the walk the ruling;
   the vault `Home.html` frame draws static cards. INTERIM DEVIATION · UNRATIFIED for this band.

   WHAT IS TAKEN FROM THE NEIGHBOUR, VERBATIM (marketing.css:190-198 + this sheet's D7 block):
     open panel      max-height:240px; opacity:1; margin-top:8px       (`.jgrid .acc:hover p`)
     closed panel    max-height:0; opacity:0; overflow:hidden; transition max-height/opacity/margin .35s
     arrow           rotate(90deg) + var(--brand) on open; #9a9aa0 at rest; transition .3s/.25s
     focus ring      2px solid var(--brand), offset 3px, radius 4px  (`.jgrid .acc h3[role=button]:focus-visible`)
     control size    padding-block / negative margin-block (+ min-height 44 border-box) to reach S1's 44 px without moving anything
   WHAT IS THE ROW'S OWN (the pinned `.sell .si` label look, marketing.css:277): 14.5px / 600 / var(--ink),
   body font — so the label reads exactly as the frame draws it; only the row GAINS a body and an arrow.

   §9b: every var() here (--brand, --ink, --mut, --font-body) is defined on `.page`, and `.sell` is
   a descendant of `.page` (measured in the browser: getPropertyValue('--brand') on a `.si` → #2164F4).

   ⛔ ONLY A ROW THAT CARRIES A BODY IS A DROP-TAB. The selectors below key on the <h3> the component
   emits only when a body exists (SellList.tsx), so a locale without bodies (ar today) keeps the
   pinned static card untouched — no empty drop, no dead control.

   THE GAP (marketing.css:276 `.sell{gap:12px}`): a `::after` of exactly the gap's height under each
   drop-tab row makes the pointer's hover area CONTIGUOUS, so crossing from row 1 to row 2 never
   passes through a no-row-hovered state (the journeys DO release in their gap — motion-probe
   `gap-1-2` measures that as "collapses, then the next card opens"; here it cannot happen).
   Nothing paints in the pseudo-element; it is hit-testing only.                                */

.sell .si:has(> div > h3)          { align-items: flex-start; cursor: pointer; position: relative; }
.sell .si:has(> div > h3)::after   { content: ""; position: absolute; left: 0; right: 0; top: 100%; height: 13px; }
/* ↑ 13, not 12: `top:100%` resolves against the PADDING box, i.e. 1px above the border-box bottom
   (the row's 1px border), so a 12px box left a 1px sliver of un-hovered gap — MEASURED 2026-09-06 as
   2 frames of "no row hovered" in a 184-frame row-1→row-2 crossing at 2px/frame. 12 + 1 = 13 reaches
   exactly the next row's top edge. */
.sell .si > div:has(> h3)          { flex: 1; min-width: 0; }
.sell .si h3 {
  font-family: var(--font-body); font-size: 14.5px; font-weight: 600; letter-spacing: normal;
  color: var(--ink); margin: 0;
  min-height: 32px; display: flex; align-items: center;   /* the label centres against the 32 px chip, as the static card did */
}
.sell .si p {
  font-size: 14.5px; font-weight: 400; color: var(--mut); line-height: 1.5; margin: 0; max-width: none;
  max-height: 0; opacity: 0; overflow: hidden;
  transition: max-height .35s ease, opacity .35s ease, margin .35s ease;
}
.sell .si .ico {
  flex: none; margin-inline-start: auto; margin-top: 5px; color: #9a9aa0;   /* far edge in BOTH directions — no RTL rule needed */
  transition: transform .3s ease, color .25s ease;
}

/* hover PREVIEWS; real keyboard focus (:focus-visible) does the same — the brief's "expands on
   hover AND keyboard focus". Journeys open on Enter only; this band opens on focus as well, which is
   the ONE deliberate difference from the sibling, and it is recorded. */
.sell .si:hover p,    .sell .si:has(h3:focus-visible) p    { max-height: 240px; opacity: 1; margin-top: 8px; }
.sell .si:hover .ico, .sell .si:has(h3:focus-visible) .ico { transform: rotate(90deg); color: var(--brand); }

/* a SELECTION (tap / Enter, data-open on the .sell — JourneysInput.tsx) holds while no row is hovered,
   exactly the journeys D7 rules with `.jgrid`/`.acc` → `.sell`/`.si`. */
.sell[data-open="1"]:not(:has(.si:hover)) .si.cat-1 p    { max-height: 240px; opacity: 1; margin-top: 8px; }
.sell[data-open="1"]:not(:has(.si:hover)) .si.cat-1 .ico { transform: rotate(90deg); color: var(--brand); }
.sell[data-open="2"]:not(:has(.si:hover)) .si.cat-2 p    { max-height: 240px; opacity: 1; margin-top: 8px; }
.sell[data-open="2"]:not(:has(.si:hover)) .si.cat-2 .ico { transform: rotate(90deg); color: var(--brand); }
.sell[data-open="3"]:not(:has(.si:hover)) .si.cat-3 p    { max-height: 240px; opacity: 1; margin-top: 8px; }
.sell[data-open="3"]:not(:has(.si:hover)) .si.cat-3 .ico { transform: rotate(90deg); color: var(--brand); }
.sell[data-open="4"]:not(:has(.si:hover)) .si.cat-4 p    { max-height: 240px; opacity: 1; margin-top: 8px; }
.sell[data-open="4"]:not(:has(.si:hover)) .si.cat-4 .ico { transform: rotate(90deg); color: var(--brand); }

/* the announced control: ring + size, copied from the journeys' D7 rules. 32 + 6 + 6 = 44. */
/* ⛔ RE-KEYED 2026-09-06 (ITEM E), declarations unchanged and transcribed:
     ~~.sell .si h3[role="button"]:focus-visible~~ · ~~.sell .si h3[role="button"]~~ */
.sell .si h3 > .acc-btn:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; border-radius: 4px; }
.sell .si h3 > .acc-btn               { padding-block: 6px; margin-block: -6px; min-height: 44px; }
/* ↑ min-height 44 on the CONTROL variant: the page is `box-sizing: border-box`, so the 32px min-height
   above INCLUDES the 6+6 padding and a one-line label measured 32px tall, not 44 — MEASURED 2026-09-06
   at 768 (614x32) while a two-line label at 1440 read 266x46. 44 border-box − 12 padding = the same
   32px in flow, so the resting row is unchanged (60 / 62px, as before B8). */

/* reduced motion: the drop happens, it does not animate. (The journeys `.acc p` carry NO such arm
   anywhere in /design — 0 reduced-motion blocks mention `.acc`, positive control 4 blocks in this
   sheet — reported as a finding, not cured here: not this row's root cause.) */
@media (prefers-reduced-motion: reduce) {
  .sell .si p, .sell .si .ico { transition: none; }
}
/* ═══ end EG-10 · B8 ═══════════════════════════════════════════════════════════════════════════ */


/* ═══ EG-5b · THE WORD RIDES THE CARD — OVERHAND SHUFFLE (operator, 2026-09-06 14:0x CT, walk issue 5 REOPENED) ═══════
   Lane C2 (component-surgeon). INTERIM DEVIATION · UNRATIFIED — the walk is full authority where it speaks; NO FRAME
   can draw a transition (S13 branch 2). His words: "the card moves like a shuffle and then the word fades out and next
   words fade in, not following my overhand shuffle criteria". Earlier: "the stutter issue is fixed" — the smoothness of
   `eg-shuf` (:190-197) is UNTOUCHED: same keyframes, same 22 px peel, same z 3→1→2, no opacity keyframe anywhere (1 at
   every frame by omission).
   WHAT CHANGED: HomeMarketing.tsx renders each rotating phrase INSIDE its card (c1↔w1, c2↔w2, c3↔w3 — mapped by class;
   the DOM order is c3,c2,c1 and the cycle order is c1→c2→c3 by the pinned delays 0/−7.2s/−3.6s). The word now travels
   with its card, peels down with it and goes behind the stack with it; the next card slides up into place with its own
   word already on it. `.hl-words` stays as the LAYOUT box (the widest word sizes `.hl`, so the stack's inset:0 still fits
   every phrase) and as the accessible-name placeholder (ROW 82: w1 names the h1; the stack is aria-hidden) — it no
   longer PAINTS: the pinned base `.hl-w{opacity:0}` holds once its animation is none.
   MEASURED BEFORE (EG5b/before.json, 1440, / and /ar): cards "" italic z 1/2/3 `eg-shuf`; words `eg-reel` w1 op 1;
   `.hl-stack` z-index −1 and `elementFromPoint(.hl centre)` = SPAN.hl-w — the words painted OVER the stack, so text on
   the cards would sit under the (invisible) word layer: the stack is lifted to z 0 inside `.hl`'s own isolated context
   (marketing.css:87 `.hl-stack{z-index:-1}` PINNED; overridden here at equal specificity by order). Nothing else in `.hl`
   paints — it has no background — so lifting the stack changes hit-testing only.
   §9b: `--ink` is defined on `.page`; `.hl` is inside `.page` (the pinned `.hl{color:var(--ink)}` already relies on it).
   /ar: direction mirrors the INLINE axis; the peel is BLOCK-axis and the text is grid-centred — nothing to mirror.      */
/* ⛔ SUPERSEDED 2026-09-06 ~15:2x CT by ITEM R (the operator's vertical reel). STRUCK IN PLACE, S9 — the cards are gone
   from the DOM (HomeMarketing.tsx), so these three rules now match NOTHING and are kept only so the change is auditable:
     ~~.hl-stack { z-index: 1; }~~
     ~~.hl-card  { display: grid; place-items: center; font-style: normal; white-space: nowrap; color: var(--ink); }~~
     ~~@media (prefers-reduced-motion: reduce) { .hl-card.c2, .hl-card.c3 { visibility: hidden; } }~~
   `@keyframes eg-shuf` (:203) and `.hl-card{animation-name:eg-shuf}` (:183) likewise apply to no element now; they are
   left readable rather than deleted (zero-deletion, R6) and are inert — VERIFIED by CSSOM: 0 elements match `.hl-card`.
   THE ONE RULE BELOW IS STILL LOAD-BEARING and must not be struck with them: without it the PINNED `.hl-w{animation:
   hl-word …}` (marketing.css:105) fades the three name-placeholder words back IN over the reel — two words at once. */
.hl-w     { animation: none; }                 /* the reel: off. Pinned base keeps opacity 0 → layout + name only     */
/* ↑ 1, not 0 — MEASURED 2026-09-06 AFTER the first cut: with z-index 0, `elementFromPoint(.hl centre)` still returned
   SPAN.hl-w. The pinned `.hl-w{transform:translateY(14px)}` makes every word span a positioned-layer paint (a transform
   creates a stacking context painted with z-index:auto items), later in the DOM than the stack, so the transparent words
   still painted OVER the cards at z 0. Any positive z-index puts the stack above them; the words never set one. */
/* reduced motion: `.hl-w.w1` must NOT paint — the reel's item 1 is the visible word and w1 would double it. */
@media (prefers-reduced-motion: reduce) {
  .hl-w.w1 { opacity: 0; }
}
/* ═══ end EG-5b ═══════════════════════════════════════════════════════════════════════════════════════════════════════ */


/* ═══ EG-9b · THE JOURNEYS STAGE — CENTRED AGAINST THE LIST, CARD AS WIDE AS THE COLUMN (operator, 2026-09-06, walk issue 9
   REOPENED, screenshot at 1490) ═══════════════════════════════════════════════════════════════════════════════════════════
   Lane C2. His words: "first drop down animation doesnt have card and card is too small and also not in the center its
   upward aligned". INTERIM DEVIATION · UNRATIFIED — the frame (Home.html) draws the 316 px `.scard` and a top-aligned
   grid; the walk governs.
   MEASURED BEFORE (EG5b/before.json, 1440 and 1490, / and /ar): `.jgrid{align-items:start}` (PINNED); `.mockswap` 340 px
   top-aligned against a 494–504 px list → stage centre 77–82 px above the list centre; the hovered `.scard` 316 px in a
   449.5 px column (70.3 %), card centre 100–112 px above the list centre. The resting fan (`.msc-1`: 3 `.shot` + `.ai-tag`)
   spans 447 px = 99.5 % of the column and occupies the TOP 277 px of the 320 px `.mock` (shots at top 20/40/54, rotated), so
   its bbox centre sits 21 px above the mock's centre even once the mock is centred.
   THE CURE, each rule beating a PINNED value by ORDER at equal specificity or by one class of specificity:
     `.mockswap{align-self:center}`   new property; centres the 340 px stage against the grid row (= the list's height). Only
                                      the stage moves; the list is the taller track so it is unaffected. Stacked (≤1279) the
                                      grid is one column and align-self is inert.
     `.mscene .scard{width:100%}`     (0,2,0) over the pinned `.scard{width:316px}` (0,1,0): the single card fills the column.
     `.msc-1 .mock{height:277px}`     (0,2,0) over `.mock{height:320px}` (0,1,0): the mock is a POSITIONING box that paints
                                      nothing; sizing it to the fan's measured extent (1.8 + 274.7 px at 1440) lets the
                                      flex centring in `.mscene` centre the FAN rather than an empty 43 px band below it.
   NOTE ON DEFECT (1) "first drop-down has no card": NOT REPRODUCED at 1440/1490 headless — `.msc-1` reads opacity 1 with the
   fan present at rest, on hover of item 1 and with item 1 selected (data-open=1); recorded in the lane report, not cured here. */
/* ⛔ J2 (3), operator 16:32: "Make sure that whenever the box is actually dropped down, it does not
   affect the positioning or the movement of the card on the right." `align-self: center` (EG-9b, my
   own 14:xx cure) centres the 340 px stage against the GRID ROW, and the grid row is as tall as the
   LIST — so every row that opens taller or shorter than the last re-centres the fan. Same defect
   class as ITEM T's card, one band up.
   THE CURE KEEPS BOTH RULINGS: centring stays; what is removed is the list's height CHANGING. Every
   open panel reserves the same 5 lines (`min-height: 5lh`, with a px fallback for engines without
   `lh`), so whichever row is open the column is the same height and the fan cannot move. A body
   shorter than 5 lines simply leaves space inside its own card — no layout outside it moves.
   ⛔ AND THAT WAS NOT ENOUGH ON ITS OWN — MEASURED, so the second half is here rather than assumed:
   with the panels reserved, the list still moved 12.0 px across the six states on `/` (624.4 rest ·
   632.4 ×4 · 636.4 on row 3) and 8.0 px on `/ar` (635.9 · 643.9 ×5) — the residue is the open panel's
   8 px margin at rest versus hover, plus one row whose heading wraps. Rather than chase two causes
   worth 12 px, the LIST COLUMN reserves a height that no state reaches, so its height is a constant
   and the centred fan has nothing to re-centre against.
   ⚠ THE VALUE IS A MEASURED px AND IT CARRIES ITS COVERAGE: 660 px covers `/` (max 636.4) and `/ar`
   (max 643.9) at 1440 with 16 px of headroom. `/es` is the only other root with this band (`/hi`,
   `/bn`, `/mr` do not render `.p-jour` at all — measured, the probe found no such element). A locale
   whose list is naturally taller than 660 px would simply grow and move again; that is the limit of
   this cure, stated. */
.mockswap       { align-self: center; }
/* STRUCK IN PLACE 2026-09-07 by P3-OP-19 (S9 - the superseded lines are kept so the change is
   auditable, never deleted). The 5lh / 109 px PANEL RESERVE stood here, on this selector list:
     ~~.jgrid .acc:hover p, .jgrid .acc:has(.acc-btn:focus-visible) p,~~
     ~~.jgrid:not(:has(.acc:hover)) .acc.cat-1 p,~~
     ~~.jgrid[data-open="1"]:not(:has(.acc:hover)) .acc.cat-1 p, ... cat-2 ... cat-3 ... cat-4 ... cat-5~~
     ~~  { min-height: 109px; min-height: 5lh; }~~
   WHY IT GOES. MEASURED on :4360 this session (BEFORE-4360.json, 9 of 9 cells, coverage asserted
   inside the instrument): the reserve applies to `.acc.cat-1 p` at REST as well, where the CLOSING
   arm at :39 above holds opacity 0 - so row 1 rests as a 176.75 px card holding a 108.75 px body box
   that paints nothing. phantomCount = 1 on every one of the 9 cells. That is the operator's
   "the body text disappears but the tab stays open".
   AND IT IS ALSO THE STUTTER. `min-height` here carries NO transition while the pinned
   `.acc p{transition:max-height .35s}` (marketing.css:192) does, so an open was ONE 108.75 px frame
   (/ and /es) or 134.06 px (/ar) and then nothing: rafOpen maxFrameDelta 108.75, movingFrames 1,
   durationMs 0. A 109 px snap is not an animation.
   WHAT REPLACES IT: the Transform band's grid-template-rows mechanism, at the end of this file.
   WHAT KEEPS J2's PROMISE: `.jgrid > div:has(.acc){min-height:660px}` on the next line is a SEPARATE
   reserve and is UNTOUCHED - it is the one that actually holds the deck still, and the AFTER read
   proves the stage drift stays where it was. */
.jgrid > div:has(.acc) { min-height: 660px; }
.mscene .scard  { width: 100%; }
.msc-1 .mock    { height: 277px; }
/* ═══ end EG-9b ═══════════════════════════════════════════════════════════════════════════════════════════════════════ */

/* ═══ P4 · "COMPARE PLANS" IS A DISCLOSURE, NOT A DECORATED RULE (operator eye-gate 2026-09-06 14:21 CT, /pricing
   screenshot) ═══════════════════════════════════════════════════════════════════════════════════════════════════════
   Lane C3. His words: "the chevron here essentially has no function its supposed to be a drop down into the features".
   ArticleView.tsx now wraps the heading in native <details class="pr-cmp"><summary class="pr-cmp-s"><h2 class="pr-cmp-h">
   and puts the `.cmp` table inside the details — the FAQ accordion's own pattern (marketing-cms.css:674-681, :731;
   marketing-interaction.css:700), so every value below is that neighbour's, verbatim; nothing is minted.
   FRAMES: `Choose Plan - Default (2)` draws the line CLOSED (no table under it); `Choose Plan - Default` draws it OPEN;
   the Subscriptions frame calls it "the 'Compare plans' expando control". Both draw the chevrons UP. Default CLOSED on
   the walk's authority; chevrons DOWN when closed (rotate 180°) — INTERIM DEVIATION · UNRATIFIED on the closed glyph.
   MEASURED BEFORE (P4/BEFORE-en-4300.json, :4300 /pricing 1440): h2.pr-cmp-h at y 998.5, h 21, margin 28px 0, colour
   rgb(29,29,31); 0 details, table 8 rows always rendered; --brand #2164F4 / --cta-fill #1A52C4 both IN SCOPE on the h2
   (§9b). The h2's 28px top margin collapses with `.pr-main > section + section{margin-top:30px}` (marketing-cms.css:763)
   to 30, so the summary must not put padding ABOVE it: the hit box is 12px padding each side with a -12px top margin
   (collapse(30,-12) = 18, +12 = 30 — the text does not move) and 16px bottom margin (12+16 = the frame's 28 to the table).
   The h2's own margin moves to 0 inside the summary: (0,4,3) over `.page h2.pr-cmp-h{margin:28px 0}` (0,1,2). Box 45px ≥ 44. */
.page details.pr-cmp > summary.pr-cmp-s { list-style: none; cursor: pointer; display: block; padding: 12px 0; margin: -12px 0 16px; box-sizing: border-box; }
.page details.pr-cmp > summary.pr-cmp-s::-webkit-details-marker { display: none; }
.page details.pr-cmp > summary.pr-cmp-s > h2.pr-cmp-h { margin: 0; }
.page details.pr-cmp > summary.pr-cmp-s:hover > h2.pr-cmp-h  { color: var(--cta-fill); }   /* the FAQ summary's hover, :731 */
.page details.pr-cmp > summary.pr-cmp-s:active > h2.pr-cmp-h { color: #143C96; }           /* the FAQ summary's active, interaction:700 */
/* ⛔ LANE S6 · 2026-09-07 · WALK-3 row W3-N03 — ONE TOKEN, STRUCK IN PLACE (S9). The line as authored read:
       ~~.page details.pr-cmp > summary.pr-cmp-s:focus-visible { outline: 2px solid var(--brand); ... }~~
   It cites `:681` — `details.mkt-faqitem > summary.mkt-qrow:focus-visible` in marketing-cms.css (now :688) — as the
   neighbour it ports verbatim, and THAT rule says `var(--cta-fill)`. The port took the declaration and changed the
   token, which is how one focus system ends up with two blues. MEASURED by REAL Tab at 1440 (WALK3-CURES-S/BEFORE.json,
   the full 44-stop /pricing and 45-stop /ar/albaqat-walasaar orders): `summary.pr-cmp-s` rings `rgb(33,100,244)` while
   the SIX other site-ringed stops on the same page ring `rgb(26,82,196)` — **8.421 dE2000** apart, reproducing §13's
   recorded 8.420 to three decimals with an instrument that self-proves (identity 0.000 · black|white 100.000 / 21.000 ·
   #F6FAFF|#F7F9FF 1.232). Ground read from the DOM, not assumed: `rgb(243,246,254)`.
       today  #2164F4 vs that ground   contrast 4.748 : 1   dE2000 44.960
       cure   #1A52C4 vs that ground   contrast 6.533 : 1   dE2000 51.978     (F8 floor 3.0 — both pass; the defect
   is TWO BLUES IN ONE FOCUS SYSTEM, not contrast, and I will not dress it as a contrast fix.)
   ⭐ THE VALUE IS NOT MINE: the operator's Issue 6 ruling (EG-24, §J idx 70) names `--cta-fill` as the one interactive
   blue and migrated 8 declarations in marketing-cms.css to it — including this rule's own stated parent at :688. This
   summary was authored after that sweep and missed it. Porting the token restores the sibling, it does not re-derive one.
   §9b PROVEN ON THE ELEMENT, not assumed: `getComputedStyle(summary.pr-cmp-s).getPropertyValue('--cta-fill')` =
   `#1A52C4`, non-empty (and `--brand` = `#2164F4`), so both tokens are in reach and the choice is a choice.
   EG-23: the element carries an inline `style="list-style:none;display:block"` — `outline` is ABSENT from it, so a
   sheet rule still wins on this property (checked on the live element, not inferred). Rows W3-N03 / W-09 family. */
.page details.pr-cmp > summary.pr-cmp-s:focus-visible { outline: 2px solid var(--cta-fill); outline-offset: 2px; border-radius: 6px; } /* marketing-cms.css:688, verbatim */
.page details.pr-cmp .cmp-chev svg { transition: transform .25s ease; }
.page details.pr-cmp:not([open]) .cmp-chev svg { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) { .page details.pr-cmp .cmp-chev svg { transition: none; } }
/* ═══ end P4 ══════════════════════════════════════════════════════════════════════════════════════════════════════ */


/* ═══ ITEM R · THE HERO WORD IS A VERTICAL REEL (operator ruling 2026-09-06 ~15:2x CT, with a reference implementation) ═══
   Lane C2 (component-surgeon). INTERIM DEVIATION · UNRATIFIED — no approved frame draws a transition (S13 branch 2) and
   the walk is full authority where it speaks. It SUPERSEDES the overhand card stack (EG-5b above, struck in place).

   HIS SNIPPET, and what is taken from it VERBATIM: a pill with `overflow:hidden`; a column track translated by
   `-index × <one item>` every 2500 ms over 600 ms on `cubic-bezier(.65,0,.35,1)`; a DUPLICATE of the first word appended
   so the loop closes. What is NOT taken: `#dbeafe`, `9999px`, `2.75rem` and `2.25rem` are his sample's placeholders —
   this pill keeps the SITE's look and the SITE's copy (S13: no colour, radius or string is minted here).

   WHY PURE CSS AND NOT HIS setInterval: the hero is a server component (`HomeMarketing.tsx`); a client island whose only
   job is a timer is a cost the page does not need. His reset is replaced by ARITHMETIC — with 3 phrases + the duplicate,
   the 100 % keyframe is `translateY(-300%)`, which renders the SAME PIXELS as 0 %, so `infinite` closes the loop with
   nothing to snap back. Timing is his, to the millisecond: hold 1.9 s + move 0.6 s = 2.5 s per phrase; 3 × 2.5 s = 7.5 s.
     25.3333 % = 1.9 s   ·   33.3333 % = 2.5 s   ·   58.6667 % = 4.4 s   ·   66.6667 % = 5.0 s   ·   92 % = 6.9 s

   GEOMETRY, and it is why no length is hardcoded: `.hl-track` is `position:absolute; inset:0`, so its border box is
   EXACTLY the pill's box — a definite height. `flex: 0 0 100%` gives every item that same height, and a percentage
   `translateY` resolves against the track's own border box ⇒ `-100%` is exactly one item at every viewport, every font
   size and every locale, with no `px`, no `rem` and no container query. `.hl-words` (invisible, opacity 0 from the pinned
   base) still sizes `.hl` to the WIDEST phrase, so the pill never resizes mid-cycle.

   §9b, checked before use: `--shuf-fill` / `--shuf-radius` / `--shuf-shadow` and `--ink` are defined on `.page`
   (marketing.css:685) and `.hl` is inside `.page` — the pinned `.hl-card` already resolved all three on this element.
   /ar: the reel travels the BLOCK axis, which `direction:rtl` does not mirror; the items are `justify-content:center`,
   so nothing is axis-dependent. MEASURED per locale rather than assumed (see the AFTER read in eg-batch/REEL/).      */
.hl-reel  { position: absolute; inset: 0; z-index: 1; overflow: hidden;
            background: var(--shuf-fill); border-radius: var(--shuf-radius); box-shadow: var(--shuf-shadow); }
.hl-track { position: absolute; inset: 0; display: flex; flex-direction: column;
            animation: hl-roll 7.5s linear infinite; }
.hl-item  { flex: 0 0 100%; display: flex; align-items: center; justify-content: center;
            white-space: nowrap; color: var(--ink); }
/* the cadence is written for THREE phrases + the duplicate (measured 2026-09-06: 3 on all 6 locale roots, `hl-w` span
   count). A different count would roll to the wrong stop, so it does not roll at all — a static first word is wrong-ish
   and legible; a mistimed reel is a defect. `data-n` is emitted by the component from `hero.rotating.length`. */
.hl-reel:not([data-n="3"]) .hl-track { animation: none; }
@keyframes hl-roll {
  0%,       25.3333% { transform: translateY(0);      animation-timing-function: cubic-bezier(.65,0,.35,1); }
  33.3333%, 58.6667% { transform: translateY(-100%);  animation-timing-function: cubic-bezier(.65,0,.35,1); }
  66.6667%, 92%      { transform: translateY(-200%);  animation-timing-function: cubic-bezier(.65,0,.35,1); }
  100%               { transform: translateY(-300%); }
}
/* reduced motion: the track holds phrase 1 — no animation, no transition, nothing to trough (S1's reduced-motion arm). */
@media (prefers-reduced-motion: reduce) {
  .hl-track { animation: none; transform: none; }
}
/* ═══ end ITEM R ══════════════════════════════════════════════════════════════════════════════════════════════════ */


/* ═══ ITEM C · THE LOGO STRIP — FULL-BLEED, EDGE-FADED, REAL MONOCHROME MARKS ═══════════════════════
   Operator, 2026-09-06 14:29 eye-gate: the strip "does not move" and is text names; he wants two
   FULL-WIDTH moving rows of real, consistent, monochrome marks. INTERIM DEVIATION · UNRATIFIED —
   the approved frame draws a 1120 px centred strip of nine third-party marks; the walk governs.

   (1) WHY IT DID NOT MOVE — found, and it was not this layer: `marketing-saver.css` carried
       `html[data-saver="on"] .logo-track{animation:none}` and the operator browses with DATA SAVER ON
       ("data saver is on", verbatim). Measured at 1440 with cookie `lr_data_saver=1`: animation-name
       `none`, 0 px of travel; with the cookie absent, `marq-left`/`marq-right` 30 s, −53.5 px/s. Cured
       at the cause in that sheet (previous commit) — nothing here paused it. The pinned keyframes
       `marq-left`/`marq-right` (marketing.css:239-240) are present in the served sheet and untouched,
       and `prefers-reduced-motion` (marketing.css:241) still stops it.
   (2) FULL BLEED: the pinned `.logos{max-width:1120px;margin:0 auto}` (marketing.css:228) is
       overridden at (0,2,0) with a `calc(50% - 50vw)` inline margin — the only escape from a centred
       container that does not depend on knowing the page width. `overflow-x:clip` on the section is the
       guard: a bleed can otherwise manufacture a horizontal scrollbar at some widths, and this lane has
       a measured 309 px scroll band in its record. The edge fade is a mask, so it works over ANY ground
       (the section paints a gradient at `.page.fin.home .p-logos`, which a solid fade strip could not
       match): transparent → opaque at 8 % → opaque to 92 % → transparent, `-webkit-` twin included.
   (3) NO GAP AT THE WRAP: `marq-left` translates the track by exactly −50 %, i.e. ONE SET, so a set
       narrower than the viewport shows empty ground on every wrap. MEASURED at 1440 BEFORE this
       change: track 3208.8 px = 2 × 1604 px ⇒ already 316 px of gap at 1920 and 956 px at 2560. The
       component now repeats each slot 6× per set (LOGO_REPEATS in HomeMarketing.tsx).
   (4) THE MARKS: `simple-icons@16.30.0` (CC0, pinned exact), inlined as `<use>` into a one-per-page
       sprite, `fill: currentColor` in the strip's own grey `#16181D` — the exact fill the CMS name
       placeholders paint, so no colour is minted (S13). One box height for every mark. The pinned
       `.logo-track img{filter:grayscale(1);opacity:.62}` cannot reach an `<svg>`, so those two are
       restated here at the same values — kept, not re-decided.                                     */
.p-logos { overflow-x: clip; }
.p-wall .logos { max-width: none; margin-inline: calc(50% - 50vw); }
.p-logos .logo-row {
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 8%, #000 92%, transparent 100%);
          mask-image: linear-gradient(to right, transparent 0, #000 8%, #000 92%, transparent 100%);
}
.logo-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.logo-track .logo-mark { flex: none; width: 32px; height: 32px; color: #16181D; fill: currentColor; filter: grayscale(1); opacity: .62; }
/* ═══ end ITEM C ══════════════════════════════════════════════════════════════════════════════════ */


/* ═══ ITEM E · THE CONTROL IS A REAL <button>, AND THE SEARCH CARD'S HEADING IS AN h2 ══════════════
   Two axe rules, measured on :4330 at 1440 BEFORE the change, on / and /ar:
     aria-allowed-role  5 nodes on EACH route — `role="button"` is not allowed on an <h3>
     heading-order      1 node on EACH route — `.matchcard > h3` sits directly under the page's <h1>
   (a) JourneysInput.tsx now nests a real `<button type="button" class="acc-btn">` inside each row's
       heading and the four rules above are re-keyed to it. A UA button brings its own font, border,
       background and centring, so they are reset to INHERIT — this changes nothing that renders; the
       proof is the AFTER read, where the control's box is the same 374.5 × 44 it measured before.
   (b) `.matchcard`'s heading becomes an <h2> (HeroSearch.tsx). SIX PINNED RULES key off
       `.matchcard h3` (marketing.css:136, :509, :573, :653, :655, :659) and would silently stop
       applying, so each is restated here for `h2` with its VALUES TRANSCRIBED VERBATIM — no value is
       re-derived and no scale is re-chosen (§18 step 5 applied to CSS). Same specificity as the
       pinned original in every case, and no `h3` rule is edited: the pinned sheet still says what it
       said. Falsifier: the AFTER read compares font-size, weight, family, margin-bottom and the
       rendered box against the BEFORE — 16px / 800 / Hanken Grotesk / 3px / 792 × 21.               */
.jgrid .acc h3 > .acc-btn,
.sell .si h3 > .acc-btn {
  appearance: none; -webkit-appearance: none;
  background: none; border: 0; box-shadow: none;
  font: inherit; color: inherit; letter-spacing: inherit; text-transform: inherit;
  text-align: inherit; display: block; width: 100%; cursor: pointer;
}
.matchcard h2                            { font-size: 24px; margin-bottom: 20px; }                                            /* = marketing.css:136 */
.home.lvl2 .matchcard h2                 { width: 100%; font-size: 15px; margin: 0 0 2px; }                                   /* = :509 */
.page.fin.home.lvl2 .matchcard h2        { font-size: 16px; font-family: var(--font-head); margin-bottom: 3px; text-align: center; width: 100%; } /* = :573 */
.page.fin.home.lvl2.sc-a .matchcard h2   { font-size: 18px; margin-bottom: 5px; }                                             /* = :653 */
.page.fin.home.lvl2.sc-b .matchcard h2   { font-size: 16px; margin-bottom: 3px; }                                             /* = :655 */
.page.fin.home.lvl2.sc-c .matchcard h2   { font-size: 20px; margin-bottom: 7px; }                                             /* = :659 */
/* ═══ end ITEM E ══════════════════════════════════════════════════════════════════════════════════ */


/* ═══ ITEM R2 · PER-CHARACTER ROLL + THE PILL'S DEPTH (operator ruling 2026-09-06 ~15:4x CT) ════════
   His code, verbatim, is in HeroReel.tsx's header. INTERIM DEVIATION · UNRATIFIED.
   ⛔ ITEM R's `@keyframes hl-roll` and `.hl-track` are NOT struck: they are now the NO-JS FALLBACK.
   The island's first render (server + first client render) IS that markup, so the phrase paints and
   rotates before hydration and forever with JavaScript off; once the island mounts it renders
   per-character lines instead and the animated element no longer exists — which cancels the CSS
   animation by construction, with no race and no second timer.

   (a) THE CLIP BOX EQUALS ONE LINE BOX — "aligns with this animation". Each character's box is the
       FULL pill height (`align-items: stretch` on the line, `height:100%` on the character), so his
       `translateY(100%)` is exactly one pill height: a character leaves through the bottom edge and
       the incoming one enters through the top edge with NO partial glyph at either edge. Had the
       character kept its own line box (~60.5 px against a 68.5 px pill) the roll would have stopped
       8 px short and left a sliver — measured before choosing this, not after.
   (b) DEPTH, WITHOUT TOUCHING THE RESTING COLOUR. NO FRAME draws a stuck or animated pill, but the
       RESTING pill is the frame's, so `--shuf-fill`, `--shuf-radius` and the element's geometry are
       untouched. Depth is added as: two drop shadows (a tight contact shadow + a wide soft one, both
       in the brand's own blue rather than a new grey), a 1 px inner top highlight, and a vertical
       gradient of the SAME tint whose extremes are BELOW the perceptual floor from the flat fill —
       measured with a dE2000 that self-proved first (identity 0.000, black vs white 100.000):
         #D5E0FB vs #CBD8F9 = 2.603 dE2000      #C2D0F6 vs #CBD8F9 = 2.313 dE2000    (cap: 4.0)
       so the frame's colour reads unchanged and the pill gains a lit top and a grounded bottom.
       `background-image` is layered OVER the pinned `background: var(--shuf-fill)`, which stays as
       the fallback colour — no token is redefined and no colour is minted (S13).                   */
.hl-reel {
  background-image: linear-gradient(180deg, #D5E0FB 0%, #CBD8F9 55%, #C2D0F6 100%);
  box-shadow: 0 2px 6px rgba(33, 100, 244, .18),
              0 12px 28px rgba(33, 100, 244, .22),
              inset 0 1px 0 rgba(255, 255, 255, .55);
}
/* the line box HUGS ITS OWN TEXT (walk 2026-09-06): `inset: 0` made every line as wide as the pill —
   which is sized by the WIDEST phrase — so the box told you nothing about the word inside it, and a
   width read off the line was the pill's width, not the text's. `width: max-content` with auto inline
   margins centres it with NO transform (a transform would put the resting text back on a layer, R4). */
.hl-reel[data-js="on"] .hl-line {
  position: absolute; top: 0; bottom: 0; left: 0; right: 0;
  width: max-content; margin-inline: auto;
  display: flex; align-items: stretch; justify-content: center;
  white-space: nowrap;
}
/* ⛔ `will-change: transform` STRUCK 2026-09-06 (R4, S9). It read:
     ~~.hl-reel[data-js="on"] .hl-ch { … will-change: transform; }~~
   A `will-change: transform` promotes EVERY character to its own compositing layer PERMANENTLY, even
   at rest, and text on a composited layer is rasterised into that layer and resampled — measured as a
   softer glyph edge than the h1 two lines above it. Motion sets its own `will-change` for the duration
   of a roll, which is exactly when it is wanted; the hint is not needed at rest and costs sharpness.
   The character box stays the FULL PILL HEIGHT — that is what makes `translateY(100%)` land flush on
   the clip edge (ITEM R2) and it is unrelated to the rasterisation. */
.hl-reel[data-js="on"] .hl-ch {
  display: inline-flex; align-items: center; height: 100%;
}
/* reduced motion: the island never starts a timer (HeroReel.tsx), so phrase 1 sits at translateY(0)
   and the rest stay at −100 % above the clip. Nothing here needs to stop an animation that never runs. */
/* ═══ end ITEM R2 ═════════════════════════════════════════════════════════════════════════════════ */


/* ═══ ITEM J · THE JOURNEYS STACK — ONE FULL SCREEN PER DROP-DOWN ITEM (operator, 2026-09-06 16:03) ══
   "these card animations can be better they look too blank" · "I need these cards to fully reflect
   what the drop down is saying". The MARKUP change is in HomeMarketing.tsx (its header carries the
   S13 reading of the approved frame and why the old screens were blank). This block only stacks them.
   INTERIM DEVIATION · UNRATIFIED — the frame draws an Affiliates/Jobs/Analytics fan; the walk governs.

   ⛔ THE CROSS-FADE IS NOT TOUCHED. `.mscene{opacity}` and the `.jgrid[data-open="N"] .msc-N` rules
   above are the existing mechanism and still do all the switching — "do not invent a new motion".
   What is added is DEPTH AT REST: the two neighbouring items' screens sit behind the front one, so
   the stack itself shows where in the list you are. They are static; nothing here animates.
   EG-9b is preserved: the FRONT card still fills the column (`.mscene .scard{width:100%}`) and the
   stack is still centred on the list — the neighbours are absolutely positioned, so they add no
   height and cannot move the front card off centre. */
/* ⛔ J3 — OPERATOR RULING 2026-09-06 16:4x, which AMENDS EG-9b (his own 14:xx ruling) and supersedes
   the J2 geometry above. Verbatim: "I still want it layered, spread out like a deck of cards, so you
   can see the other cards behind it. All I asked initially was to add more information on the cards
   themselves." ⇒ EG-9b's full-width front card is AMENDED: the frame's deck returns, the content stays.
   STRUCK, S9 — what J2 had, and what J had before it:
     ~~.mcard { width: 100% }  .mcard-b1/-b2 { left:0; right:0; top:0 }~~
     ~~.mcard-b1 { transform: translateY(-40px) scale(.962) rotate(-1.2deg) }~~   (J2, 40.3 px exposed)
     ~~.mcard-b2 { transform: translateY(-76px) scale(.924) rotate(-2.4deg) }~~   (J2, 76.1 px exposed)
     ~~.mcard-b1 { translateY(-15px) scale(.955) }  .mcard-b2 { translateY(-28px) scale(.910) }~~  (J)
   THE GEOMETRY BELOW IS THE APPROVED FRAME'S, transcribed from the pinned sheet, not re-derived:
     `.mock .shot3{left:2%;top:54px;width:64%}` · `.shot2{left:18%;top:40px;width:64%}` ·
     `.shot1{left:34%;top:20px;width:62%}` (marketing.css:167-169) — three cards stepped 16 % to the
     right and 14-20 px down, so each card behind shows a ~72 px band of its own left edge, icon and
     header. At the 449.5 px stage that is 9 / 80.9 / 152.8 px of left offset.
   ⚠ THE TILT IS *NOT* THE FRAME'S −6/2/8 deg, and that is a choice being declared rather than hidden:
     the operator has already rejected slanted cards once this session (the hero, D2: "the cards are
     slanted"), so the J2 tilts (−1.2° / −2.4°, front flat) are kept. If he wants the frame's full tilt
     it is three numbers in this block.
   ⚠ EG-9b's `.mscene .scard{width:100%}` still applies — the card fills its `.mcard` wrapper, and the
   WRAPPER now carries the frame's width. The J2 pin (`align-self:center` + the reserved list height)
   is untouched: the stage still cannot move when a row opens. INTERIM DEVIATION · UNRATIFIED. */
.mockswap .mstack   { position: relative; width: 100%; height: 100%; }
.mockswap .mcard    { position: absolute; }
.mockswap .mcard-b2 { left: 2%;  top: 54px; width: 64%; transform: rotate(-2.4deg); opacity: .82; z-index: 1; pointer-events: none; }
.mockswap .mcard-b1 { left: 18%; top: 40px; width: 64%; transform: rotate(-1.2deg); opacity: .93; z-index: 2; pointer-events: none; }
.mockswap .mcard-f  { left: 34%; top: 20px; width: 62%; z-index: 3; }
/* the "AI match" tail. Same 10px/700 as the pinned `.scard .sm`, in the brand's own tint pair —
   `--accent-bg` on `--brand`, the exact pair `.sci` already uses one line above it in the card. */
/* ⛔ STRIKE, 2026-09-08 — ROW §J idx 195 (P2-DEMO-F9-AXE-COLOR-CONTRAST) root A. `color: var(--brand)`
   is STRUCK IN PLACE (S9); only the INK moves, `background: var(--accent-bg)` is deliberately untouched
   because the tint is the card's own ground and the operator has walked that band.
     ~~color: var(--brand)~~   = #2164F4 on #D6E2FD
   MEASURED, WCAG 2.x relative-luminance ratio (L1+0.05)/(L2+0.05) on the element's RESOLVED colour
   against its RESOLVED background, at the rendered 10px/700:
     BEFORE  #2164F4 on #D6E2FD  =  3.85 : 1   <- axe `color-contrast` VIOLATION, 3 nodes x 6 cells
     AFTER   #1A52C4 on #D6E2FD  =  5.301 : 1  <- above the AA bar
   THE BAR IS 4.5, NOT 3.0: 10px bold is SMALL text (bold-large starts at 18.66px). 3.85 sits BELOW 4.5
   and ABOVE 3.0 — a straight AA fail, NOT an S1 `contrast-marginal` (that band is 4.5-5.5).
   ⚠ 5.301 IS ITSELF INSIDE THE 4.5-5.5 MARGINAL BAND and is reported as marginal even though it passes.
   That is not a licence to redesign: `--cta-press` #143C96 exists and would score higher, but choosing
   it would MINT a treatment this surface does not use for this element (S13).
   NOTHING IS MINTED. 5.301 is TRANSCRIBED, not re-derived (§18 step 5), from this tree's own
   measurement of the identical pair: marketing-interaction.css:110 ("--accent-bg #D6E2FD ... contrast
   5.301  <- CHOSEN") and :116 ("hover-unselected #D6E2FD/#1A52C4  5.301"). #1A52C4 IS `--cta-fill`
   (marketing.css:689 · design-system.css:91, both on `.tok-iter3`).
   NO FRAME — `.mk-ai` is lane-authored ITEM J, INTERIM DEVIATION · UNRATIFIED, and this correction
   inherits that status. It is not a frame disagreement and not a frame defect.
   THE DISCRIMINATOR, stated because S13 branch 4 requires it: the comment above cites `.sci`
   (marketing.css:214, PINNED — `background:var(--accent-bg);color:var(--brand)`), and that precedent
   DOES NOT TRANSFER. `.sci` is a 30x30 ICON CHIP whose `color` paints an SVG stroke — axe does not test
   it and WCAG 1.4.3 does not govern it. `.mk-ai` is 10px BOLD TEXT. The pair was ported from a
   NON-TEXT context onto text. So this is a lane-authored CORRECTNESS error in a lane-owned sheet, and
   S13 branch 2 governs: correctness, no re-design.
   §9b — `--cta-fill` is defined on `.tok-iter3`, the SAME selector that defines the `--accent-bg` this
   rule already resolves on this element; scope proven in the browser
   (getComputedStyle(el).getPropertyValue('--cta-fill') non-empty) before this shipped, per the check
   already recorded for `--accent-bg` at :1156 below.
   S14 DENOMINATOR — 3 of 3 source occurrences, cured by this ONE declaration, BOTH arms of the
   selector list: HomeMarketing.tsx:191 and :201 (`.mockswap`) and :939 (`.p-trans .analytics .tscene`,
   which is `tsc-3`, NOT tsc-4 — tsc-4 opens at :964 and holds no `mk-ai`). Two structurally different
   counts agree: `grep -c` 3 lines, `grep -o | wc -l` 3 occurrences. The tscene arm is opacity 0 unless
   a row is hovered/focused/`data-open` (:865, :869-882), so axe NEVER TESTED IT — that arm was
   UNMEASURED, not clean (S16, trap 16). It was measured for this row in its shown state, reached by
   its own CSS arm (`data-open="3"` on `.sell`, :876), never by injected CSS. Both arms covered. */
.mockswap .scard .sm.mk-ai,
.p-trans .analytics .tscene .sm.mk-ai {
  background: var(--accent-bg); color: var(--cta-fill);
  border-radius: 999px; padding: 3px 9px; font-size: 10px; font-weight: 700;
}
/* ═══ end ITEM J ══════════════════════════════════════════════════════════════════════════════════ */


/* ═══ ITEM T · THE TRANSFORM BAND — THE CARD HOLDS STILL, THE SCENE FOLLOWS THE ROW ═════════════════
   Operator 2026-09-06 16:18, verbatim: "I don't like how the card is static — there's only one card
   for it. Every one of those dropdowns should have a different animation on the right side, and it
   should be switching. I don't want the card to be moving with the dropdown because it makes it seem
   glitchy. The card itself should be the only thing that moves, and then the animation on the right is
   static in the same position, but it changes depending on which card you're hovering over."
   INTERIM DEVIATION · UNRATIFIED (the frame draws one static analytics card and a centred grid).

   (1) THE CARD MUST NOT MOVE. Cause, measured before the cure: the pinned
       `.p-trans{...;align-items:center}` (marketing.css:279) CENTRES both columns, so every +95 px a
       row opens re-centres the right column and the card slides by half of it. `align-items: start`
       pins the card's top to the row; the left column then grows downward on its own. (0,1,0) at
       equal specificity, later in the cascade.
   (2) A SCENE PER ROW. Four scenes live in one `.tscenes` frame; all four are absolutely positioned
       so the frame's height is set by `min-height` and NEVER by which scene is showing — that is what
       keeps the card still while the scene changes. Selection is pure CSS on the common ancestor
       (`:has()`, the technique the journeys band already uses): hover, `:focus-visible` and the
       `data-open` arm, so it follows exactly what opens a row — no client code, no new state.
   (3) SMOOTHER OPEN. `max-height: 0 → 240px` overshoots the real content (~95 px), so the eased
       curve is applied to a distance 2.5× too long and the row appears to stall and then jump. The
       body is now a grid row animating `0fr → 1fr`, which eases over the CONTENT's own height.
       ⚠ AND THE BRIEF'S "no frame with a step > 2 px" IS ARITHMETICALLY UNREACHABLE FOR AN OPEN OF
       THIS SIZE, so it is reported rather than faked: a 95 px expansion at ≤ 2 px per frame needs
       ≥ 48 frames = ≥ 800 ms at 60 Hz, and an 800 ms disclosure is slower than every other control on
       this page. 320 ms is kept; the measured peak step is in the commit message beside this number. */
.p-trans { align-items: start; }
.p-trans .analytics .tscenes { position: relative; min-height: 268px; margin-top: 18px; }
.p-trans .analytics .tscene  { position: absolute; inset: 0; opacity: 0; transition: opacity .25s ease; pointer-events: none; }
.p-trans .analytics .tscene .an-lbl:first-child { margin-top: 0; }
/* scene 1 at rest — nothing hovered, nothing focused, no row held open */
.p-trans:not(:has(.sell .si:hover)):not(:has(.sell .si h3 .acc-btn:focus-visible)):not(:has(.sell[data-open])) .tsc-1 { opacity: 1; }
.p-trans:has(.sell .si.cat-1:hover) .tsc-1, .p-trans:has(.sell .si.cat-1 .acc-btn:focus-visible) .tsc-1 { opacity: 1; }
.p-trans:has(.sell .si.cat-2:hover) .tsc-2, .p-trans:has(.sell .si.cat-2 .acc-btn:focus-visible) .tsc-2 { opacity: 1; }
.p-trans:has(.sell .si.cat-3:hover) .tsc-3, .p-trans:has(.sell .si.cat-3 .acc-btn:focus-visible) .tsc-3 { opacity: 1; }
.p-trans:has(.sell .si.cat-4:hover) .tsc-4, .p-trans:has(.sell .si.cat-4 .acc-btn:focus-visible) .tsc-4 { opacity: 1; }
/* the held-open arm, only while nothing is hovered — the journeys' own precedence, verbatim */
.p-trans:has(.sell[data-open="1"]):not(:has(.sell .si:hover)) .tsc-1 { opacity: 1; }
.p-trans:has(.sell[data-open="2"]):not(:has(.sell .si:hover)) .tsc-2 { opacity: 1; }
.p-trans:has(.sell[data-open="3"]):not(:has(.sell .si:hover)) .tsc-3 { opacity: 1; }
.p-trans:has(.sell[data-open="4"]):not(:has(.sell .si:hover)) .tsc-4 { opacity: 1; }
/* a hovered row always wins over a held-open one, and a scene that is not showing must not be read */
.p-trans:has(.sell .si:hover) .tscene { opacity: 0; }
.p-trans:has(.sell .si.cat-1:hover) .tsc-1, .p-trans:has(.sell .si.cat-2:hover) .tsc-2,
.p-trans:has(.sell .si.cat-3:hover) .tsc-3, .p-trans:has(.sell .si.cat-4:hover) .tsc-4 { opacity: 1; }
/* (3) the open itself: one eased transition over the body's REAL height */
.sell .si > div:has(> h3) { display: grid; grid-template-rows: auto 0fr; transition: grid-template-rows .32s cubic-bezier(.2, .8, .2, 1); }
.sell .si p { min-height: 0; max-height: none; transition: opacity .32s cubic-bezier(.2, .8, .2, 1), margin .32s cubic-bezier(.2, .8, .2, 1); }
.sell .si:hover > div:has(> h3),
.sell .si:has(.acc-btn:focus-visible) > div:has(> h3) { grid-template-rows: auto 1fr; }
.sell[data-open="1"]:not(:has(.si:hover)) .si.cat-1 > div:has(> h3),
.sell[data-open="2"]:not(:has(.si:hover)) .si.cat-2 > div:has(> h3),
.sell[data-open="3"]:not(:has(.si:hover)) .si.cat-3 > div:has(> h3),
.sell[data-open="4"]:not(:has(.si:hover)) .si.cat-4 > div:has(> h3) { grid-template-rows: auto 1fr; }
@media (prefers-reduced-motion: reduce) {
  .p-trans .analytics .tscene { transition: none; }
  .sell .si > div:has(> h3)   { transition: none; }
}
/* THE ROW VOCABULARY INSIDE A SCENE. `.srow` / `.sav` / `.st` / `.sm` are styled by the pinned sheet
   only UNDER `.scard` (marketing.css:215-219), so inside the analytics card they rendered with no
   layout at all — chip 0 px, name and sub-label run together, the tick on its own line. CAUGHT BY THE
   HAND-CHECK, not by a probe (the DOM was correct and the pixels were not — §9 trap 17). The five
   declarations below are those five pinned rules TRANSCRIBED VERBATIM, re-scoped; the only change is
   `padding-inline: 0`, because the analytics card already carries its own 22 px padding. */
.p-trans .analytics .tscene .srow          { display: flex; align-items: center; gap: 11px; padding: 12px 0; border-bottom: 1px solid var(--line); font-size: 12.5px; }
.p-trans .analytics .tscene .srow:last-child { border-bottom: none; }
.p-trans .analytics .tscene .srow .sav     { width: 26px; height: 26px; border-radius: 8px; flex: none; display: flex; align-items: center; justify-content: center; color: #fff; font-weight: 800; font-size: 11px; font-family: var(--font-head); }
.p-trans .analytics .tscene .srow .st      { flex: 1; min-width: 0; }
.p-trans .analytics .tscene .srow .st b    { display: block; font-size: 12.5px; font-weight: 700; color: var(--ink); }
.p-trans .analytics .tscene .srow .st span { font-size: 10.5px; color: var(--mut); }
.p-trans .analytics .tscene .srow .sm      { margin-inline-start: auto; font-size: 10px; font-weight: 700; flex: none; }
/* ═══ end ITEM T ══════════════════════════════════════════════════════════════════════════════════ */
/* ═══ WALK 2026-09-06 · W-04 · THE TRANSFORM ROWS HAD NO HOVER CHANGE ══════════════════════════════
   The walk measured `Δ {}` on all four `.sell .si` rows while `cursor: pointer` invited the pointer,
   and the SAME control class 300 px above (`.acc-btn` in the journeys band) does change. The row's
   panel and arrow already respond (B8); what never moved was the CARD ITSELF, which is the thing the
   pointer is over. S14 — the treatment is the neighbour's, not a new one: the journeys card's own
   resting border and the site's existing card shadow token, both already on this element's siblings.
   No colour, radius or shadow is minted; `--brand` and `--sh-card` are `.page`-scoped and in reach
   (§9b — the pinned `.sell .si` already resolves `--line` and `--sh-soft` on this element). */
.sell .si { transition: border-color .2s ease, box-shadow .2s ease; }
.sell .si:hover,
.sell .si:has(.acc-btn:focus-visible) { border-color: var(--brand); box-shadow: var(--sh-card); }
@media (prefers-reduced-motion: reduce) { .sell .si { transition: none; } }

/* ═══ WALK · W-11 · THE CARD BEHIND SHOWED A SLICED WORD ═══════════════════════════════════════════
   "Verified employers" was cut through ~60 % of its glyph height by the front card's edge. With the
   frame's deck (J3) the exposed band is 74 px and a header runs longer than that, so SOME cut is
   structural — the frame has the same shape. The choice is between a hard cut through glyphs and a
   fade; the fade shows the same content without a half-letter.
   ⛔ THE FIRST CUT OF THIS RULE DID NOTHING AND THE MEASUREMENT CAUGHT IT (a mask that reaches the
   element and still loses — the third failure mode in this lane's own component brief). It faded from
   58 % to 96 % OF THE CARD'S OWN WIDTH, while the front card's edge crosses that card at 25 %: the
   whole gradient sat in the region already hidden BEHIND the front card. Measured ink in the 24
   device-px strip before the front edge: 829 px with the mask, 829 px with it forced off — byte-equal,
   i.e. the rule was inert. The stop positions now come from the deck's OWN percentages:
       b1  left 18 %, width 64 %, front at 34 %  ⇒  visible band = (34−18)/64 = 25 % of the card
       b2  left  2 %, width 64 %, front at 34 %  ⇒  visible band = (34− 2)/64 = 50 % of the card
   so each card's ink is gone before the edge that would slice it. Physical direction, because the deck
   is laid out with physical `left` offsets in both writing directions. */
/* ⛔ STRUCK IN PLACE 2026-09-07 (S9) — the two mask rules this block argued for. Kept verbatim so
   the change is auditable, and CANCELLED EXPLICITLY at the end of this section rather than deleted:
     ~~.mockswap .mcard-b1 { mask-image: linear-gradient(to right,#000 0,#000 14%,transparent 24%) }~~
     ~~.mockswap .mcard-b2 { mask-image: linear-gradient(to right,#000 0,#000 14%,transparent 24%) }~~
   THE STOP POSITIONS WERE RIGHT and are re-measured here: :4320, dpr 2, / @1440 — b2 75.41/299.29 =
   25.2 %, b1 74.23/292.29 = 25.4 %, reproducing the figure recorded below. What the arithmetic could
   not see is that a CORRECT gradient is still a gradient: it puts the last ~40 % of everything a
   person can see at alpha 0. That is the fade the operator named. See EG-DECK-FADE at the end. */
/* .mockswap .mcard-b1 {
  -webkit-mask-image: linear-gradient(to right, #000 0, #000 14%, transparent 24%);
          mask-image: linear-gradient(to right, #000 0, #000 14%, transparent 24%);
} */
/* ⛔ STRUCK IN PLACE 2026-09-07 (S9) — the `.mockswap .mcard-b2` mask rule that stood here. It is
   written out rather than wrapped in a comment because its own W-11 SECOND-CUT header sat INSIDE the
   rule and CSS comments do not nest — wrapping it would have terminated at that inner header's own
   COMMENT TERMINATOR (the two characters star-then-slash, which is why this sentence spells them out
   instead of quoting them) and left two live `mask-image` declarations followed by a stray CLOSE
   BRACE. Declarations, verbatim:
     ~~-webkit-mask-image: linear-gradient(to right, #000 0, #000 14%, transparent 24%);~~
     ~~        mask-image: linear-gradient(to right, #000 0, #000 14%, transparent 24%);~~
   THE SECOND-CUT NOTE, kept verbatim so the correction it records is not lost: 38%/49% was derived
   against the WRONG COVERING CARD and was therefore INERT — the same failure the first cut of this
   rule already recorded, repeated on the sibling selector one line down from where it was written up.
       b1  left 18 %, covered by .mcard-f  at 34 %  ->  (34−18)/64 = 25 %   14%→24%   was right
       b2  left  2 %, covered by .mcard-f  at 34 %  ->  (34− 2)/64 = 50 %   38%→49%   WRONG CARD
       b2  left  2 %, covered by .mcard-b1 at 18 %  ->  (18− 2)/64 = 25 %             the real band
   b2 is covered by b1, not by the front card. MEASURED on :4330, dpr 2, 12 cells: card0's strip is
   75.4 px of its own 299.3 px = 25.2 %, identical to card1's 74.2/292.3 = 25.4 %. Re-measured on
   :4320 2026-09-07: 75.41/299.29 and 74.23/292.29 — the same two numbers. Both cards took the same
   stops because both are covered at the same fraction of their own width. */

/* ⛔⛔ W-11 — THE MASK IS NOT THE CURE, AND THE BLIND VERIFIER IS THE REASON I KNOW.
   VERDICT on the stamped build: FAIL on `/` (en), PASS on `/ar` — and the ar pass is an RTL accident
   (RTL puts the title at the card's trailing edge, which is the covered side), so it carries no
   information about any cure. Its predicate, quoted so the next reader grades against the same
   question: "a pixel whose maxChannel delta from the card ground rgb(250,252,255) is > 20", inside
   the strip (card leading edge → covering card's near edge) over that card's own title band.
   RE-DERIVED HERE BY AN INDEPENDENTLY WRITTEN INSTRUMENT, 12 cells (2 routes × 1280/1440/1920 ×
   saver on/off), coverage 12/12: en card0 3426 px · card1 3448 px · ar 107/100 · front card
   (positive control) 6621 · border-only control B 0/78 · 40.2 % and 65.5 % of each title's own ink.
   Reproduces the verifier to 1–2 px.

   ⭐ THE TWO CRITERIA ARE DIFFERENT QUESTIONS AND THAT IS THE WHOLE FAILURE. The first cut asked
   "is a glyph cut in half at the edge?" and faded the last 10 % of the band. The verifier asks "is
   there ANY title ink in the strip?". A fade that starts at 14 % of the card leaves a title that
   begins ~55 px into a 74 px strip almost entirely painted. b1's stops were CORRECT and b1 still
   measured 3448 px. A cure can be geometrically right and answer the wrong question.

   S13 DECIDES BETWEEN THE TWO REMEDIES ON OFFER, and it is not a judgement call: the approved deck
   this block transcribes its geometry from is `marketing.css:167-175` (PINNED), where a stacked
   card's header is `.mock .shot .hd{height:24px;background:var(--tint)}` with `.hd i` dots and
   **NO TEXT**. The frame's cards behind carry a header BAR, not a title. So the title is dropped on
   the covered cards and the icon chip stays — the band a person sees behind the front card is the
   card's colour, its edge and its icon, which is what the frame draws and what the operator asked
   for ("layered … so you can see the other cards behind it"). The FRONT card is untouched.
   ⚠ Physical `left` selectors on purpose: the deck is laid out with physical offsets in both
   writing directions, so b1/b2 are the covered cards in ltr AND rtl.
   ⚠ a11y: nothing leaves the accessibility tree that is not already in it. The hidden strings are
   the NEIGHBOURING accordion items' own titles, rendered a few hundred px to the left in the
   `.acc` list; the deck is decorative (`pointer-events:none` on both covered cards).
   S14 DENOMINATOR: 6 routes carry the deck (`/ /ar /bn /es /hi /mr`), 5 `.mscene` each, 2 covered
   cards per scene = 60 covered cards. `/referral-home` has `.mscene` but zero `.mcard-b*` and is
   the negative control. */
.mockswap .mcard-b1 .shd-t,
.mockswap .mcard-b2 .shd-t { display: none; }

/* ═══ WALK 2026-09-07 · EG-DECK-FADE · THE TWO BACK CARDS AT FULL STRENGTH, AND NO GLYPH CUT ═══════
   OPERATOR RULING 2026-09-07 05:21 CT, verbatim, with his screenshot of `/` at ~1300 px on the
   "Building career journeys that inspire" band: "the background cards are too faded here". His
   walk-1 ruling W-11 — "the card behind is a sliced word" — still stands. Both are cured together.
   INTERIM DEVIATION · UNRATIFIED.

   MEASURED BEFORE — EG-DECK-FADE/BEFORE.json, :4320, dpr 2, `/` and `/ar` × 1085/1280/1440/1920 ×
   saver on+off = 16 cells; coverage asserted inside the instrument 16/16 cells and 160/160 covered
   cards; pointer parked at (2,2) and the park verified; read after `networkidle`, never DCL:
     (a) EFFECTIVE ALPHA of the icon chip = (ground − observed)/(ground − trueFill) on the channel of
         largest spread, sampled on a 4 CSS-px band inside the chip's leading edge, ground = an 8×8
         patch just outside the card's leading edge. TWO structurally different estimates agree:
           `.sci` chip   b2 0.838 · b1 0.938 · front 1.000     ratio to front  0.838 / 0.938
           `.sav` chip   b2 0.823 · b1 0.931 · front 1.000     (= the declared .82 / .93)
         per-column alphaBorder across the strip, (246 − minRed)/(246 − 217), 217 = `--line`:
           b2   0.83 0.83 0.83 … 0.55 … 0.24 at the far end   — the gradient, as numbers.
     (b) SLICED WORDS, the blind verifier's row-3 predicate re-implemented (per-CHARACTER Range walk;
         a word is SLICED when the covering card's near edge falls strictly inside it):
           `/`   16 words / 12 text nodes at 1280-1920, 13 at 1085 — reproduces VERIFY-WALK3 exactly.
           `/ar`  5 words /  5 text nodes at 1280-1920. ⚠ NEW. The recorded "/ar = 0" was an artefact
                  of an ltr-only edge convention: in RTL `.sm` (`margin-left:auto`, PHYSICAL) lands on
                  the card's LEADING side and is the thing that gets cut — "مباشر", "الجمعة".
           across all five `.mscene` decks, not just the first: `/` 63 · `/ar` 16.

   (1) FULL STRENGTH — the mask is cancelled and the opacity ladder retired.
       ⭐ S13, AND THE OPACITY IS THE FRAME'S, NOT A CHOICE OF MINE: the approved deck whose geometry
       the J3 block above transcribes is `marketing.css:166-168` — `.mock .shot3/.shot2/.shot1` set
       left/top/width/height/transform ONLY and carry NO opacity. `.82`/`.93` were added by this lane
       in J3. Retiring them RESTORES the frame; no value is minted (the cure is the neighbours' —
       the front card's own opacity 1).
       ⚠ `mask-image: none` is written EXPLICITLY instead of relying on the deletion above, because
       `marketing-critical.css` is GENERATED and inlined AHEAD of the linked sheets: until the
       integration regenerates it, a merely-deleted rule would still be inlined and would still paint
       the gradient at first paint. That is the EG24-5 pre-paint-flash lesson. An explicit `none`
       wins at every moment.
   (2) NO HALF-GLYPH — `.st` and `.sm` are dropped on the two COVERED cards only.
       `display`, NOT `visibility`: predicate (b) is a LAYOUT-RECT test, so `visibility:hidden` would
       paint nothing and still measure 16 — a correct-looking cure that reads as a failure.
       `display:none` is also exactly the treatment the blind verifier's own GREEN control proved
       reaches 0 (VERIFY-WALK3/VERDICT.txt row 3, and its remediation line 3a).
       `.sbtn` is NOT touched: measured, its centred label never crosses a covering edge in either
       writing direction, and hiding it would cost the express card ~57 px of height for nothing.
       INTERIM DEVIATION · UNRATIFIED — the frame DOES draw body text on the cards behind, cut by the
       covering card. Not inferred from the pinned sheet alone (`marketing.css:172-180`: `.mock .sbar`
       / `.ssr` / `.mlabel`): MEASURED off the frame itself by lane S6 on 2026-09-07 —
       `Candidate/Home to Apply Jobs/Home.png` at native 1200, card left edges 101.7 / 184.3 / 266.7,
       exposed band 82.6 px on a derived 330 px card = 25.0 % exposure (live 25.2 % / 25.4 %: THE SAME
       DECK), and at that exposure its covered cards read `Softwa|` `Produ|` `Notion|` `Andr|` `Profe|`
       `Rob|` — cut mid-word, at FULL opacity. The operator has refused cut words twice (walk-1 W-11
       and again 2026-09-07). Reverting rule (2) alone restores the frame's treatment exactly.
       ⚠ A SECOND disagreement carried from S6 and NOT settled here: the frame's covered cards also
       carry a legible header LABEL (`AFFILIATES`, `JOBS`), which W-11's `.shd-t{display:none}` (kept
       untouched above) removes. That is the same argument as rule (2) applied to the title, and it
       is the founder's to rule on, not this lane's.
   (3) THE TITLES ARE NOT TOUCHED. The `.shd-t{display:none}` rule immediately above is unchanged —
       0 client rects before AND after, both covered cards, both locales, 16/16 cells. Both cards are
       `aria-hidden="true"` (HomeMarketing.tsx:293-294), so NOTHING here changes an a11y state.

   MEASURED AFTER: chip alpha b2 0.995 · b1 0.998 · front 1.000 — ratio to front ≥ 0.995 against the
   brief's 5 % floor; sliced words 0 and sliced text nodes 0 on 16 of 16 cells, 160 of 160 covered
   cards, both routes, all five scenes. `.sci` rects 1 and 3 visible `.sav` per covered card, before
   and after, unchanged.
   GEOMETRY: the side bands hold — stripW 75.41 → 74.04 (b2) and 74.23 → 74.10 (b1) against the
   integration's 75.4 / 74.2 ± 2. The covered cards LOSE HEIGHT because `.st` no longer sets the flex
   row's height (bbox 294.8 → 222.9 on b2, 229.0 → 217.0 on b1); the side band moves because those
   boxes are ROTATED, so a shorter card has a narrower bounding box. `.mockswap` stays 340 px, so the
   stage does not move, and the measured effect is that the fan now steps evenly (card bottoms
   243 / 254 / 271) instead of b2 running ~100 px below the front card and off the 340 px stage.
   S14 DENOMINATOR: 6 routes carry the deck (`/ /ar /bn /es /hi /mr`) × 5 `.mscene` × 2 covered cards
   = 60 covered cards, every one served by the two selectors below. Measured on `/` and `/ar` (20 of
   60); the other four locales take the identical rule from this sheet — an OWED read, not a cure.
   `/referral-home` has `.mscene` and zero `.mcard-b*`: the negative control.
   ⚠ REPORTED, NOT CURED (S13 — a disagreement, not a defect): in `/ar` the deck keeps its PHYSICAL
   `left` offsets while the card CONTENT mirrors, so a covered card's icon and avatar chips sit on the
   TRAILING (covered) side — measured `sciInStrip false` on both covered cards, BEFORE and AFTER. The
   `/ar` strip is therefore card surface and row separators only. Mirroring the deck would change
   frame-derived geometry; that is the founder's call, not this lane's. */
.mockswap .mcard-b1,
.mockswap .mcard-b2 { -webkit-mask-image: none; mask-image: none; opacity: 1; }
.mockswap .mcard-b1 .srow .st, .mockswap .mcard-b2 .srow .st,
.mockswap .mcard-b1 .srow .sm, .mockswap .mcard-b2 .srow .sm { display: none; }

/* WALK 2026-09-07 - P3-OP-5 (B) - THE ar COVERED-CARD STRIP WAS EMPTY ON 10 OF 10
   OPERATOR RULING 7, 2026-09-07 06:48 CT, verbatim: "the furthes back card doesnt show anything we
   gotta clean this up, use the frame gallery to find static frames we can derive inspiration or
   guidance for the content of the cards, now how the cards are postioned is completely fine".
   NO FRAME for a covered .scard, and NO FRAME for an RTL deck anywhere in the 555-frame gallery
   (EG-DECK-CONTENT/TRIAGE.md section 0 and 1c: 2 of 555 frames draw the deck, both ltr).
   S13 branch 2 - correctness governs. INTERIM DEVIATION - UNRATIFIED.

   MEASURED BEFORE, EG-DECK-CONTENT/BEFORE.json, this worktree on :4360, dpr 2, routes / and /ar at
   1440 and 1280, scene driven through data-open on .jgrid with scene opacity asserted 1 before AND
   after every read, pointer parked at (2,2) and the park verified, read after networkidle never DCL.
   Coverage asserted inside the instrument: 20 of 20 cells processed, 0 errors, 40 of 40 covered
   cards seen.
     /ar  IN-BAND ELEMENTS PER COVERED CARD = 0 on 10 of 10, at BOTH widths (20 of 20 card-reads).
          .sci measured at dx 241.1-249 and every .sav at dx 247.4-251.7, on a band that ends at
          dx 72.25-74.86 - i.e. every leading item sits on the TRAILING, covered edge.
     /    the same cards read 2-5 in-band elements, so the loss is the writing direction and
          nothing else.
   INDEPENDENTLY CORROBORATED by the blind verifier on :4300 build Si9cZSyudeyIUuHnLD-Mx
   (VERIFY-MORNING/VERDICT.txt row 1): the .sci and .sav chips sit in the visible strip on 10 of 10
   covered cards on / and 0 of 10 on /ar, the chip 167 px past the covering edge. Two instruments,
   two ports, two sessions, same reading.

   THE CAUSE: the deck is laid out with PHYSICAL left 2 percent / 18 percent / 34 percent in both
   writing directions (the J3 block above, which is the frame byte-for-byte), while .shd and .srow
   are display:flex and mirror under dir=rtl. So the strip is on the physical left in both
   directions and the content is on the physical right in one of them.
   THE CURE, and it is the smallest thing that can work: the two COVERED cards lay their header row
   and their list rows out left-to-right. Their content is one icon glyph and coloured chips with a
   single Latin/loc initial - there is no sentence in them to mirror, because .st and .sm are
   display:none on these two cards (the EG-DECK-FADE rule directly above). .mcard-f keeps full RTL
   and is not named by any selector here.
   ALTERNATIVE CONSIDERED AND EXCLUDED BY THE RULING: mirroring the STACK on /ar (left to
   inset-inline-start) needs no content change at all and puts the strip on the physical right - the
   operator ruled the positions "completely fine". Recorded so the choice is visible.
   a11y: BOTH covered cards are aria-hidden="true" and pointer-events:none
   (HomeMarketing.tsx:293-294), re-verified true on 40 of 40 covered cards in the AFTER read, so no
   accessibility state changes. This is a visual ltr-ism inside an rtl page, on decorative nodes.
   S14 DENOMINATOR: 6 routes carry the deck (/ /ar /bn /es /hi /mr) x 5 .mscene x 2 covered cards =
   60 covered cards; the rule is inert on the 50 ltr ones (their containers are already ltr, measured
   0 delta on / at both widths) and cures the 10 rtl ones. /referral-home has .mscene and zero
   .mcard-b: the negative control. */
.mockswap .mcard-b1 .shd, .mockswap .mcard-b1 .srow,
.mockswap .mcard-b2 .shd, .mockswap .mcard-b2 .srow { direction: ltr; }

/* WALK 2026-09-07 - P3-OP-5 (A2) - THE IMMIGRATION CARD: AN ICON OVER THREE BLANK RULES
   Same operator ruling 7 as the block above; this is the card in his screenshot. NO FRAME for a
   covered .scard (TRIAGE section 0). S13 branch 2. INTERIM DEVIATION - UNRATIFIED.

   MEASURED BEFORE (BEFORE.json, :4360, same 20-cell instrument as above): on / at 1440 and 1280,
   msc-3 .mcard-b2 and msc-4 .mcard-b1 are the immig screen and read
       elsIn 2 (the .sci span and its 16.7 px svg), chipsPerRow 0, rowsRendered 3
   against 5 in-band elements and 3 chips on every other covered card. The strip is an icon chip
   over blank rules - the defect the operator named.
   THE CAUSE IS CONTENT-SHAPED, NOT A STYLE BUG: immig.rows in ALL SIX seeds carry no i key on any
   of the three rows (measured this session in home.json and ar/es/hi/bn/mr.home.json), so
   HomeMarketing.tsx:129-134 renders no .sav; and .st / .sm are display:none on covered cards.

   WHY A PSEUDO-ELEMENT AND NOT order:-1 ON THE ROW TAIL - decided by MEASUREMENT before either was
   written (S4: one attempt, and the refuted shape is recorded so nobody re-tries it):
   the immig rows use tail="step", so order:-1 on .sm would put a CheckSvg on row 0, the text 2/3 on
   row 1 and an 18x18 arrow svg on row 2 at the leading edge. Two of the three are 18 px against the
   brief acceptance floor of 21 px square, and the third un-hides text the operator has refused
   twice (walk-1 W-11, and again 2026-09-07). Refuted on its own numbers, NOT SHIPPED.

   THE CURE IS THE NEIGHBOURS, NO COLOUR IS MINTED (S13): 26 x 26, radius 8, is the pinned
   .scard .srow .sav box verbatim (marketing.css:217); var(--accent-bg) is the fill the pinned
   .scard .sci (marketing.css:214) and the frame's own .mock .sjl (marketing.css:176) already use on
   this very card. WORDLESS by operator question 41, default taken under G12 - the frame draws a
   one-word label, our heads render 64.2-149.9 px against a 51.9 px budget and would be cut.
   9b TOKEN SCOPE, ASKED OF THE BROWSER not the sheet, on .mcard-b2 .shd in the BEFORE read:
       getComputedStyle(el).getPropertyValue("--accent-bg") -> "#D6E2FD"   NON-EMPTY
       getComputedStyle(el).getPropertyValue("--tint")      -> "#E3ECFE"   NON-EMPTY
   (the page root is div.page.home.lvl2.portal-candidate.tok-iter3.fin, HomeMarketing.tsx:547, and
   the tokens are defined on .tok-iter3 - the deck is a descendant.)
   CAN IT WIN: 9 inline style={{ }} exist in HomeMarketing.tsx and every one of them sets background
   or color on .sav / .sjl / .sm. An inline style cannot reach a pseudo-element at all, so this
   declaration cannot lose the way the cookie-banner controls did (EG-23).
   IS IT VISIBLE: #D6E2FD on the card ground --card #FAFCFF is a max-channel delta of 36 of 255,
   above the 12 of the band-ink predicate. It is not painting its own ground.
   IN-BAND, DERIVED AND THEN MEASURED: a pseudo has no client rect, so its leading edge is derived
   as row.x + border-left + padding-left = card.x + 17 and its right edge as that + 26 = card.x + 43,
   against a band that ends at card.x + 72.25-74.86 - about 29 px of clearance. The instrument
   recomputes this per row and reports IN / CUT / OUT with the clearance.
   S14 DENOMINATOR: 10 of the 60 covered cards are the immig screen (b2 of msc-3 and b1 of msc-4, x
   5 ltr routes) and are the only rows in the deck with no .sav, so :not(:has(.sav)) selects exactly
   them and nothing else - measured 0 pseudo-chips on all other covered cards in the AFTER read.
   On /ar the same rule applies to whichever scenes render immig, and lands at the leading edge
   because of the direction rule above. */
/* RETIRED 2026-09-07 by operator ruling NRC-P1-244 - STRUCK IN PLACE, never deleted (S9), because
   the block above is a long and careful derivation and the reason it no longer ships is the whole
   point. The rule that stood here, verbatim:
     ~~.mockswap .mcard-b1 .srow:not(:has(.sav))::before,~~
     ~~.mockswap .mcard-b2 .srow:not(:has(.sav))::before {~~
     ~~  content: ""; width: 26px; height: 26px; border-radius: 8px;~~
     ~~  background: var(--accent-bg); flex: none; }~~
   THE OPERATOR REJECTED WORDLESS CHIPS: they read as "empty profile pictures". The chip itself was
   the right size and the right fill - what was wrong was that it carried nothing. Note that the
   block above records the chip as WORDLESS by operator question 41 taken on its recommended default
   under G12; this ruling REPLACES that inferred default with a real one, which is exactly what an
   INFERRED ruling is for.
   WHAT REPLACES IT AND WHERE: lane-c10 is adding LETTERED chips in HomeMarketing.tsx (components
   worktree) in the same wave. That is a MARKUP change - a pseudo-element cannot carry a per-row
   letter without inventing content in CSS - so it is the component lane's row, not this one's.
   ⚠ THE TWO LAND TOGETHER AT INTEGRATION. Between this commit and lane-c10's merge, the 10 immig
   rows (b2 of msc-3 and b1 of msc-4 on the 5 ltr routes) have NO leading chip at all, which is the
   BEFORE state this sheet inherited and not a new defect. Do not stamp this half alone.
   MEASURED BEFORE THIS RETIREMENT, :4360, s8-deck.mjs, coverage 20/20 cells and 40/40 covered cards:
   msc-3 .mcard-b2 and msc-4 .mcard-b1 read chips=3(sav0+ps3) - three pseudo chips, zero real ones.
   Every other covered card reads chips=3(sav3+ps0) and is NOT touched by this change.
   NOTHING ELSE FROM LANE-S8 IS TOUCHED: the direction rule and the .shd bar
   (.mockswap .mcard-b1 .shd, .mockswap .mcard-b2 .shd { background: var(--tint) }) stand. */
/* AND THE STRIKE ALONE IS NOT ENOUGH - THE SAME CASCADE FINDING AS P3-OP-19, ON A SECOND RULE, AND
   IT IS WHY THIS NEUTRALISER EXISTS RATHER THAN JUST AN ABSENCE. After the rule above was struck,
   s8-deck.mjs still read chips=3(sav0+ps3) on msc-3 b2 and msc-4 b1, 20/20 cells, 40/40 covered
   cards. Asked of the browser: the ONLY remaining copy of the declaration is the INLINED
   marketing-critical.css, which is a snapshot of this sheet taken before the strike -
   getComputedStyle(row, "::before").content is still the empty string with width 26px. Removing a
   rule from a sibling sheet cannot remove an extract of it, so a REMOVAL must be written as an
   explicit override, exactly as an addition would be.
   `content: none` suppresses the pseudo-element entirely; equal specificity, later sheet, so it
   wins whether or not the extract is refreshed. */
.mockswap .mcard-b1 .srow:not(:has(.sav))::before,
.mockswap .mcard-b2 .srow:not(:has(.sav))::before { content: none; }

/* WALK 2026-09-07 - P3-OP-5 (D-fill) - THE COVERED CARD READS AS A CARD BEHIND A CARD
   Same operator ruling 7. This half IS frame-derived (S13 branch 1 applied by transposition): the
   only two frames in the 555-frame gallery that draw a covered card draw it as .mock .shot with a
   tinted title bar - marketing.css:169 (PINNED) reads
       .mock .shot .hd{height:24px;background:var(--tint);border-bottom:1px solid var(--line)}
   and it is the frame's strongest "this is a card behind a card" cue. .scard .shd already carries
   the 1 px var(--line) bottom border (marketing.css:213), so only the fill is missing.
   MEASURED BEFORE (BEFORE.json): shd background-color rgba(0, 0, 0, 0) on 40 of 40 covered-card
   reads, both routes, both widths - the header row is card ground.
   9b: var(--tint) proven in scope by asking the browser on this exact element - see the block
   above, "#E3ECFE", non-empty. IS IT VISIBLE: #E3ECFE on --card #FAFCFF is a max-channel delta of
   23 of 255, above the band-ink predicate's 12. CAN IT WIN: .shd carries no inline style in
   HomeMarketing.tsx (the 9 inline declarations are background on .sav/.sjl and color on .sm).
   NOTHING MOVES: this is a paint-only declaration - 0 elements change rect, 0 text is un-hidden,
   .shd-t stays display:none (W-11) and the deck geometry is untouched.
   THE 3 DOTS ARE NOT SHIPPED AND ARE AN OWED ROW, not an omission: the frame draws 3 x 7.7 px
   var(--tint2) circles inside that bar (.mock .shot .hd i, marketing.css:170). They are MARKUP the
   .scard does not have, and the only sheet-only shape - .shd::before - takes the same leading flex
   slot the .sci icon chip occupies, so it would DISPLACE the one element that carries the strip.
   Owner: component-surgeon lane, about 15 min, one span triple in SceneCard. Recorded in
   EG-DECK-CONTENT/NOTES.md.
   S14 DENOMINATOR: all 60 covered cards (6 routes x 5 .mscene x 2), every one served by these two
   selectors; .mcard-f is not named. */
.mockswap .mcard-b1 .shd,
.mockswap .mcard-b2 .shd { background: var(--tint); }

/* OPERATOR SMOKE 2026-09-12 — the covered cards already contain the neighbouring scene's full
   rows, but the no-sliced-words ruling above intentionally hides their text. Keep that ruling and
   show each neighbouring card's own CMS title and row text in the exposed strip. The next card
   naturally covers the remainder, as the operator explicitly requested; the
   front card remains unchanged and no statistic or translated sentence is invented. */
/* Operator follow-up 2026-09-12: the neighbouring card's existing title should remain visible in
   the exposed strip even when the card above naturally covers the rest. This latest ruling replaces
   the earlier hidden-title treatment; the front card and the deck geometry do not move. */
.mockswap .mcard-b1 .shd-t,
.mockswap .mcard-b2 .shd-t {
  display: block; position: absolute; left: 50px; white-space: nowrap;
}
.mockswap .mcard-b1 .shd,
.mockswap .mcard-b2 .shd { position: relative; }
.mockswap .mcard-b1 .srow,
.mockswap .mcard-b2 .srow { position: relative; }
.mockswap .mcard-b1 .srow .st,
.mockswap .mcard-b2 .srow .st {
  display: block; position: absolute; left: 52px; white-space: nowrap;
}

/* OPERATOR SMOKE 2026-09-12 — all four analytics scenes share the fixed 268px stage. The short
   tables and lists previously ended halfway down it. These source-free trend shapes reuse the
   approved analytics graph already present in this card; their only job is to complete each scene's
   visual hierarchy without adding claims. Heights are tailored to the content already above them. */
.p-trans .analytics .tscene > .scene-list { height: 100%; }
.p-trans .analytics .tscene .scene-list > .srow,
.p-trans .analytics .tscene .scene-list > .ss > .srow { min-height: 76px; }
.p-trans .analytics .tscene .scene-list .an-tbl td { padding-top: 20px; padding-bottom: 20px; }
.p-trans .analytics .tsc-4 .scene-list > .srow { min-height: 58px; }
.p-trans .analytics .an-company-mark {
  width: 28px; height: 28px; border-radius: 8px; margin-inline-end: 10px;
  display: inline-flex; align-items: center; justify-content: center; vertical-align: middle;
  background: var(--accent-bg); color: var(--cta-fill); font-weight: 800;
}
.p-trans .analytics .payout-preview { height: 100%; }
.p-trans .analytics .payout-kpis { display: grid; grid-template-columns: repeat(2,1fr); gap: 10px; margin-top: 12px; }
.p-trans .analytics .payout-kpi {
  border: 1px solid var(--line); border-radius: var(--r-tile); padding: 12px 14px;
  background: var(--card);
}
.p-trans .analytics .payout-kpi b { display: block; font: 800 20px/1.1 var(--font-head); color: var(--ink); }
.p-trans .analytics .payout-kpi span { display: block; margin-top: 5px; font-size: 11px; color: var(--mut); }
.p-trans .analytics .payout-history { margin-top: 10px; border-top: 1px solid var(--line); }
.p-trans .analytics .payout-row { display: flex; align-items: center; gap: 10px; min-height: 58px; border-bottom: 1px solid var(--line); }
.p-trans .analytics .payout-glyph {
  width: 28px; height: 28px; border-radius: 8px; display: flex; align-items: center;
  justify-content: center; flex: none; background: var(--accent-bg); color: var(--cta-fill); font-weight: 800;
}
.p-trans .analytics .payout-row > div { flex: 1; min-width: 0; }
.p-trans .analytics .payout-row > div b,
.p-trans .analytics .payout-row > div span { display: block; }
.p-trans .analytics .payout-row > div b { font-size: 12px; }
.p-trans .analytics .payout-row > div span { margin-top: 2px; font-size: 11px; color: var(--mut); }
.p-trans .analytics .payout-row > .ab { border-radius: var(--r-pill); padding: 3px 10px; font-size: 10px; font-weight: 700; }
.p-trans .analytics .payout-row > .ab.live { background: var(--green-tint); color: var(--pos); }
.p-trans .analytics .payout-row > .ab.closed { background: #EEF0F4; color: #6E6E73; }

/* ═══ WALK · W-02b · THE TWO LOGO ROWS RAN 11.5 % APART ════════════════════════════════════════════
   Both rows declare `30s linear infinite` (marketing.css:235-236, pinned) and both translate by −50 %
   of their OWN track, so the speed is the set width ÷ 30 s and the rows differ because their contents
   differ. MEASURED at 1440 (saver ON and OFF) and at 1920 — the widths are identical in all three, so
   they are content-driven and stable:
       left  set 3581.3 px → −119.4 px/s        right set 3991.9 px → +133.1 px/s      (11.5 % apart)
   The right row's duration is set from its OWN width so both run at one speed:
       3991.9 ÷ 3581.3 × 30 s = 33.44 s     ⇒ 3991.9 ÷ 33.44 = 119.4 px/s
   ⚠ THE NUMBER IS DERIVED FROM CONTENT AND MUST BE RE-DERIVED IF THE STRIP'S CONTENT CHANGES — the
   arithmetic is written above so the next reader recomputes rather than guesses. The left row keeps
   the pinned 30 s, so the pinned value still governs the pair's speed. */
.lr-right .logo-track { animation-duration: 33.44s; }

/* ═══ WALK · ST-15 (ST-1001, operator p.9, 2026-10-01) · THE LOGO CAROUSEL IS SLIGHTLY TOO FAST ════
   Verbatim: "Slow down the company logo carousel, it slightly too fast". NO FRAME consulted for the pace
   (the pinned 30 s at marketing.css:235-236 is the build's value). INTERIM DEVIATION · UNRATIFIED.
   MEASURED: only the source this pass (browsers forbidden) — pace before = W-02b's 1440 reading above,
   119.4 px/s on both rows. Cure = BOTH rows × 1.5, so W-02b's equal-speed ratio is kept exactly:
       left 30 s → 45 s · right 33.44 s → 50.16 s   ⇒ predicted ≈ 79.6 px/s on both rows at 1440.
   Duration only: keyframes (seam), hover pause and the reduced-motion `animation:none` are untouched
   (that media rule sets animation-name none, so a duration here cannot restart it).
   Reaches every `.lr-left/.lr-right .logo-track` (HomeMarketing, ReferralHomeMarketing,
   PlaceholderLogoMarquee); none of them carries an inline style on the track. Tripwire:
   src/styles/logoMarqueePaceTripwire.test.ts. Re-derive with W-02b's arithmetic if the strip changes. */
.lr-left .logo-track { animation-duration: 45s; }
.lr-right .logo-track { animation-duration: 50.16s; }

/* WALK 2026-09-07 - P3-OP-19 - THE JOURNEYS ACCORDION TAKES THE TRANSFORM BAND'S TREATMENT
   NRC-P1-280. Operator ruling #20 from a 14 s recording on the home band "Building career
   journeys" (.jgrid .acc), verbatim in intent: (1) "certain times, not all the time, there's a
   stutter if you scroll slow enough"; (2) "if I'm on the third drop tab and try to go back to the
   second, it skips the second and goes straight to the first"; (3) "the tab stays open when I
   leave - the body text disappears but the tab stays open when it should be closing"; (4) the
   Transform band (.sell .si) is "much better and much smoother - I favor the white background
   rather than the clear one; the blue outline that drops around the card on hover, the grey arrow
   turning blue, still animated - keep that consistent."
   INTERIM DEVIATION - UNRATIFIED against the Home frame, which draws border-top rows with item 1
   open at rest. The frame is not edited (S13); this block is one commit to revert.

   NOTHING BELOW IS MINTED (S13, take the cure from the neighbours). Every declaration is the
   Transform band's own, transcribed from :406-432 and :871-908 of this file and from the PINNED
   .sell .si (marketing.css:277), with .sell/.si re-keyed to .jgrid/.acc.

   MEASURED BEFORE - EG-DECK-HOVER/BEFORE-4360.json, :4360, dpr 2, / /ar /es x 1280/1440/1920 = 9
   cells, coverage asserted INSIDE the instrument (meant 9, processed 9, diff 0, errors 0); pointer
   parked at (5,5) and the park VERIFIED with matches(':hover') = 0 before every resting read
   (trap 13); every read after networkidle AND the .jgrid[data-input="on"] hydration marker, never
   DCL (trap 17):
     (c) PHANTOM at rest: row 1 is 176.75 px tall holding a 108.75 px body at opacity 0.
         phantomCount 1 of 5 rows, on 9 of 9 cells.
     (a) OPEN of row 2, per rAF: maxFrameDelta 108.75 px (/ , /es) and 134.06 px (/ar),
         movingFrames 1, durationMs 0 - a snap, not a transition. CLOSE: maxFrameDelta 65.25 px
         over 350.8 ms. Against the brief's floors (<= 4 px per frame, 320 +- 40 ms) both fail.
     (e)(f) CARD at rest and on hover: background rgba(0,0,0,0) in BOTH states; border-top-color
         rgb(217,226,243) = --line in BOTH states; box-shadow `none` in BOTH states. The card
         itself has NO hover response at all - the same `delta {}` the walk found on .sell .si
         (W-04, cured at :905 above). The arrow already turns rgb(33,100,244) = --brand and the
         h3 already turns --ink; those two are pinned and are NOT touched here.
     (d) STAGE at rest and across all 5 open states: drift 0.00 px on / and /ar; 1.39 px on /es,
         whose list column already overruns the 660 px reserve by 2.78 px BEFORE this change - an
         EXISTING J2 residue, recorded here, not created by this block.
   9b TOKEN SCOPE, ASKED OF THE BROWSER on a real .jgrid .acc element in the BEFORE read, not read
   off the sheet - all NON-EMPTY, so no var() here can silently invalidate its declaration:
       --card #FAFCFF   --line #D9E2F3   --r-tile 14px   --brand #2164F4
       --sh-card 0 14px 38px rgba(30,45,110,.10)         --sh-soft 0 5px 14px rgba(30,45,110,.07)
       --ink #1D1D1F    --mut #6E6E73    --cta-fill #1A52C4
   (the page root is div.page.home.lvl2.portal-candidate.tok-iter3.fin, HomeMarketing.tsx:547;
   .acc is a descendant, so the .tok-iter3 tokens reach it.)
   CAN IT WIN (EG-23): `grep -n 'style={{' HomeMarketing.tsx` returns 9 hits and NOT ONE is on .acc
   or any of its children - all 9 set background/color on the deck's .sav / .sjl / .sm, plus one
   margin on the page wrapper. JourneysInput.tsx writes only data-open, aria-expanded, an id and a
   button wrapper; it sets no style property. No inline declaration outranks these selectors.
   IS IT VISIBLE (the third way a correct declaration renders nothing): --card #FAFCFF on the band
   ground is a real but SMALL step, reported as a number not a boolean; the hover ring --brand
   #2164F4 against that #FAFCFF card is a max-channel delta of 217 of 255. The ring is not painting
   its own ground.
   SPECIFICITY, written down because it is the design and not a discovery:
       PINNED  .acc                    (0,1,0)  border-top, padding 20px 0, flex, cursor
       PINNED  .home.lvl2 .acc         (0,3,0)  border 1px --line, radius --r-card, padding 18px,
                                                margin-bottom 10px   <- the card box ALREADY EXISTS
       here    .jgrid .acc             (0,2,0)  background + box-shadow + transition. Neither
                                                pinned rule declares background or box-shadow at
                                                all, so (0,2,0) is unopposed on those properties.
       here    .jgrid .acc:hover       (0,3,0)  ties .home.lvl2 .acc on border-color and WINS ON
                                                SHEET ORDER (this file loads after marketing.css).
       here    .jgrid[data-open=N]...  (0,6,0)  the held-open arm, over its own hover arm's :not().
   S14 DENOMINATOR, derived twice and stated with its qualifier: the `.jgrid .acc` band is emitted
   by TWO components - HomeMarketing.tsx:763 and ReferralHomeMarketing.tsx - and renders on the
   THREE ltr/rtl home roots that carry .p-jour (/, /ar, /es; /hi /bn /mr do not render the band -
   measured, EG-9b). 3 routes x 5 rows = 15 rows, x 3 widths = 45 cells measured here.
   /referral-home carries the same class and is NOT in this session's measured set - stated as an
   uncovered occurrence of the same root cause, not silently included. */

/* (1) THE CARD. The box (border, radius, padding, gap) is already the PINNED .home.lvl2 .acc; what
   the operator asked for is the WHITE GROUND and the resting lift the Transform card has from the
   pinned .sell .si{background:var(--card);box-shadow:var(--sh-soft)} (marketing.css:277). */
.jgrid .acc { background: var(--card); box-shadow: var(--sh-soft); position: relative;
              transition: border-color .2s ease, box-shadow .2s ease; }

/* THE GAP BRIDGE, transcribed from .sell .si::after at :407 with its own reasoning re-derived for
   this band: the rows are separated by the pinned `margin-bottom:10px`, and `top:100%` resolves
   against the PADDING box, i.e. 1 px above the border box, so 10 + 1 = 11 reaches exactly the next
   card's top edge. It paints nothing; it is hit-testing only. This is what removes the no-hover
   instant the operator's skip (2) travels through. */
.jgrid .acc::after { content: ""; position: absolute; left: 0; right: 0; top: 100%; height: 11px; }

/* (2) THE OPEN MECHANISM - the Transform band's, verbatim from :871-872, re-keyed. It animates the
   body's REAL height instead of a 240 px cap the content never reaches, and it needs no reserve. */
.jgrid .acc > div:has(> h3) { flex: 1; min-width: 0; display: grid; grid-template-rows: auto 0fr;
                              transition: grid-template-rows .32s cubic-bezier(.2, .8, .2, 1); }
/* `max-height: none` is LOAD-BEARING and is the neighbour's (.sell .si p, :872): without it the
   PINNED `.acc p{max-height:0}` (0,1,1) returns the instant the hover arm drops and the body
   VANISHES on close instead of easing shut - the grid track would be animating a box already
   clipped to zero. (0,2,1) beats it; the pinned 240 px cap on the open arms is left in place,
   exactly as the Transform band leaves it, because the grid track governs the height and the cap
   is never reached. */
.jgrid .acc p { min-height: 0; max-height: none; overflow: hidden;
                transition: opacity .32s cubic-bezier(.2, .8, .2, 1), margin .32s cubic-bezier(.2, .8, .2, 1); }
.jgrid .acc:hover > div:has(> h3),
.jgrid .acc:has(.acc-btn:focus-visible) > div:has(> h3) { grid-template-rows: auto 1fr; }
.jgrid[data-open="1"]:not(:has(.acc:hover)) .acc.cat-1 > div:has(> h3),
.jgrid[data-open="2"]:not(:has(.acc:hover)) .acc.cat-2 > div:has(> h3),
.jgrid[data-open="3"]:not(:has(.acc:hover)) .acc.cat-3 > div:has(> h3),
.jgrid[data-open="4"]:not(:has(.acc:hover)) .acc.cat-4 > div:has(> h3),
.jgrid[data-open="5"]:not(:has(.acc:hover)) .acc.cat-5 > div:has(> h3) { grid-template-rows: auto 1fr; }

/* (3) THE STATES - .sell .si:hover at :906-907, verbatim. Hover, real keyboard focus, and a held
   selection all get the same treatment; at REST no row is open (the closing arm at :38-40 above
   already rules that and is untouched) and the deck's rest scene .msc-1 stays lit as EG-9b/D6 rules. */
.jgrid .acc:hover,
.jgrid .acc:has(.acc-btn:focus-visible) { border-color: var(--brand); box-shadow: var(--sh-card); }
.jgrid[data-open="1"]:not(:has(.acc:hover)) .acc.cat-1,
.jgrid[data-open="2"]:not(:has(.acc:hover)) .acc.cat-2,
.jgrid[data-open="3"]:not(:has(.acc:hover)) .acc.cat-3,
.jgrid[data-open="4"]:not(:has(.acc:hover)) .acc.cat-4,
.jgrid[data-open="5"]:not(:has(.acc:hover)) .acc.cat-5 { border-color: var(--brand); box-shadow: var(--sh-card); }

/* THE REDUCED-MOTION ARM - the Transform band's own, :880-882 and :908. A user who has asked for
   less motion gets the state change with no transition; nothing is hidden from them. */
@media (prefers-reduced-motion: reduce) {
  .jgrid .acc                 { transition: none; }
  .jgrid .acc > div:has(> h3) { transition: none; }
  .jgrid .acc p               { transition: none; }
}

/* (2b) THE CASCADE OVERRIDE - AND IT IS THE MEASUREMENT THAT MATTERS MOST IN THIS BLOCK.
   STRIKING THE 5lh RESERVE AT :545 ABOVE CHANGED NOTHING. AFTER-1 came back BYTE-FOR-BYTE
   identical to BEFORE on all 9 cells - phantom 1, rafOpen maxFrameDelta 108.75, movingFrames 1 -
   and it was a CORRECT measurement of a page that still carried the struck declaration.
   WHY, asked of the browser and not of the sheet: `apps/web/public/design/marketing-critical.css`
   is INLINED in the document head, and it is a SNAPSHOT of the sibling sheets taken at extract
   time. document.styleSheets[1] (href null, 358 rules) still holds
       .jgrid .acc:hover p, ... , .jgrid[data-open="5"]:not(:has(.acc:hover)) .acc.cat-5 p
         { min-height: 5lh; }
   at (0,3,1)/(0,6,1), which outranks the new `.jgrid .acc p{min-height:0}` at (0,2,1). Deleting a
   declaration from a sibling sheet does NOT delete the copy that was already extracted from it.
   ⇒ A FOURTH WAY A CORRECT DECLARATION RENDERS NOTHING, beside the three the lane already knows
   (out of token scope / outranked by an inline style={} / invisible against its own ground):
   IT IS OUTRANKED BY AN EARLIER SNAPSHOT OF THE VERY RULE IT REPLACES. The strike is necessary and
   is NOT sufficient, and a cure that relies on the extract being regenerated is a cure that depends
   on someone else's build step.
   THE FIX IS NOT TO REGENERATE. The extract was regenerated only to MEASURE (and discarded before
   the commit, per the standing rule): the integration regenerates against :4300 at its own step, so
   the committed sheets must win on their own. This rule restates the reserve's OWN selector list at
   EQUAL specificity and neutralises it; the external sheet is later in document order than the
   inlined style element (measured: styleSheets[1] is the inline block, [12] is this file), so an
   equal-specificity declaration here wins whether or not the extract is ever refreshed.
   `max-height: none` is carried on the same list for the same reason - the inlined
   `.jgrid:not(:has(.acc:hover)) .acc.cat-1 p{max-height:0}` (0,5,1) would otherwise clip row 1's
   body to zero the instant the pointer leaves, making row 1's CLOSE snap while rows 2-5 ease.
   The grid track is 0fr in every closed state, so removing the cap opens nothing. */
.jgrid .acc:hover p, .jgrid .acc:has(.acc-btn:focus-visible) p,
.jgrid:not(:has(.acc:hover)) .acc.cat-1 p,
.jgrid[data-open="1"]:not(:has(.acc:hover)) .acc.cat-1 p,
.jgrid[data-open="2"]:not(:has(.acc:hover)) .acc.cat-2 p,
.jgrid[data-open="3"]:not(:has(.acc:hover)) .acc.cat-3 p,
.jgrid[data-open="4"]:not(:has(.acc:hover)) .acc.cat-4 p,
.jgrid[data-open="5"]:not(:has(.acc:hover)) .acc.cat-5 p { min-height: 0; max-height: none; }


/* ═══ ITEM T2 · P3-OP-11 — A ROW WITHOUT A BODY MUST NOT BLANK THE CARD ════════════════════════════
   ROW P3-OP-11 (NRC-P1-246). Operator, /ar home, 2026-09-07 08:49, two screenshots: hovering a
   Transform tab shows a BLANK card, and there is blank space where the scene should be.

   MEASURED BEFORE THE CURE (BEFORE.json, :4360 built from wt/graph/sheets 31cfc8be, hydrated DOM,
   pointer parked between reads and every hover confirmed with matches(':hover') — trap 13):
     /ar  1280 and 1440, BOTH toggle sides, all 4 rows:  every `.tscene` computed opacity 0.000
          on hover  ->  visible scenes []  ->  THE BLANK CARD.        (16 of 16 readings)
     /    1280 and 1440, BOTH toggle sides, all 4 rows:  row N shows scene N, opacity 1.000.
     Rendered-DOM census of the root cause (DENOMINATOR.json, hydrated, not curl — a served-HTML
     count is a FLOOR): 6 home routes carry the band; `.si` rows 48; rows carrying `cat-N` 8 (en
     only); rows WITHOUT it 40  =  5 routes (/ar /bn /es /hi /mr) x 2 toggle sides x 4 rows.
     /referral-home carries NO `.p-trans` band (ReferralHomeMarketing.tsx:30) — out of the set.
     All four `.tscene`s are PRESENT and NON-EMPTY on all six routes (scenesWithText 4/4 each), so
     the scenes are built and populated in every locale; only the hook that selects them is absent.

   THE ROOT CAUSE, in the sheet: ITEM T's selection arms (:869-872, :880-881) key on `.si.cat-N`,
   while the arm that clears the stage (:879 `.p-trans:has(.sell .si:hover) .tscene{opacity:0}`)
   keys on ANY `.si`. `SellList.tsx:64` emits `cat-${idx+1}` ONLY for a row that has a body, and the
   body-less path is DELIBERATE (SellList.tsx:20-24 — an empty disclosure is worse than none). So on
   every locale whose `trans.{rec,aff}.sellBody` is unseeded, hovering a row fires the clear arm and
   no restore arm: four scenes at opacity 0, an empty card. The sheet assumed a class the component
   is documented not to always emit.

   THE CURE, and it is taken from the neighbour rather than invented (S13/S14): select the scene by
   the row's POSITION as well as by its class. The two are equivalent BY CONSTRUCTION — `cat-N` is
   derived from the same zero-based index (`cat-${idx+1}`), and `.sell`'s only element children are
   the four `.si` divs — so these arms agree with the `cat-N` arms wherever those apply (en: verified
   row N -> scene N, unchanged) and are the only arms that fire where they do not (the other five
   locales). Nothing is removed and nothing is overridden away: `marketing-critical.css` inlines the
   `.tscene` rules (11 occurrences of `tscene`; positive control `p-nav` = 53), so a struck
   declaration would still paint from the inline copy — these are ADDITIVE arms at (0,6,0), above
   the clear arm's (0,5,0), appended at the end of the sheet so source order cannot be the question.
   NO FRAME governs this state: the approved Home frame draws ONE static analytics card and no
   hover behaviour at all, so ITEM T is already an INTERIM DEVIATION · UNRATIFIED (operator ruling
   2026-09-06 16:18) and this repairs that deviation on the locales it was silently skipping.
   INTERIM DEVIATION · UNRATIFIED.
   ⚠ NOT CURED HERE, REPORTED (see LANE-S15-REPORT.md): the body-less rows are not drop-tabs at all
   — no <h3>, no <p>, no arrow, no control, so there is no keyboard arm to add (`.acc-btn` does not
   exist on them). That is CONTENT (`trans.{rec,aff}.sellBody`, 8 strings x 5 locales = 40 unseeded),
   not a sheet rule, and a sheet cannot manufacture a body. */
.p-trans:has(.sell .si:nth-child(1):hover) .tsc-1,
.p-trans:has(.sell .si:nth-child(2):hover) .tsc-2,
.p-trans:has(.sell .si:nth-child(3):hover) .tsc-3,
.p-trans:has(.sell .si:nth-child(4):hover) .tsc-4 { opacity: 1; }

/* ==========================================================================================
   P3-OP-38 + P3-OP-39 — CARD HOVER: blue outline + a slight 3D pop; help-centre rows get the
   same family in a BOUNDED, RADIUSED box.  lane-s19 (sheet-surgeon), 2026-09-07.

   WHY THIS SHEET: this file already carries the D7 hover mechanism these rows transcribe
   (`.jgrid .acc:hover` at :1351-1352). One technique, one sheet (S8/S14). The pinned
   marketing.css:380 (`.mkt-fcard`) and design-system.css:2697/2703 (`.cms-topic`, `.cms-hlrow`)
   are NEVER edited — sha/md5 unchanged, printed in the row's evidence.

   AUTHORITY: operator rulings #37 and #39, 2026-09-07, verbatim in the brief —
   #37 "I want it to glow ... or have a blue line, and I want it to pop a little bit as if it
       has depth ... this one doesn't need an arrow ... Not too heavy of an animation here, but
       the blue outline for sure."
   #39 "some type of highlighter animation whenever you hover over it, so you know this is a
       button ... it has to be in a specific box, and the corners have to have the radius as
       we've been doing it."
   The approved frames draw all of these cards STATIC, so both rows are an
   INTERIM DEVIATION · UNRATIFIED (S13) — the founder reverses them by deleting this block.

   TAKEN FROM THE NEIGHBOUR, VERBATIM — NOTHING MINTED (S13):
     border-color   var(--brand)   = #2164F4        `.jgrid .acc:hover`, this sheet :1352
     box-shadow     var(--sh-card) = 0 14px 38px rgba(30,45,110,.10)      same rule
     rest shadow    var(--sh-soft) = 0 5px 14px rgba(30,45,110,.07)       marketing.css:380
     transition     border-color .2s ease, box-shadow .2s ease            this sheet :1319
     radius         var(--r-card) 18px / var(--r-tile) 14px               design-system tokens
   The ONLY value not on a neighbour is the depth the operator asked for in words and the
   brief proposed as a range: translateY(-2px) + scale(1.015). It is set at the S1 FLOOR
   (2 px, 2 % — 1.5 % scale reads together with the 2 px lift as one motion) and no further,
   which is what "not too heavy" means in a number.

   §9b — MEASURED IN THE BROWSER, not read off the JSX (BEFORE.json, 10 cells, all True):
     getComputedStyle(.mkt-fcard).getPropertyValue('--brand')   -> '#2164F4'
     ... ('--sh-card') -> '0 14px 38px rgba(30,45,110,.10)'   ('--sh-soft') -> non-empty
     ... ('--line') -> '#D9E2F3'   ('--r-card') -> '18px'   ('--r-tile') -> '14px'
   Same six non-empty on `a.cms-topic` and on `.cms-hlrow`. Every var() below is in scope.

   CAN IT WIN — the card element carries an inline `style={{textDecoration,color}}` when it has
   an href (CardLink, ArticleView.tsx:258). That inline declaration names NEITHER border-color,
   box-shadow NOR transform, so these rules win the cascade on every property they set.
   Specificity: `.page .mkt-fcard:hover` (0,3,0) over the pinned `.mkt-fcard` (0,1,0);
   `.page a.cms-topic:hover` (0,2,1) over `.cms-topic` (0,1,0) in two sheets, and this sheet
   loads 11th of 14, after both. Verified in the served <head>.

   DOES IT RENDER AGAINST ITS OWN GROUND — the third failure mode. The ring #2164F4 sits on
   the card ground --card #FAFCFF; measured contrast and ΔE2000 are in AFTER-1/AFTER-2.json.
   A ring that ties its ground would be a correct rule that paints nothing.

   MEASURED BEFORE (BEFORE.json, 10 cells at 1280 and 1440, pointer parked and matches(':hover')
   asserted True on every cell): border ΔE2000 = 0.000 · box-shadow unchanged · transform
   none -> none = 0.00 px / 0.0 %. There is no hover response today, on any of them.

   NO ARROW, NO EXPANSION, NO CONTENT MOVES. `transform` is composited: it does not reflow, so
   sibling rects are unmoved (asserted per cell). The highlight box is drawn by ::before with
   negative insets — it changes NO layout box and cannot bleed past its own radius.
   ========================================================================================== */

/* ---- P3-OP-38 — the feature cards (.mkt-fcard). Already a bordered, radiused, shadowed box,
   so the neighbour's two declarations land directly on it. ---- */
.page .mkt-fcard {
  transition: border-color .2s ease, box-shadow .2s ease, transform .2s ease;
  will-change: transform;
}
/* ⛔ P3-OP-61 (2026-09-07, lane-s25) — THE SCALE IS STRUCK IN PLACE (S9). The declaration read:
     ~~transform: translateY(-2px) scale(1.015);~~
   OPERATOR, verbatim: the feature cards in "The tools the job actually needs" on /recruiters go
   BLURRY on hover. He is right, and it is measured, not inferred.

   NO FRAME draws a hover on these cards (the approved set draws them static — P3-OP-38's own
   header above says so), so S13 leaves correctness as the only governor. The 2 px lift, the
   --brand ring and the --sh-card shadow the operator asked for in rulings #37/#39 are UNCHANGED;
   nothing is invented and no value is minted. Only the scale goes.

   WHY A 1.5 % SCALE IS NOT FREE: `.mkt-fcard` bears live text (an <h3> at 16px and a <p> at
   13.5px, pinned marketing.css:380ff). Scaling a text-bearing box re-rasterises its glyphs at a
   NON-INTEGER size, and `will-change: transform` on the line above promotes the card to its own
   compositing layer, where the glyphs are rasterised ONCE at 1x and then RESAMPLED for every
   intermediate scale — which is why the softest frame is mid-transition, not the settled one.

   MEASURED BEFORE (BEFORE.json + BEFORE-sharpness.json — 8 cells: /recruiters + /employers, en
   and the ar twins /ar/masuulu-altawzif + /ar/lilsharikat, at 1440 and 1280; real pointer, card
   scrolled to centre, matches(':hover') asserted TRUE on 8/8 for every hover read and FALSE
   before every resting read (trap 13); networkidle, never domcontentloaded (trap 17); dpr 2).
   PREDICATE for every sharpness number below: mean |4c − N − S − E − W| (3x3 cross Laplacian)
   over the BT.601 luma of the card TITLE's own bounding rect in THAT state, +2 px pad — a
   per-pixel DENSITY, so the ~1.5 % area change between rest and hover cannot move it.
     rest-vs-rest NOISE FLOOR (two parked captures)   0.0000 on 8 of 8 cells
     settled hover vs rest      −3.69 % .. −5.73 %   (mean −4.69 %)
     mid-transition (~100 ms)   −27.47 % .. −29.10 % (mean −28.26 %)   ← the operator's "blurry"
   Both are far outside a 0.0000 noise floor. Card transform at rest `none` → settled
   `matrix(1.015, 0, 0, 1.015, 0, −2)` on 8/8; the TEXT child reads `none` in BOTH states, because
   transform does not inherit — a child-level read cannot see this defect and must not be used.

   AND THE LIFT WAS NEVER 2 px. scale(1.015) about the default 50 % 50 % origin raises the top
   edge by a further h × 0.0075, so the card's own rect moved +3.009 / +3.080 / +3.161 px, not the
   2 px the P3-OP-38 header claims. Deleting the scale returns the lift to the declared 2.000 px.

   S14 DENOMINATOR, derived before this edit, two ways: (1) served-HTML FLOOR over the 131-route
   sitemap (`grep -c '<loc>'` and `grep -o '<loc>' | wc -l` both 131) = 46 routes carrying >= 1
   `.mkt-fcard`, 164 cards — NOT the 12 routes / 72 cards an employer+recruiter-twins reading
   gives; a curl count is a FLOOR, so (2) the HYDRATED DOM was read on the 8 cells by two
   structurally different counts (querySelectorAll vs a TreeWalker classList scan): 4/4 and 8/8,
   agreeing on every cell. One rule, one sheet, all 46 routes cured together (S8/S14).

   `will-change: transform` above is KEPT, and that was MEASURED rather than assumed. Three arms,
   same 8 cells, same predicate (ARMC.json): (A) as-is · (B) scale removed, will-change kept —
   this rule · (C) scale removed AND `will-change: auto` injected as a later same-specificity rule.
     settled hover vs rest    A −4.69 %   B  0.00 %   C  0.00 %      (noise floor 0.0000)
     mid-transition vs rest   A −28.26 %  B −8.36 %   C −9.10 %      (mean of 8)
   C is not better than B — it is 0.74 pp worse on a figure whose own jitter is larger than that,
   because the residual mid-transition softening is caused by the SUB-PIXEL translateY of the 2 px
   lift (−1.60 .. −1.75 px at the sampled frame), which no layer hint removes. So will-change earns
   its place by doing no harm and keeping the promotion explicit; removing it would be a change
   with no measured benefit. ⚠ RESIDUE, carried and not hidden: the ≤ 200 ms transition is still
   −6.80 % .. −13.20 % sharper-at-rest than mid-flight. That is inherent to animating a 2 px lift
   and is recorded in the row's REPORT.md rather than cured here. ---- */
.page .mkt-fcard:hover,
.page a.mkt-fcard:focus-visible {
  border-color: var(--brand);
  box-shadow: var(--sh-card);
  transform: translateY(-2px);
}

/* ---- P3-OP-39 — the help-centre rows and topic cards. These have NO border, NO radius and NO
   shadow of their own (measured: borderRadius 0px, box-shadow none), so the operator's "specific
   box ... with the radius as we've been doing it" is drawn as an overlay rather than by
   restyling the row — which is also what keeps the layout byte-identical.

   ⛔ KEYED ON THE ANCHOR, DELIBERATELY. `CardLink` emits an <a> only when the seed gives the row
   a destination and a plain <div> otherwise (ArticleView.tsx:257-265). A hover box on the <div>
   would advertise a button that does not exist — the operator's own test is "so you know this is
   a button". Rows without an href therefore stay static, and light up by themselves the day the
   seed supplies one. MEASURED: /help-center serves 11 cms-topic anchors and, in the HYDRATED DOM,
   cms-hlrow rows that are anchors too — the served HTML reported 0 of those and was a FLOOR. ---- */
/* ---- P3-OP-51 (2026-09-07, lane-s24) — TWO CORRECTIONS TO THE BLOCK BELOW. NO FRAME draws a hover
   box (S13 still governs: correctness only), so the ring, the 14 px radius and the --card fill are
   UNCHANGED. Operator, verbatim: "whenever I hover over the highlighted articles, it does not show
   the text on the button, and the button itself is much too big."

   (a) STACKING — CURED FOR THE WHOLE FAMILY (S14: a.cms-topic, a.cms-hlrow, a.cms-gcard together).
   `z-index:0` on the pseudo plus `> *{z-index:1}` on the children was the WRONG STACKING MODEL. A
   `.cms-hlrow` anchor's content is a BARE TEXT NODE (`<CardLink className='cms-hlrow'>{row.title}`,
   ArticleView.tsx:692), so `> *` matches ZERO elements there and lifts nothing — while in-flow
   inline text paints at CSS painting step 5 and a positioned z-index:0 descendant paints at step 8,
   i.e. ON TOP OF IT. MEASURED on /help-center at 1280 and 1440 (BEFORE.json), on RENDERED PIXELS
   inside the row's own rect, predicate stated with the number: modal = most-frequent colour in the
   rect, ink = px with relative luminance <= modalLum-0.15, contrast = WCAG(mean darkest 1 %, modal):
       a.cms-hlrow   text contrast   resting 15.959:1  ->  HOVER 1.000:1   (a flat fill: no ink)
                     ink coverage    resting  8.304 %  ->  HOVER 0.000 %
       a.cms-topic   (element children, so the old lift did work there)  15.959 -> 16.376:1
   CURE: `isolation:isolate` on the anchor and `z-index:-1` on the pseudo. Inside a stacking context
   a negative z-index paints ABOVE the element's own background and BELOW ALL in-flow content, text
   nodes included — which is what the `> *` lift was trying, and failing, to express. All three
   anchors are background-less (design-system.css:2697/2703, marketing-cms.css:553), so nothing of
   their own can swallow the box — checked, because a rule that reaches and wins can still paint
   into its own ground. The `> *` lift is KEPT: at z-index -1 it cannot change the outcome, and
   keeping it holds the topic/gcard resting state byte-identical (measured: ink 12.348 % -> 12.348 %).

   (b) SIZE — hlrow ONLY. The override sits immediately after this rule. ---- */
.page a.cms-topic,
.page a.cms-hlrow,
.page a.cms-gcard { position: relative; isolation: isolate; }

.page a.cms-topic::before,
.page a.cms-hlrow::before,
.page a.cms-gcard::before {
  content: "";
  position: absolute;
  inset: -12px -16px;                 /* the box is bigger than the text row, and nothing else moves.
     UNCHANGED for topic/gcard, which carry no padding of their own. OVERRIDDEN for .cms-hlrow only,
     immediately below — see P3-OP-51 (b). */
  border: 1px solid var(--brand);
  border-radius: var(--r-tile);       /* 14px — the site's own tile radius, not a chosen number */
  background: var(--card);            /* VARIANT 2. Variant 1 was rgba(33,100,244,.05) — the blue
     tint the word "highlighter" suggests — and it was MEASURED FAILING and reverted: the
     `.cms-topic` description text is `--mut` #6E6E73 on the page ground, already CONTRAST-MARGINAL
     at 4.748:1 before this row existed, and a 5 % blue wash pushed it to 4.450:1 — BELOW S1's 4.5
     floor, in the hover state, at 1280 AND 1440. A cure may not spend a marginal control's
     remaining headroom. `--card` #FAFCFF is the fill the sibling hoverable card already uses
     (`.jgrid .acc{background:var(--card)}`, this sheet :1318) — taken from the neighbour, not
     minted (S13) — and being LIGHTER than the page ground it RAISES the text's contrast instead
     of spending it. Measured after: see AFTER-1/AFTER-2 text_contrast_hover. */
  box-shadow: var(--sh-card);
  opacity: 0;
  pointer-events: none;               /* hit-testing is unchanged; the row is still the target */
  z-index: -1;                        /* P3-OP-51 (a). WAS `0`, which painted the fill OVER a bare
     text node. -1 inside the isolated stacking context above = above the anchor's own background,
     below every in-flow child INCLUDING text nodes. */
  transition: opacity .2s ease;
}
.page a.cms-topic > *,
.page a.cms-hlrow > *,
.page a.cms-gcard > * { position: relative; z-index: 1; }

/* ---- P3-OP-51 (b) — SIZE, `.cms-hlrow` ONLY. MEASURED, /help-center, 1280 and 1440 (BEFORE.json):
   the row is 62 px tall (padding 21px 4px + a 1 px border-bottom, design-system.css:2703 /
   marketing-cms.css:463) and the painted box — bbox of the #2164F4 ring in the rendered hover
   screenshot — was 85 px, i.e. row + 23 px, overhanging 14.09 px into the row ABOVE and 8.91 px
   into the row BELOW (`.cms-hl` has row-gap 0, so the rows are adjacent and the box crossed two
   border lines). That is the operator's "much too big". The topic cards keep -12px -16px because
   they carry NO padding of their own; only hlrow does, and the negative inset was spending it
   twice. This inset keeps the box INSIDE the row's own padding box vertically and 12 px past it
   horizontally (the two `.cms-hl` columns are 46 px apart, so 12 px each side leaves 22 px clear).
   NO FRAME draws this box: the ring, radius, fill and shadow above are untouched. ---- */
.page a.cms-hlrow::before { inset: 6px -12px; }

.page a.cms-topic:hover::before,      .page a.cms-topic:focus-visible::before,
.page a.cms-hlrow:hover::before,      .page a.cms-hlrow:focus-visible::before,
.page a.cms-gcard:hover::before,      .page a.cms-gcard:focus-visible::before { opacity: 1; }

.page a.cms-topic,
.page a.cms-hlrow,
.page a.cms-gcard { transition: transform .2s ease; }
.page a.cms-topic:hover,  .page a.cms-topic:focus-visible,
.page a.cms-hlrow:hover,  .page a.cms-hlrow:focus-visible,
.page a.cms-gcard:hover,  .page a.cms-gcard:focus-visible { transform: translateY(-2px); }

/* ---- REDUCED MOTION: the outline stays (it is the information), the movement goes. The operator
   asked for depth; a user who has asked the OS for less motion has asked for it not to move.
   S1's transient-contrast rule has a reduced-motion arm that fires at ANY duration, and the
   cheapest way to satisfy it is to have no transition to trough through. ---- */
/* ============================================================================
   P3-OP-127 — THE TESTIMONIAL CARDS HAD NO HOVER AT ALL. Operator, 2026-09-08, on /about's quotes
   band: "same card animation here like the other pages pleqse".

   BEFORE, MEASURED: all 5 `.cms-qcard` on /about @1440 dpr2, hydrated, pointer PARKED at (3,3) with
   `matches(':hover')` asserted FALSE on ALL cards before every resting read and RE-PARKED between
   every pair (trap 13 — an unparked loop reads card 2..N in card 1's hover state):
     border-color rgb(217,226,243) #D9E2F3   UNCHANGED on hover
     transform    none                        UNCHANGED on hover
     box-shadow   none                        UNCHANGED on hover
   othersHovered FALSE on all 5. The hover produced ZERO change; there was no rule to weaken.

   S13 BRANCH 2 — NO FRAME. DISCRIMINATOR: the approved `About Us` frame's own sheet carries 0 hover
   rules for `.cms-qcard` (positive control: the selector appears 5 times there as base styles). The
   frame draws no hover on these cards, so nothing is contradicted; correctness governs and he asked.

   TAKEN FROM THE NEIGHBOURS, NOT MINTED: this is `.mkt-fcard`'s technique (P3-OP-61 / lane-s25, this
   sheet :1599). A parity request answered with a variant would defeat itself.
   ⛔ "APPLIED UNCHANGED" WAS FALSE AND IS CORRECTED HERE (bv-op127): the HOVER half is byte-identical,
   but the RESTING half omits `.mkt-fcard`'s `will-change: transform`. The verifier chased that because
   the operator has already called these cards BLURRY on hover (P3-OP-61), which is the right instinct.
   MEASURED CONSEQUENCE: NONE — text interior pixel-identical across rest / hover / hover+will-change,
   0 of 164,640 px. The word was wrong, not the CSS; do not "fix" it by adding the property.

   ⛔ AND A CONFLICTING OPERATOR RULING, 140 LINES ABOVE IN THIS SAME SHEET — say both, never one.
   P3-OP-39 (:1611): "A hover box on the <div> would advertise a button that does not exist — the
   operator's own test is 'so you know this is a button'. Rows without an href therefore stay static."
   That is HIS test, so this is two operator instructions in tension, not lane-vs-operator. §12 governs:
   prefer the more recent AND say both.
   WHY THIS BAND SHIPS THE LIFT ANYWAY — the older ruling's MECHANISM is absent here. `cms-hlrow` /
   `cms-topic` are SOMETIMES anchors (CardLink emits <a> with a destination, <div> without), so a static
   twin sits beside a lifting twin on the same page and the hover IS the information that separates
   them. `.cms-qcard` is ALWAYS a div, never an anchor, with no clickable twin anywhere (measured 30/30).
   There is no contrast case for the hover to corrupt. Reversible in one line if he rules otherwise.

   ⛔ AND THE S13 DISCRIMINATOR BELOW IS VACUOUS, recorded rather than quietly restated (bv-op127):
   "the frame draws no hover on these cards" COULD NOT have come out differently — the approved corpus
   carries :hover 0, :focus 0, :focus-visible 0, :active 0 across BOTH its stylesheets, i.e. zero
   interaction states for EVERY selector (positive control on the same method: marketing-interaction.css
   hover 63 / focus 62 / active 28). BRANCH 2 is still the right ruling, reached properly: the frame
   MEDIUM specifies nothing about hover, so correctness governs every interaction state in this project.
   §9b: both tokens checked ON THE ELEMENT before use — `--brand` '#2164F4' and `--sh-card`
   '0 14px 38px rgba(30,45,110,.10)' are IN SCOPE on `.cms-qcard`. No literal needed.
   SPECIFICITY: `.page .cms-qcard:hover` (0,3,0) over the pinned `.cms-qcard` (0,1,0); this sheet
   loads after marketing-cms.css, so it wins on order as well.
   DENOMINATOR (S14): 30 instances — 5 cards x 6 locale routes (about, ar, bn, es, hi, mr), derived
   from the seed corpus, which is where the quotes sections are defined.

   ⛔ NO `:focus-visible` ARM, DELIBERATELY. The precedent cards are ANCHORS; these are non-focusable
   `<div>`s with no href (measured: tag DIV, href null, focusable false, all 5). A focus rule on an
   element that cannot receive focus is a guard behind a branch nobody takes.
   ⚠ RECORDED, NOT DECIDED: a 2px lift on a non-interactive card creates the affordance of a clickable
   thing that does nothing when clicked. He asked for parity with cards that ARE links; that is what
   is built, and the affordance question is filed as its own row rather than silently answered. The
   lift-free variant (border + shadow, no transform) is one line. ---- */
.page .cms-qcard { transition: transform .2s ease, border-color .2s ease, box-shadow .2s ease; }
.page .cms-qcard:hover {
  border-color: var(--brand);
  box-shadow: var(--sh-card);
  transform: translateY(-2px);
}

/* ---- P3-04b (operator-2026-09-25-REVIEW-HOVER, ~05:36, 1440 shot of the About Us rail): "whenever i
   hover over a review card it should highlight light blue and the quotation mark should turn blue
   similar to the card thats fixed that way". The hovered card takes the FEATURED card's own look —
   the values are the pinned `.cms-qcard.mid` pair (marketing-cms.css:57-58: background
   var(--tint-panel), svg color var(--brand)), reused by token, so no colour is minted (S13) and the
   two can never drift apart. The P3-OP-127 lift / blue border / shadow above stay as they are.
   BEFORE, MEASURED (lead probe, 1440, pointer parked 500 ms on a real non-featured card): bg
   rgb(255,255,255), svg rgb(201,210,228); featured: bg rgb(238,243,255), svg rgb(33,100,244).
   DENOMINATOR (S14): /about is the only route that serves `.cms-qcard` — 15 nodes = 5 real + 10
   aria-hidden marquee clones (curl of :4300/about); /, /help-center, /blog, /contact, /employers 0;
   the 5 locale twins (/ar/about …) now 308 to /about. Scoped under `.cms-qmarq` so nothing else can match.
   GATED behind (hover: hover): a tap on a phone/tablet leaves a sticky :hover, and the task keeps
   no-hover devices unchanged — so the colours (and their transition) exist only where a pointer hovers.
   SPECIFICITY: (0,3,0)/(0,3,1) — which is also why the reduced-motion arm below has to be restated
   here: the shared `.page .cms-qcard { transition: none }` (0,2,0) cannot beat this transition. ---- */
/* ---- P3-04c (operator-2026-09-25-REVIEW-CENTRE, 11:28 + 11:33 "include the fill a well" + answer 13:43,
   verbatim, which voids the 12:28 hover-only amendment: "I want it to be shifting. Anytime someone is close
   to the middle, they get highlighted. They get the outline and all that. That's what I want.").
   This OVERRIDES the frame's pre-featured 3rd card (he said otherwise; frame-built-pages rule allows it).
   ONE LOOK, ONE TRIGGER — the "full treatment" is P3-OP-127's blue border + shadow + lift plus P3-04b's
   light-blue fill + blue quote mark, all by token (no colour minted, S13), and it is drawn ONLY by
   `.is-centre`, which AboutMarquee puts on exactly one card at a time, at every width and on every device:
   the card nearest the rail's centre, or — while a mouse is on the rail — the card under the pointer.
   BEFORE, MEASURED (lead probe-before.json, 4 contexts): Alex `.mid` bg rgb(238,243,255), border
   rgba(0,0,0,0), svg rgb(33,100,244) at rest everywhere; the others bg #fff, border rgb(217,226,243),
   svg rgb(201,210,228).
   `.mid` AT REST takes its siblings' values — the pinned base's own `#fff` / `var(--line)` / `#C9D2E4`
   (marketing-cms.css:55-56), restated because a sheet cannot "un-apply" the pinned `.mid` pair (:57-58).
   Its 340 px width is untouched (contract: sizes unchanged).
   `:hover` IS HELD AT REST INSIDE THE RAIL: P3-OP-127's `.page .cms-qcard:hover` border/shadow/lift is
   not hover-gated, so a finger's sticky tap, or a card the wheel slides under a still pointer, would
   outline a second card. The JS already makes the hovered card `.is-centre`, so the hover look is kept.
   SPECIFICITY / ORDER: the `.mid` reset is (0,4,0)/(0,4,1) and the `:hover:not(.is-centre)` hold (0,5,0),
   both above P3-OP-127's (0,3,0); `.is-centre` (0,4,0) comes after the reset. The lift and shadow of
   `.is-centre` carry their own reduced-motion arm below. DENOMINATOR (S14): /about is the only route
   serving `.cms-qcard` (15 nodes = 5 real + 10 aria-hidden clones); every selector is under `.cms-qmarq`. ---- */
.page .cms-qmarq .cms-qcard {
  transition: transform .2s ease, border-color .2s ease, box-shadow .2s ease, background-color .2s ease;
}
.page .cms-qmarq .cms-qcard svg { transition: color .2s ease; }
.page .cms-qmarq .cms-qcard.mid { background-color: #fff; border-color: var(--line); }
.page .cms-qmarq .cms-qcard.mid svg { color: #C9D2E4; }
.page .cms-qmarq .cms-qcard:hover:not(.is-centre) { border-color: var(--line); box-shadow: none; transform: none; }
.page .cms-qmarq .cms-qcard.is-centre {
  background-color: var(--tint-panel);
  border-color: var(--brand);
  box-shadow: var(--sh-card);
  transform: translateY(-2px);
}
.page .cms-qmarq .cms-qcard.is-centre svg { color: var(--brand); }
/* the loop's wrap hands the highlight to the same testimonial's twin at the same pixel: no fade (AboutMarquee) */
.page .cms-qmarq .cms-qcard.mq-snap,
.page .cms-qmarq .cms-qcard.mq-snap svg { transition: none; }
@media (prefers-reduced-motion: reduce) {
  .page .cms-qmarq .cms-qcard,
  .page .cms-qmarq .cms-qcard svg { transition: none; }
  .page .cms-qmarq .cms-qcard.is-centre { transform: none; }
}

/* P3-OP-134 + Guides listing closeout — the bordered upper listing cards became whole-card links
   but were omitted from the linked-card interaction family. They already own their white surface,
   line, radius and clipping, so use the neighbouring bordered-card treatment directly rather than
   painting an oversized pseudo-element outside the clipped card. Mouse and keyboard receive the
   same state. RED-FIRST for Guides: `.cms-gfeat` and `.cms-scard` produced no computed change in
   border, shadow, transform, or focus at all while `.cms-gcard` did respond. */
.page a.cms-feat,
.page a.cms-mini,
.page a.cms-big,
.page a.cms-gfeat,
.page a.cms-scard {
  transition: transform .2s ease, border-color .2s ease, box-shadow .2s ease, background-color .2s ease;
}
.page a.cms-feat:hover, .page a.cms-feat:focus-visible,
.page a.cms-mini:hover, .page a.cms-mini:focus-visible,
.page a.cms-big:hover,  .page a.cms-big:focus-visible,
.page a.cms-gfeat:hover, .page a.cms-gfeat:focus-visible,
.page a.cms-scard:hover, .page a.cms-scard:focus-visible {
  border-color: var(--brand);
  background-color: var(--card);
  box-shadow: inset 0 0 0 1px var(--brand), var(--sh-card);
  transform: translateY(-2px);
}

/* Operator smoke-test correction, 2026-09-12: the ring/lift above changed computed values but the
   Featured guides photographs remained completely static, so the interaction was not visibly
   legible. The image moves inside the card's existing overflow clip; content and geometry stay put. */
.page a.cms-gfeat .cms-cardimg,
.page a.cms-scard .cms-cardimg {
  transition: transform .28s ease;
  transform-origin: center;
}
.page a.cms-gfeat:hover .cms-cardimg, .page a.cms-gfeat:focus-visible .cms-cardimg,
.page a.cms-scard:hover .cms-cardimg, .page a.cms-scard:focus-visible .cms-cardimg {
  transform: scale(1.035);
}

@media (prefers-reduced-motion: reduce) {
  .page .mkt-fcard, .page .cms-qcard,
  .page a.cms-feat, .page a.cms-mini, .page a.cms-big, .page a.cms-gfeat, .page a.cms-scard,
  .page a.cms-gfeat .cms-cardimg, .page a.cms-scard .cms-cardimg,
  .page a.cms-topic, .page a.cms-hlrow, .page a.cms-gcard,
  .page a.cms-topic::before, .page a.cms-hlrow::before, .page a.cms-gcard::before {
    transition: none;
  }
  .page .mkt-fcard:hover, .page .cms-qcard:hover,
  .page a.mkt-fcard:focus-visible,
  .page a.cms-feat:hover, .page a.cms-feat:focus-visible,
  .page a.cms-mini:hover, .page a.cms-mini:focus-visible,
  .page a.cms-big:hover,  .page a.cms-big:focus-visible,
  .page a.cms-gfeat:hover, .page a.cms-gfeat:focus-visible,
  .page a.cms-scard:hover, .page a.cms-scard:focus-visible,
  .page a.cms-topic:hover,  .page a.cms-topic:focus-visible,
  .page a.cms-hlrow:hover,  .page a.cms-hlrow:focus-visible,
  .page a.cms-gcard:hover,  .page a.cms-gcard:focus-visible { transform: none; }
  .page a.cms-gfeat:hover .cms-cardimg, .page a.cms-gfeat:focus-visible .cms-cardimg,
  .page a.cms-scard:hover .cms-cardimg, .page a.cms-scard:focus-visible .cms-cardimg { transform: none; }
}

/* ═══ P2-01 · THE HEADER'S CURRENT PAGE, VISIBLE — ruling R-2026-09-23-P10-I, plan 2.1 ═══════════════════════════
   Verbatim: "Add a visible current-page highlight on top of the existing `aria-current` marker (the 2026-08-26
   "nothing visual" note is superseded for the header): clean, not a copy of Indeed, with a smooth left-to-right
   sliding transition, never a pop-in." Research 09 §5: a cue beyond colour (WCAG 1.4.1) plus aria-current="page".

   WHAT IT IS: a 3px bar with round ends under the current link's LABEL, in the CTA blue that already draws the
   nav's focus rings and :active colour (`--cta-fill`, #1A52C4 — marketing-locale.css:158/:172,
   marketing-interaction.css:816). No colour minted. Not Indeed's treatment: theirs is a full-width tab edge sitting
   on the header's bottom border; this sits under the words, inside the link's own 44px hit box.

   WHERE IT REACHES (S14, enumerated 2026-09-24): the only header emitter of aria-current="page" is NavPriority's
   NavLink — the row copy and the "+N"/burger panel copy — mounted by SiteChrome, HomeMarketing and
   ReferralHomeMarketing. Frame navlinks, LocaleSwitcher (aria-current="true") and the footer `a.fl` never match.

   ⛔ NO LAYOUT MOVES. The bar is a `::after`, absolutely positioned inside the link — NOT a new flex child of
   `.p-nav`, which NavPriority.measure() would charge as a fixed item plus a 34px gap and so change the fold
   depth. The link's hit box is 44px over a 19px layout box (marketing-target.css:38, 12.5px block padding each
   side); the bar lives in the lower padding, 3.5px under the line box, so no rect changes.

   ⭐ THE SLIDE. At rest before hydration the bar is scaleX(0); NavPriority sets `data-nav-current="in"` on the nav
   two animation frames after mount — i.e. after the empty state has PAINTED once — and the bar grows from its
   left end (`transform-origin: left` is physical, so it runs left-to-right in ar too; the ruling says
   left-to-right and is not re-argued). Under prefers-reduced-motion: reduce none of that applies: the bar is at
   rest from the first frame, transition none. With scripting disabled it is also shown at rest, so the cue never
   depends on JS arriving.                                                                                          */
/* ⚠ SPECIFICITY IS KEPT LOW ON PURPOSE — (0,2,2) for every row rule, via :where(). Measured 2026-09-24: written as
   `html .page .p-nav a.navlink[aria-current="page"]::after` (0,4,3) this block OUTRANKED any later author rule on the
   same bar — including the P2-01 grader's own detector controls (autorun/runs/P2-01/check/check.mjs, injected at
   (0,3,3)), which then measured THIS block's transition instead of theirs and could no longer tell a slide from a
   pop-in. Nothing else styles a navlink's ::after (census: 0 rules in the 16 served sheets), so low specificity costs
   nothing here and keeps the bar overridable by whoever comes next. */
:where(.p-nav) a.navlink[aria-current="page"] { position: relative; }
:where(.p-nav) a.navlink[aria-current="page"]::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 6px;
  height: 3px;
  border-radius: 999px;
  background-color: var(--cta-fill, #1A52C4);
  transform-origin: left center;
  pointer-events: none;
}
/* The "+N" / burger panel. Its links are `display:block` across the whole card (min-width: max-content, 18px
   inline padding — marketing-locale.css:171), so a left:0/right:0 bar would run the card's width, not the word's.
   A one-column `max-content` grid makes the column exactly the label's width; the bar is the second grid item and
   stretches to it. Its margin box nets to 0 (3px + 3px − 6px), so the link stays 44px tall. The link rule must
   outrank marketing-locale.css:171 (0,5,2) to win `display`, hence the full chain here. */
html .page .p-nav .p-nav-more-panel a.navlink.p-nav-more-link[aria-current="page"] {
  display: grid;
  grid-template-columns: max-content;
  justify-content: start;
}
:where(.p-nav-more-panel) a.navlink.p-nav-more-link[aria-current="page"]::after {
  position: static;
  grid-row: 2;
  margin-block: 3px -6px;
}
@media (prefers-reduced-motion: no-preference) {
  :where(.p-nav) a.navlink[aria-current="page"]::after {
    transform: scaleX(0);
    transition: transform .5s cubic-bezier(.22, .61, .36, 1);
  }
  :where(.p-nav[data-nav-current="in"]) a.navlink[aria-current="page"]::after { transform: scaleX(1); }
  /* Opening the panel takes its links from display:none, which never transitions — so the bar would pop in.
     @starting-style gives the opened panel's bar the same left-to-right grow. */
  @starting-style {
    :where(.p-nav[data-nav-current="in"] .p-nav-more-panel) a.navlink[aria-current="page"]::after { transform: scaleX(0); }
  }
}
@media (prefers-reduced-motion: no-preference) and (scripting: none) {
  :where(.p-nav) a.navlink[aria-current="page"]::after { transform: none; transition: none; }
}

/* NW-03 — an explicit closed state beats the legacy :hover / :focus-visible paint. This keeps
   the existing row treatment, arrow and dimensions; it only lets a second activation truly close. */
.jgrid[data-hover-pending] .acc,
.sell[data-hover-pending] .si { pointer-events: none; }
.jgrid[data-open="none"] .acc:hover,
.jgrid[data-open="none"] .acc:has(.acc-btn:focus-visible) { border-color: var(--line); box-shadow: none; }
.jgrid[data-open="none"] .acc:hover h3,
.jgrid[data-open="none"] .acc:has(.acc-btn:focus-visible) h3 { color: var(--mut); }
.jgrid[data-open="none"] .acc:hover > div:has(> h3),
.jgrid[data-open="none"] .acc:has(.acc-btn:focus-visible) > div:has(> h3) { grid-template-rows: auto 0fr; }
.jgrid[data-open="none"] .acc:hover p,
.jgrid[data-open="none"] .acc:has(.acc-btn:focus-visible) p,
.jgrid[data-open="none"]:not(:has(.acc:hover)) .acc.cat-1 p { max-height: 0; opacity: 0; margin-top: 0; }
.jgrid[data-open="none"] .acc:hover .ico,
.jgrid[data-open="none"] .acc:has(.acc-btn:focus-visible) .ico { transform: none; color: #9a9aa0; }

.sell[data-open="none"] .si:hover,
.sell[data-open="none"] .si:has(.acc-btn:focus-visible) { border-color: var(--line); box-shadow: none; }
.sell[data-open="none"] .si:hover h3,
.sell[data-open="none"] .si:has(.acc-btn:focus-visible) h3 { color: var(--mut); }
.sell[data-open="none"] .si:hover > div:has(> h3),
.sell[data-open="none"] .si:has(.acc-btn:focus-visible) > div:has(> h3) { grid-template-rows: auto 0fr; }
.sell[data-open="none"] .si:hover p,
.sell[data-open="none"] .si:has(.acc-btn:focus-visible) p { max-height: 0; opacity: 0; margin-top: 0; }
.sell[data-open="none"] .si:hover .ico,
.sell[data-open="none"] .si:has(.acc-btn:focus-visible) .ico { transform: none; color: #9a9aa0; }
.p-trans:has(.sell[data-open="none"]):not(:has(.sell .si:hover)) .tsc-1 { opacity: 1; }

/* 2026-09-30 — NW-03 still closes the journey disclosure on a second click. Keep its
   last selected scene visible while closed; `none` previously matched no scene and
   also suppressed the default stack. JourneysInput stores the independent scene key. */
.p-jour .jgrid[data-open="none"][data-scene="1"]:not(:has(.acc:hover)) .msc-1,
.p-jour .jgrid[data-open="none"][data-scene="2"]:not(:has(.acc:hover)) .msc-2,
.p-jour .jgrid[data-open="none"][data-scene="3"]:not(:has(.acc:hover)) .msc-3,
.p-jour .jgrid[data-open="none"][data-scene="4"]:not(:has(.acc:hover)) .msc-4,
.p-jour .jgrid[data-open="none"][data-scene="5"]:not(:has(.acc:hover)) .msc-5 { opacity: 1; }

/* ═══ ST-33 · CHIP-AND-WIRE SECTIONS: CARD HOVER + WIRE-BY-WIRE SCROLL REVEAL (operator walk 2026-10-01, pp.23-24) ═══
   Decision D12 built as its default (ST-1001 QUEUE.md): heading + body + chip visible; wires draw out of the chip
   one at a time (~300 ms each); each card fades in as its wire arrives; the employer chip section too; reduced
   motion shows the finished state. INTERIM DEVIATION - UNRATIFIED: no frame draws motion here; the finished state
   IS the approved frame (Affiliate/Home/Become an Affiliate, Employer/Become an Employer, frames-to-routes HIGH).

   S14 DENOMINATOR (grep, source): 3 chip renderers — AffiliateHome `Earnings` (/affiliates + twins), EmployerNode
   (/employers + 5 twins), ArticleView `NodeBand` (CMS `node` bodies). 2 of 3 carry the reveal; NodeBand is NOT
   touched (its CMS output must not change, and its routes depend on the DB seed) — carried in ST-33/SHIP.md.

   STATES: `data-wire-reveal` is stamped on the <section> by ChipWireReveal.tsx, and ONLY when motion is allowed
   and the wires are displayed. No attribute = today's finished section (server HTML, no JS, reduced motion, data
   saver, phones/tablets where the wires are hidden).
     (ST-33 armed/play below were REPLACED on 2026-10-02 by ST-57 `scrub` — see the ST-57 note under the keyframes.)
     armed : wires, end dots and cards at opacity 0 — heading, body and chip stay.
     play  : each piece runs a `backwards`-filled animation (never `forwards`), so once it ends NOTHING here applies
             and every wire, dot and card is painted by its own sheets exactly as before. Cards animate OPACITY only,
             so the hover transform below is never overridden by a fill.
   Timing: slot 450 ms per wire = 300 ms draw (out of the chip: dash offset -1 -> 0 on pathLength 1, which grows
   from the path's END, the chip end) + the card's 250 ms fade starting on arrival; the next wire starts 150 ms
   into that fade. 4 affiliate wires = 1.75 s, 8 employer wires = 3.55 s.
   CAN IT WIN: no inline style={} on any of these elements (grep -n 'style={{' AffiliateHome.tsx EmployerNode.tsx = 0).
   Employer wire opacity is set at (0,5,1) by marketing-cms.css, so the armed rule carries the page root (0,7,1). */
@keyframes cwr-draw { from { stroke-dasharray: 1 1; stroke-dashoffset: -1; } to { stroke-dasharray: 1 1; stroke-dashoffset: 0; } }
@keyframes cwr-in { from { opacity: 0; } to { opacity: 1; } }

/* ═══ ST-57 · SCRUBBED, NOT TIMED (operator 2026-10-02: "the chip animation needs to be a scroll animation meaning it
   progresses as I scroll"). The `armed`/`play` pair above is gone. ChipWireReveal.tsx stamps `scrub` and writes
   `--cwr-p` (0..1, the reader's position through the diagram, one rect per animation frame) on the section. Every
   animation below is the SAME ST-33 keyframe, created `paused`, with `- var(--cwr-t)` added to its delay, where
   --cwr-t = p x the timeline's total. A paused animation never advances, so its delay alone decides what it shows:
     p = 0      every delay >= 0: the `backwards` fill holds the `from` keyframe (wire hidden/undrawn, card at 0) —
                heading, body and chip only (the old `armed` look, now produced by the fill, no extra rule);
     0 < p < 1  slot k (450 ms each, an equal slice of p) sweeps wire k out of the chip, then fades its card;
     p = 1      total (1950 / 3750 ms) is past the last end (1900 / 3700 ms): every animation is in its AFTER phase
                and, with backwards fill only, applies NOTHING — the static finished layout, as before.
   Scrolling up lowers p and the same arithmetic un-draws it (scrub both directions). Card hover untouched (cards
   animate opacity only). Reduced motion / data saver / no JS / wires hidden: no attribute = finished. ═══ */
.page.aff-home .aff-earn[data-wire-reveal="scrub"] { --cwr-t: calc(var(--cwr-p, 0) * 1950ms); }
.page.emp-home .emp-node[data-wire-reveal="scrub"] { --cwr-t: calc(var(--cwr-p, 0) * 3750ms); }

/* ---- the wire index --cwr-k (reading order: top-left, top-right, then down) ---- */
.page.aff-home .aff-earn[data-wire-reveal="scrub"] .left.top { --cwr-k: 0; }
.page.aff-home .aff-earn[data-wire-reveal="scrub"] .right.top { --cwr-k: 1; }
.page.aff-home .aff-earn[data-wire-reveal="scrub"] .left.bottom { --cwr-k: 2; }
.page.aff-home .aff-earn[data-wire-reveal="scrub"] .right.bottom { --cwr-k: 3; }
/* Affiliate wire = three segments; the third meets the hub, so it draws first, then the riser, then the run to the box. */
.page.aff-home .aff-earn[data-wire-reveal="scrub"] .aff-wire line { animation: cwr-draw 100ms linear backwards paused; }
.page.aff-home .aff-earn[data-wire-reveal="scrub"] .aff-wire line:nth-of-type(3) { animation-delay: calc(var(--cwr-k) * 450ms - var(--cwr-t)); }
.page.aff-home .aff-earn[data-wire-reveal="scrub"] .aff-wire line:nth-of-type(2) { animation-delay: calc(var(--cwr-k) * 450ms - var(--cwr-t) + 100ms); }
.page.aff-home .aff-earn[data-wire-reveal="scrub"] .aff-wire line:nth-of-type(1) { animation-delay: calc(var(--cwr-k) * 450ms - var(--cwr-t) + 200ms); }
.page.aff-home .aff-earn[data-wire-reveal="scrub"] .aff-wire circle:nth-of-type(2) { animation: cwr-in 100ms ease-out backwards paused; animation-delay: calc(var(--cwr-k) * 450ms - var(--cwr-t)); }
.page.aff-home .aff-earn[data-wire-reveal="scrub"] .aff-wire circle:nth-of-type(1) { animation: cwr-in 120ms ease-out backwards paused; animation-delay: calc(var(--cwr-k) * 450ms - var(--cwr-t) + 300ms); }
.page.aff-home .aff-earn[data-wire-reveal="scrub"] .aff-earn-box { animation: cwr-in 250ms ease-out backwards paused; animation-delay: calc(var(--cwr-k) * 450ms - var(--cwr-t) + 300ms); }

/* Employer: NODE_WIRES paths 1-4 are the left wires top-down, 5-8 the right; paths 9-24 are the end dots in pairs
   (card end, chip end) in the same order. Order: L1 R1 L2 R2 L3 R3 L4 R4. */
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-wires path:nth-child(1),
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-wires path:nth-child(9),
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-wires path:nth-child(10),
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-col.left .mkt-node-card:nth-child(1) { --cwr-k: 0; }
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-wires path:nth-child(5),
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-wires path:nth-child(17),
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-wires path:nth-child(18),
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-col.right .mkt-node-card:nth-child(1) { --cwr-k: 1; }
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-wires path:nth-child(2),
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-wires path:nth-child(11),
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-wires path:nth-child(12),
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-col.left .mkt-node-card:nth-child(2) { --cwr-k: 2; }
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-wires path:nth-child(6),
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-wires path:nth-child(19),
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-wires path:nth-child(20),
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-col.right .mkt-node-card:nth-child(2) { --cwr-k: 3; }
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-wires path:nth-child(3),
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-wires path:nth-child(13),
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-wires path:nth-child(14),
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-col.left .mkt-node-card:nth-child(3) { --cwr-k: 4; }
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-wires path:nth-child(7),
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-wires path:nth-child(21),
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-wires path:nth-child(22),
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-col.right .mkt-node-card:nth-child(3) { --cwr-k: 5; }
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-wires path:nth-child(4),
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-wires path:nth-child(15),
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-wires path:nth-child(16),
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-col.left .mkt-node-card:nth-child(4) { --cwr-k: 6; }
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-wires path:nth-child(8),
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-wires path:nth-child(23),
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-wires path:nth-child(24),
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-col.right .mkt-node-card:nth-child(4) { --cwr-k: 7; }
/* ST-33 REWORK (VERDICT FAIL 2026-10-01). MEASURED (ST-33/review/wires.json, emp-1440-reveal-t300ms-200.png): the
   dash draw above (cwr-draw) painted every NOT-YET-STARTED employer wire as ~20 dotted fragments — these paths carry
   `vector-effect: non-scaling-stroke` (marketing.css:459, pinned), under which Chrome measures the pathLength-1 dash
   `1 1` in SCREEN px, so the "gap" never covers the wire. /affiliates (plain <line>s, no vector-effect) measured
   clean and keeps cwr-draw. NO FRAME (motion); INTERIM DEVIATION · UNRATIFIED; row ST-33.
   Employer wires therefore do not dash at all:
     - waiting for its turn: the backwards-filled `from` keyframe holds `visibility: hidden` — the wire paints
       nothing, whatever the stroke/dash machinery does (start state = heading + body + chip, as asked);
     - its turn: a clip-path inset sweeps open from the CHIP edge toward the card (left wires 1-4 have the chip on
       their right, right wires 5-8 on their left). The -4px insets on the other three sides keep the half-stroke
       of a run that lies on its own bounding-box edge from being shaved during the sweep;
     - after: backwards fill only, so no clip and no visibility rule remains — the finished state is unchanged.
   If a browser rejects clip-path on an SVG path, the wire simply appears whole at its turn (still no fragments). */
@keyframes cwr-grow-l { from { visibility: hidden; clip-path: inset(-4px -4px -4px 100%); } to { visibility: visible; clip-path: inset(-4px -4px -4px 0%); } }
@keyframes cwr-grow-r { from { visibility: hidden; clip-path: inset(-4px 100% -4px -4px); } to { visibility: visible; clip-path: inset(-4px 0% -4px -4px); } }
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-wires path:nth-child(-n+4) { animation: cwr-grow-l 300ms ease-out backwards paused; animation-delay: calc(var(--cwr-k) * 450ms - var(--cwr-t)); }
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-wires path:nth-child(n+5):not(.wdot) { animation: cwr-grow-r 300ms ease-out backwards paused; animation-delay: calc(var(--cwr-k) * 450ms - var(--cwr-t)); }
/* the chip-end dot (even child) lights as the wire leaves the chip; the card-end dot (odd) as it arrives */
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-wires path.wdot:nth-child(even) { animation: cwr-in 100ms ease-out backwards paused; animation-delay: calc(var(--cwr-k) * 450ms - var(--cwr-t)); }
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-wires path.wdot:nth-child(odd) { animation: cwr-in 120ms ease-out backwards paused; animation-delay: calc(var(--cwr-k) * 450ms - var(--cwr-t) + 300ms); }
.page.emp-home .emp-node[data-wire-reveal="scrub"] .mkt-node-card { animation: cwr-in 250ms ease-out backwards paused; animation-delay: calc(var(--cwr-k) * 450ms - var(--cwr-t) + 300ms); }

/* ---- the hover: the affiliate earnings boxes had none (BEFORE.json: 0 rules). The values are the neighbour's,
   never minted: the same page's feature cards `.page .mkt-fcard:hover` (brand edge, --sh-card, 2 px lift, .2s).
   Hover-capable pointers only (a tap leaves :hover stuck — the emp-home note in marketing-employer.css). The
   employer node cards already carry the brand edge + --sh-card hover (marketing-employer.css) and are left as they
   are: their wire-end dot is part of the card, so a lift there would pull the dot off its wire. ---- */
.page.aff-home .aff-earn .aff-earn-box { transition: border-color .2s ease, box-shadow .2s ease, transform .2s ease; }
@media (hover: hover) {
  .page.aff-home .aff-earn .aff-earn-box:hover { border-color: var(--brand); box-shadow: var(--sh-card); transform: translateY(-2px); }
}
@media (prefers-reduced-motion: reduce) {
  .page.aff-home .aff-earn .aff-earn-box { transition: none; }
  .page.aff-home .aff-earn .aff-earn-box:hover { transform: none; }
  /* The reveal itself needs no rule here: ChipWireReveal never stamps `data-wire-reveal` under reduced motion. */
}
