/* ============================================================================
   SCENE 2 — THE MAP (absorption flow) + THE SHARED MAP VOCABULARY (.shm-*)
   ----------------------------------------------------------------------------
   The concentric shield is retired. The video's scope map is the E3
   "absorption flow": four horizontal swimlanes, a client entry far left, a
   hatched stream running left -> right that SPLITS at every lane — a branch
   peels off, tapers, and plugs into that lane's work — a dashed measurement
   floor, and a dark TARGET STATE plate. Direction A (2026 editorial ink):
   neon #03F9EC only as highlight bars / underlines / the circle-arrow motif,
   ink #020204 as the working black and the one dark block.

   THREE CONSUMERS share this file:
     .sh   — the 1600x900 fit box + status cascade + scene chrome, used by
             scene 2 (js/shield.js) and scene 8 (js/scene-deps.js).
     .sh2- — scene 2's own fixed layout (header, captions, target plate).
     .shm- — the map vocabulary itself: stream, branches, forks, cards,
             plugs, floor. Deliberately UNSCOPED so ring-scene.js (the journey
             strip in scenes 3-7), scene-deps.js (the compact band) and the
             promise scene can all speak it. Colour resolves through var(--sc),
             provided by whichever scene root carries the data-status cascade.

   Hard constraints (BUILD-SPEC §2, §5 + binding rules):
     - No @keyframes, no transitions on animated elements. CSS declares
       resting states and the primitives GSAP writes into; every frame is a
       pure function of the timeline position.
     - Dashed strokes are revealed through an SVG <mask> (pathLength 1000),
       never by touching the visible element's dasharray.
     - Status colour paints swatches, strokes and fills. Never text colour.
     - Nothing reads as delivered: no solid closed "done" shapes; the branch
       plugs are open-ended rails, the stream edges stay dashed.
     - Nothing load-bearing below 14px at the 1600x900 authoring size.
   ========================================================================= */

/* ---- the 1600x900 authoring canvas --------------------------------------
   Pure-CSS fit on purpose: resize listeners and ResizeObservers are both
   unreliable under a CDP-driven viewport change — the layout updates but no
   notification is delivered. The engine re-resolves this on every layout, so
   there is no event for a capture rig to miss and no JS in the path at all.
   Clamped at 1 so text is never transform-upscaled. */
.sh {
  position: absolute;
  left: 50%; top: 50%;
  width: 1600px; height: 900px;
  margin: 0;
  --sh-k: min(1, calc(100vw / 1600px), calc(100vh / 900px));
  transform: translate(-50%, -50%) scale(var(--sh-k));
  transform-origin: 50% 50%;
  font-family: var(--font-body);
  color: var(--fg-primary);
  pointer-events: none;
}

/* ---- status -> --sc cascade ---------------------------------------------
   The single hop from a data attribute to one custom property. Everything
   downstream reads var(--sc) for strokes, fills and swatches; no rule
   downstream may set `color` from it, which makes the "status colour as text
   colour" contrast failure structurally impossible rather than a review item. */
.sh [data-status="progress"] { --sc: var(--status-progress); }
.sh [data-status="testing"]  { --sc: var(--status-testing);  }
.sh [data-status="blocked"]  { --sc: var(--status-blocked);  }
.sh [data-status="paused"]   { --sc: var(--status-paused);   }
.sh [data-status="pipeline"] { --sc: var(--status-pipeline); }

/* ---- shared micro type role (scene 2 + scene 8 chrome) ------------------- */
.sh-cap {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--text-sm);
  line-height: var(--lh-sm);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--fg-muted);
  white-space: nowrap;
}
.sh-cap--ink { color: var(--fg-secondary); }
.sh-hair { flex: 1; height: 1px; background: var(--border-subtle); }

/* ---- scene 8 keeps its two-column chrome ---------------------------------
   Thesis band, columns, caplines, stamp and readout — reused verbatim by
   scene-deps.js. Scene 2 no longer uses these (its header is the 2026 kit's). */
.sh__thesis { position: absolute; left: 72px; top: 92px; width: 800px; }
.sh__thesis h2 {
  margin: var(--space-2) 0 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-display-xs);
  line-height: var(--lh-display-xs);
  letter-spacing: -.01em;
  color: var(--fg-primary);
  clip-path: inset(0% 0% 0% 0%);
}
.sh__rule {
  position: absolute; left: 72px; top: 166px; width: 1420px; height: 1px;
  background: var(--border-default);
  transform-origin: 0% 50%;
}
.sh__diagram { position: absolute; left: 72px;  top: 182px; width: 700px; height: 634px; }
.sh__manifest{ position: absolute; left: 828px; top: 182px; width: 664px; height: 634px; }
.sh__capline { display: flex; align-items: center; gap: var(--space-4); height: 20px; }
.sh__capline .sh-dot {
  width: 5px; height: 5px; flex: none;
  border-radius: var(--radius-full);
  background: var(--border-strong);
}
.sh__stamp {
  position: absolute; left: 72px; top: 824px; width: 340px;
  padding-top: var(--space-3);
  border-top: 1px solid var(--fg-primary);
}
.sh__stamp b {
  display: block;
  font-family: var(--font-display); font-weight: 700;
  font-size: var(--text-display-xs); line-height: var(--lh-display-xs);
  letter-spacing: .22em;
  color: var(--fg-primary);
}
.sh__stamp span {
  display: block;
  font-family: var(--font-body); font-weight: 400;
  font-size: var(--text-md); line-height: var(--lh-md);
  color: var(--fg-tertiary);
}
.sh__scope { position: absolute; right: 108px; top: 92px; width: 440px; text-align: right; }
.sh__scope p {
  margin: var(--space-2) 0 0;
  font-family: var(--font-body); font-weight: 400;
  font-size: var(--text-lg); line-height: var(--lh-lg);
  color: var(--fg-secondary);
}

/* The mask-reveal primitive's stroke. GSAP writes an inline stroke-dashoffset,
   which beats this class. THE 1000 IS LOAD-BEARING: with pathLength="1" GSAP's
   CSSPlugin truncates px to whole integers and the whole reveal has exactly
   two states — every stroke POPS instead of wiping. Keep in step with the
   pathLength attributes in shield.js / scene-deps.js. */
.sh-draw { stroke-dasharray: 1000; stroke-dashoffset: 1000; }

/* ==========================================================================
   THE MAP VOCABULARY — .shm-*, unscoped, spoken by scenes 2, 3-7 and 8.
   Scene 8 (dependencies) is the LAST scene that draws the map: C5.5 retired
   the ladder for the closing, and scenes 9 and 10 are now pure type.
   ======================================================================== */

/* A full-bleed SVG wire layer inside a 1600x900 (or scene-sized) box. */
.shm-wire {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  pointer-events: none;
  overflow: visible;
  shape-rendering: geometricPrecision;
}

/* The through-stream: a quiet primary-hue tint with a sparse hatch — volume,
   not texture. Dashed edges: NOT dealt with yet. */
.shm-hatch-bg   { fill: var(--primary-hue-50); }
.shm-hatch-line { stroke: var(--primary-hue-300); stroke-width: 1; }
.shm-ribbon-edge{ fill: none; stroke: var(--neutral-500); stroke-width: 1.3;
                  stroke-dasharray: 5 6; stroke-linecap: butt; }
.shm-journey    { fill: none; stroke: var(--secondary-ink); stroke-width: 2.2;
                  stroke-dasharray: 12 7; stroke-linecap: butt; }

/* The absorbed branch: a smooth taper in the same tint, no hatch — it has
   been dealt with — plugging into this lane's work. Solid edges, but never a
   closed "done" shape. */
.shm-branch      { fill: var(--primary-hue-50); stroke: none; }
.shm-branch-edge { fill: none; stroke: var(--neutral-500); stroke-width: 1.1;
                   stroke-linecap: butt; }

/* The split point: a small open ring ON the stream's top edge, exactly where
   the branch leaves. Open — a port, not a completed thing. */
.shm-node { fill: var(--bg-primary); stroke: var(--neutral-800); stroke-width: 2; }

/* Dashed stubs (junction fan-outs, floor taps) and measurement geometry. */
.shm-tap       { fill: none; stroke: var(--neutral-600); stroke-width: 1.4; stroke-dasharray: 3 5; }
.shm-floorrule { fill: none; stroke: var(--neutral-600); stroke-width: 2.2;
                 stroke-dasharray: 9 7; stroke-linecap: butt; }
.shm-drop      { fill: none; stroke: var(--border-default); stroke-width: 1.2; stroke-dasharray: 2 6; }

/* The branch terminal: a status rail — solid edge plus 14% tint. "Absorbed by
   this work", legible from shape alone. Status colour on fills only. */
.shm-plug-edge { fill: var(--sc, var(--neutral-600)); }
.shm-plug-tint { fill: color-mix(in srgb, var(--sc, var(--neutral-600)) 14%, transparent); }

/* ---- lane label block ----------------------------------------------------- */
.shm-lane { position: absolute; }
.shm-lane__hd { display: flex; align-items: center; gap: 9px; }
.shm-lane__no {
  width: 26px; height: 26px; flex: 0 0 auto; border-radius: 8px;
  border: 1px dashed var(--border-strong);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-display); font-weight: 700;
  font-size: 15px; line-height: 15px;
  color: var(--fg-secondary);
}
.shm-lane__ic { width: 18px; height: 18px; flex: 0 0 auto; color: var(--fg-muted); }
.shm-lane__ic path { fill: none; stroke: currentColor; }
.shm-lane__name {
  font-family: var(--font-display); font-weight: 600;
  font-size: 18px; line-height: 22px; letter-spacing: -.025em;
  color: var(--fg-primary); white-space: nowrap;
}
.shm-lane__promise {
  margin-top: 4px;
  font-size: var(--text-sm); line-height: var(--lh-sm);
  color: var(--fg-tertiary); white-space: nowrap;
}

/* ---- project card seated in a lane ----------------------------------------
   Kit rule: border OR shadow, never both. Border it is. The left rail is the
   branch's terminal: a status-tinted rail with a solid status edge. */
.shm-card {
  position: absolute; height: 54px;
  background: var(--bg-primary);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  overflow: hidden;
  display: flex; align-items: center; gap: 10px;
  padding: 0 12px 0 20px;
  clip-path: inset(0% 0% 0% 0%);
}
.shm-card__stripe {
  position: absolute; left: 0; top: 0; bottom: 0; width: 7px;
  background: linear-gradient(90deg,
    var(--sc) 0 2.5px,
    color-mix(in srgb, var(--sc) 14%, transparent) 2.5px);
}
.shm-card__ic { width: 20px; height: 20px; flex: 0 0 auto; color: var(--sc); }
.shm-card__ic path { fill: none; stroke: currentColor; }
.shm-card__txt { min-width: 0; display: block; }
.shm-card__name {
  display: block;
  font-family: var(--font-display); font-weight: 600;
  font-size: 16px; line-height: 20px; letter-spacing: -.02em;
  color: var(--fg-primary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.shm-card__meta {
  display: flex; align-items: center; gap: 7px;
  font-size: var(--text-sm); line-height: var(--lh-sm);
  color: var(--fg-tertiary); white-space: nowrap;
}
.shm-card__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--sc); flex: 0 0 auto; }

/* Compact variant for the scene-8 band. Name only — the ledger column carries
   the words; the map carries the shape. 14px, on the §5 floor. */
.shm-card--sm { height: 38px; padding: 0 10px 0 17px; gap: 8px; }
.shm-card--sm .shm-card__stripe { width: 6px; }
.shm-card--sm .shm-card__ic { width: 16px; height: 16px; }
.shm-card--sm .shm-card__name { font-size: var(--text-sm); line-height: var(--lh-sm); }

/* ---- paused sub-node: geometry ghosted, label at full contrast ------------ */
.shm-sub { position: absolute; width: 206px; height: 40px; }
.shm-sub__geo {
  position: absolute; inset: 0; border-radius: 12px;
  border: 1px dashed var(--sc);
  background: var(--bg-primary);
  opacity: .4;
}
.shm-sub__row { position: absolute; inset: 0; display: flex; align-items: center; gap: 9px; padding: 0 12px; }
.shm-sub__ic { width: 17px; height: 17px; flex: 0 0 auto; color: var(--sc); opacity: .4; }
.shm-sub__ic path { fill: none; stroke: currentColor; }
.shm-sub__name { font-family: var(--font-display); font-weight: 600; font-size: var(--text-sm); line-height: var(--lh-sm); color: var(--fg-primary); }
.shm-sub__sep { width: 1px; height: 14px; background: var(--border-default); opacity: .4; }
.shm-sub__status { font-size: var(--text-sm); line-height: var(--lh-sm); color: var(--fg-tertiary); }
.shm-sub__cap { position: absolute; left: 0; top: 44px; font-size: var(--text-sm); line-height: var(--lh-sm); color: var(--fg-muted); white-space: nowrap; }

/* ---- the terminal (the human) --------------------------------------------- */
.shm-terminal {
  position: absolute;
  border: 2px dashed var(--border-strong); border-radius: var(--radius-xl);
  background: var(--bg-primary);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
}
.shm-terminal__disc {
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--secondary-ink); color: var(--fg-inverse);
  display: flex; align-items: center; justify-content: center;
}
.shm-terminal__disc svg { width: 22px; height: 22px; }
.shm-terminal__disc path { fill: none; stroke: currentColor; stroke-width: 1.7;
                           stroke-linecap: round; stroke-linejoin: round; }
.shm-terminal__lbl {
  font-family: var(--font-display); font-weight: 600;
  font-size: 16px; line-height: 19px; color: var(--fg-primary); text-align: center;
}
.shm-terminal--sm { gap: 4px; }
.shm-terminal--sm .shm-terminal__disc { width: 28px; height: 28px; }
.shm-terminal--sm .shm-terminal__disc svg { width: 16px; height: 16px; }
.shm-terminal--sm .shm-terminal__lbl { font-size: var(--text-sm); line-height: var(--lh-sm); }

/* ---- honest, unmeasured captions ------------------------------------------ */
.shm-caught {
  position: absolute; white-space: nowrap;
  font-size: var(--text-sm); line-height: var(--lh-sm); color: var(--fg-muted);
  background: var(--bg-primary); padding: 0 4px;
}
/* C3.3: the one line that matters is underscored in ink, not neon. 2px
   --fg-primary — the same weight the eyebrow rule carries, so the two ink
   rules on the page read as one system. */
.shm-uneon { border-bottom: 2px solid var(--fg-primary); padding-bottom: 3px; }

/* A small journey-position mark (the strip's "you are here"): lane numeral or
   FL, knocked out of whatever runs beneath it. */
.shm-mark {
  position: absolute;
  transform: translate(-50%, 0);
  padding: 0 6px;
  background: var(--bg-primary);
  font-family: var(--font-display); font-weight: 700;
  font-size: 15px; line-height: 18px;
  color: var(--fg-primary);
  white-space: nowrap;
  clip-path: inset(0% 0% 0% 0%);
}

/* C3.7: pills rejected. The key is a whisper — every card already says its
   status in words, so this exists only to name the five colours. Square
   swatch + word, no ground, no border, no radius, no badge chrome. The
   swatch is square precisely so it cannot be mistaken for a card's round
   status dot: one is a key, the other is data. */
.shm-lgitem {
  display: flex; align-items: center; gap: 7px;
  font-size: var(--text-sm); line-height: var(--lh-sm); font-weight: 400;
  color: var(--fg-tertiary); white-space: nowrap;
}
.shm-lgdot { width: 8px; height: 8px; background: var(--sc); flex: 0 0 auto; }

/* ==========================================================================
   SCENE 2's OWN LAYOUT — .sh2-*
   ======================================================================== */

/* C3.3: the neon bar is gone. Ink small-caps sitting on a hairline — the
   editorial section mark, not a highlighter. Shrink-to-fit width so the rule
   is exactly as long as the words. Sits right of the shell's corner
   logomark. */
.sh2-eyebrow {
  position: absolute; left: 72px; top: 22px;
  display: inline-block;
  padding: 0 0 6px;
  border-bottom: 1px solid var(--fg-primary);
  font-size: var(--text-sm); line-height: 16px; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--fg-primary);
  clip-path: inset(0% 0% 0% 0%);
}
/* Kit big-title rules: lh 0.95, letter-spacing -0.040em, ink. */
.sh2-title {
  position: absolute; left: 72px; top: 52px;
  font-family: var(--font-display); font-weight: 700;
  font-size: 36px; line-height: 34px; letter-spacing: -.040em;
  color: var(--secondary-ink); white-space: nowrap;
  clip-path: inset(0% 0% 0% 0%);
}
.sh2-cap {
  position: absolute; left: 72px; top: 94px;
  font-size: var(--text-sm); line-height: var(--lh-sm); color: var(--fg-tertiary);
  display: flex; align-items: center; gap: 10px;
  clip-path: inset(0% 0% 0% 0%);
}
.sh2-cap .sh2-arrowline { display: block; width: 90px; height: 1px; background:
  repeating-linear-gradient(90deg, var(--border-strong) 0 6px, transparent 6px 12px); }
/* C3.3: a plain arrowhead in --fg-muted, flush against the dashed lead. */
.sh2-cap .sh2-arrowhead {
  display: block; width: 9px; height: 10px; flex: 0 0 auto;
  margin-left: -9px; overflow: visible;
}
.sh2-cap .sh2-arrowhead path { fill: var(--fg-muted); }

/* C3.7 deleted the "All seven projects" chip; the key now owns this corner.
   A right-aligned inline key under one hairline — quieter than the cards by
   construction: no ground, no border, no radius, nothing to read as chrome.
   Right edge is 56px, so it lands on the same axis as .sh2-hdrule's end. */
.sh2-legend {
  position: absolute; right: 56px; top: 48px;
  display: flex; gap: 20px; align-items: center;
  padding-top: 10px;
  border-top: 1px solid var(--border-default);
}
.sh2-hdrule {
  position: absolute; left: 72px; top: 120px; width: 1472px; height: 1px;
  background: var(--border-subtle); transform-origin: 0 50%;
}

/* Lane separators: hairlines; the stream carries the structure. */
.sh2-lanesep {
  position: absolute; left: 56px; width: 1488px; height: 1px;
  background: var(--border-subtle); transform-origin: 0 50%;
}

/* Entry (the client) label. */
.sh2-entryname {
  position: absolute; left: 300px; top: 170px; width: 100px; text-align: center;
  font-family: var(--font-display); font-weight: 600;
  font-size: 16px; line-height: 20px;
  color: var(--fg-primary);
  clip-path: inset(0% 0% 0% 0%);
}

/* Honesty captions. */
.sh2-flowcap {
  position: absolute; left: 344px; top: 424px;
  font-size: var(--text-sm); line-height: var(--lh-sm); color: var(--fg-muted);
  display: flex; align-items: center; gap: 9px;
}
.sh2-flowcap .sh2-lead { display: block; width: 40px; height: 1px; background:
  repeating-linear-gradient(90deg, var(--border-strong) 0 4px, transparent 4px 9px); }
.sh2-tailcap {
  position: absolute; left: 1150px; top: 664px; width: 230px; text-align: right;
  font-size: 15px; line-height: 19px; font-weight: 600; color: var(--secondary-ink);
}

/* ---- the marker column: 1 · 2 · 3 · 4 · ALL -------------------------------
   C3.7. The dashed spine is painted first and the numeral chips carry an
   opaque ground, so each stage knocks a hole in it — the line visibly passes
   THROUGH all four and terminates on ALL. Scoped to .sh2-lane so the shared
   .shm-lane__no keeps its transparent default for every other consumer. */
.sh2-spine {
  position: absolute; width: 0;
  border-left: 1px dashed var(--border-strong);
  transform-origin: 50% 0;
}
.sh2-lane .shm-lane__no { background: var(--bg-primary); }

/* ALL is a word, not a digit, so its pill is wider than the 26px numerals.
   36 and -5px on each side is the one geometry where BOTH stay true: the
   pill is centred on the numerals' own 69px spine axis (51..87), and the
   flow position of the icon after it lands on 91px — exactly where every
   lane's icon sits. Widen the pill and the `insights` glyph collides with
   its right border; that was measured, not guessed. */
.sh2-allmark {
  width: 36px; height: 26px; flex: 0 0 auto;
  margin: 0 -5px; border-radius: 8px;
  border: 1px dashed var(--border-strong);
  background: var(--bg-primary);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-display); font-weight: 700;
  font-size: 15px; line-height: 15px; letter-spacing: .01em;
  color: var(--fg-secondary);
}
.sh2-allcap {
  margin-top: 7px;
  font-size: var(--text-sm); line-height: var(--lh-sm); font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--fg-muted); white-space: nowrap;
}

/* Floor label block slot. Keep `top` in step with FLOOR_LBL_TOP in shield.js
   — the spine is sized to land exactly on the ALL pill's top edge. */
.sh2-floorlbl { position: absolute; left: 56px; top: 676px; width: 280px; }

/* The one deliberate dark moment. Kit dark-block recipe: ink #020204 ground,
   #101828 border — both referenced through their tokens. */
.sh2-target {
  position: absolute; left: 56px; top: 790px; width: 1488px; height: 76px;
  background: var(--secondary-ink);
  border: 1px solid var(--neutral-900);
  border-radius: var(--radius-xl);
  display: flex; align-items: center; padding: 0 28px; gap: 22px;
}
.sh2-target__word {
  font-family: var(--font-display); font-weight: 700;
  font-size: 28px; line-height: 32px; letter-spacing: -.02em;
  color: var(--fg-inverse);
  clip-path: inset(0% 0% 0% 0%);
}
.sh2-target__bar { width: 1px; height: 34px; background: var(--neutral-700); }
.sh2-target__note { font-size: 16px; line-height: 22px; color: var(--neutral-400);
                    clip-path: inset(0% 0% 0% 0%); }
