/* ============================================================================
   FOW TRAVEL — F2R · S1-CR THE LIVING TRAVERSE · surface
   THE ATLAS BECOMES OPERATIONAL

   One spatial argument, four surfaces, one causal system:

     LEFT    the accepted Tokyo MAP BOOK — physical source (canvas)
     CENTER  the Tokyo city terrain — primary active field (canvas, GSI relief)
     OVER    the living cartographic HUD (svg + marginalia, .f2r-field)
     BOTTOM  the aged archival FOLIO — operational index (.f2folio)
     RIGHT   S2 · the SMOKED CARTOGRAPHIC OPERATION PLATE (.fnl)

   State lives on <body>: data-hub="hub"|"detail", data-fn="<domain>".
   The folio DOM remains the essential navigation surface; terrain and HUD
   are enhancement. Nothing just appears: every surface resolves, registers,
   plots or settles in an authored order.
   ============================================================================ */

/* ------------------------------------------------------------- §0 FOLIO STOCK
   Aged atlas paper / vellum-stock hybrid: Fedrigoni restraint + Awagami fibre
   + archival patina. Luxury conservation material — not parchment, not SaaS. */
.f2folio, .fnl, .f2r-field {
  /* ONE PAPER: these are aliases now, not a second palette. The material is
     published as --fow-paper-* in FOW_TRAVEL_TYPOGRAPHY_TOKENS_v0_1.css, from
     these exact values, so the FOLIO here and the Published Page
     (fow_pub.css) stand on one stock. The literals stay as var() fallbacks:
     if the token sheet ever fails to load, this surface is byte-identical to
     what it was before the Published Page alignment. */
  --fo:      var(--fow-paper-face,   #EDE7D6);   /* face  */
  --fo-2:    var(--fow-paper-face-2, #E5DCC6);
  --fo-3:    var(--fow-paper-face-3, #D9CEB4);
  --fo-sunk: var(--fow-paper-sunk,   #CEC2A6);
  --fo-cloud:var(--fow-paper-cloud,  #F7F3E7);   /* clouding highlight */
  --fo-edge:   var(--fow-paper-edge,       #C2B694);
  --fo-edge-d: var(--fow-paper-edge-dark,  #96896A);
  --fo-edge-l: var(--fow-paper-edge-light, #F6F1E2);
  --fo-ink:   var(--fow-paper-ink,       #191818);
  --fo-ink-2: var(--fow-paper-ink-soft,  #46464A);
  --fo-ink-3: var(--fow-paper-ink-faint, #6B6A66);
  --fo-ink-4: var(--fow-paper-ink-quiet, #8B8672);
  /* -ink-4 stays the quiet/atmospheric tone (underline plots, secondary
     labels not measured as failing). Where it colours MEASURED semantic
     status text (ev--none/ev--illus — F4, WCAG AA audit) it read 2.4-2.6:1
     against the paper stock. This is the same brass hue proportionally
     darkened in linear light until the worst-case measured stock luminance
     clears 4.5:1, not a different colour choice. */
  --fo-ink-4-semantic: var(--fow-paper-ink-quiet-semantic, #585547);
  --fo-hair:   var(--fow-rule-on-paper,      #C6BCA2);
  --fo-hair-2: var(--fow-rule-on-paper-soft, #D6CDB7);
  --plot: var(--fow-paper-brass, #8A7442);   /* cartographic brass */
  /* -plot stays the decorative brass (icon strokes, fill bars). Where it
     colours MEASURED semantic text (op__i D1-D4, ev--pub, ev--sample — F4)
     it read 3.1-3.5:1 against the paper stock. Same treatment as -ink-4
     above: proportionally darkened until worst-case stock clears 4.5:1. */
  --plot-semantic: var(--fow-paper-brass-semantic, #685730);
  --hot:  var(--fow-paper-hot, #B23A1E);
  /* the smoked plate's own ink set */
  --pl:      #17191E;
  --pl-2:    #1D2026;
  --pl-3:    #23262d;
  --pl-ink:   #E2DFD4;
  --pl-ink-2: #B0AEA4;
  --pl-ink-3: #83837E;
  --pl-hair:  rgba(214, 208, 190, .14);
  --pl-hair-2:rgba(214, 208, 190, .08);
  --pl-plot:  #AD9257;
  /* H·L: the carved interlock notch is retired — the Folio is one complete
     independent sheet (the 3-D released leaf). These now only reserve the
     band's stand-off where the volume stands in front of the sheet. */
  --notch-x: 30px;
  --notch-w: 300px;
  --notch-d: 50px;
}

/* ================================================================ §1 THE FIELD
   Terrain + HUD layer. Sits over the canvas, under the paper surfaces.
   Constructed, never faded-in as one: datum → registration line → nodes →
   traces → measures → labels → operation state. */
.f2r-field {
  position: absolute; inset: 0; z-index: 8; pointer-events: none;
  opacity: 0; visibility: hidden;
  transition: opacity 500ms var(--ease), visibility 0s linear 500ms;
}
.f2r-field.is-on { opacity: 1; visibility: visible; transition: opacity 500ms var(--ease), visibility 0s; }

.f2r-hud { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.f2r-hud text {
  font-family: var(--font-data); font-size: 10px; letter-spacing: .18em;
  fill: rgba(232, 226, 204, .85); text-transform: uppercase;
}
/* quiet readings stay in the WARM archival family — no cool survey blue */
.f2r-hud .hud-t--q { font-size: 8.5px; letter-spacing: .13em; fill: rgba(214, 208, 190, .60); }

/* the plotted traverse + datum cross belong to the FLAT fallback only —
   in the WebGL field the 3-D corridors and the city instrument carry them */
.hud-trace, .hud-datum { display: none; }
html[data-hero="flat"] .hud-trace {
  display: block;
  fill: none; stroke: rgba(228, 206, 146, .55); stroke-width: 1;
  vector-effect: non-scaling-stroke;
  stroke-dasharray: 1; stroke-dashoffset: 1;
  transition: stroke-dashoffset 900ms var(--ease-out-strong) 780ms, stroke 300ms var(--ease), opacity 300ms var(--ease);
}
html[data-hero="flat"] .is-set .hud-trace { stroke-dashoffset: 0; }
.is-lit-hnd .hud-trace--nrt, .is-lit-nrt .hud-trace--hnd { opacity: .22; }
.is-lit-hnd .hud-trace--hnd, .is-lit-nrt .hud-trace--nrt,
.is-arrival .hud-trace { stroke: rgba(238, 214, 148, .95); stroke-width: 1.4; }
html[data-hero="flat"] .hud-datum { display: block; opacity: 0; transition: opacity 400ms var(--ease) 460ms; }
html[data-hero="flat"] .is-set .hud-datum { opacity: 1; }
.hud-datum path, .hud-datum circle { fill: none; stroke: rgba(232, 226, 204, .9); stroke-width: 1; vector-effect: non-scaling-stroke; }
.hud-datum__pulse { animation: f2r-pulse 5.4s var(--ease) infinite; transform-box: fill-box; transform-origin: center; }
@keyframes f2r-pulse {
  0%, 62% { transform: scale(1); opacity: 0; }
  68% { opacity: .8; }
  100% { transform: scale(3.4); opacity: 0; }
}

/* R03 · instrument plaques — the physical dark tag of the reference:
   smoked ground, hairline brass rule, one elbowed leader to the node */
.hud-plq__bg {
  fill: rgba(9, 11, 15, .78);
  stroke: rgba(196, 166, 98, .42); stroke-width: 1;
  vector-effect: non-scaling-stroke;
}
.hud-plq__lead {
  fill: none; stroke: rgba(196, 166, 98, .38); stroke-width: 1;
  vector-effect: non-scaling-stroke;
}
.hud-plq__t { fill: rgba(240, 232, 210, .92); }
.hud-plq__sub { fill: rgba(196, 208, 228, .55); }
.hud-plq__hit { fill: transparent; stroke: none; pointer-events: all; cursor: crosshair; }
.hud-plq { opacity: 0; transition: opacity 420ms var(--ease) 1150ms; }
.hud-plq--tokyo { transition-delay: 950ms; }
.is-set .hud-plq { opacity: 1; }
.hud-plq.is-off { opacity: 0 !important; }
/* addressing: the lit gateway's plaque answers, the other stands back */
.is-lit-hnd .hud-plq--hnd .hud-plq__t, .is-lit-nrt .hud-plq--nrt .hud-plq__t { fill: rgba(244, 220, 156, 1); }
.is-lit-hnd .hud-plq--hnd .hud-plq__bg, .is-lit-nrt .hud-plq--nrt .hud-plq__bg { stroke: rgba(216, 188, 126, .8); }
.is-lit-hnd .hud-plq--nrt, .is-lit-nrt .hud-plq--hnd { opacity: .38; }

/* S2: the instrument goes sparse — the plate carries the depth */
.is-detail .hud-plq__sub { opacity: 0; transition: opacity 300ms var(--ease); }
.f2r-field.is-detail .hud-scale { opacity: 0; }
.is-detail .hud-fuji { opacity: 0 !important; }

/* flat fallback keeps a plotted cross at each gateway */
.hud-gate__x, .hud-gate__c { display: none; }
html[data-hero="flat"] .hud-gate__x, html[data-hero="flat"] .hud-gate__c {
  display: block; fill: none; stroke: rgba(216, 200, 150, .85);
  stroke-width: 1.1; vector-effect: non-scaling-stroke;
}
.hud-gate { opacity: 0; transition: opacity 380ms var(--ease) 1050ms; }
.is-set .hud-gate { opacity: 1; }
.hud-gate.is-off { opacity: 0 !important; }
.is-lit-hnd .hud-gate--nrt, .is-lit-nrt .hud-gate--hnd { opacity: .38; }

/* Fuji: a truthful margin cue — bearing arrow + measure, at the window edge */
.hud-fuji path { fill: none; stroke: rgba(206, 196, 168, .55); stroke-width: 1; vector-effect: non-scaling-stroke; }
.hud-fuji { opacity: 0; transition: opacity 420ms var(--ease) 1650ms; }
.is-set .hud-fuji { opacity: .8; }
.hud-fuji.is-off { opacity: 0 !important; }

/* the measured scale */
.hud-scale path { fill: none; stroke: rgba(214, 208, 186, .55); stroke-width: 1; vector-effect: non-scaling-stroke; }
.hud-scale { opacity: 0; transition: opacity 400ms var(--ease) 1760ms; }
.is-set .hud-scale { opacity: 1; }

/* marginalia — survey-sheet edge text over the night field */
.f2r-marg { position: absolute; inset: 0; }
.f2r-marg__t {
  position: absolute; font-family: var(--font-data); font-size: 9.5px;
  letter-spacing: .22em; text-transform: uppercase; color: rgba(212, 204, 182, .46);
  white-space: nowrap; opacity: 0; transition: opacity 420ms var(--ease);
}
.is-set .f2r-marg__t { opacity: 1; }
.f2r-marg__sheet { left: 72px; top: 78px; transition-delay: 1250ms; }
.f2r-marg__datum { right: 72px; top: 78px; color: rgba(236, 230, 212, .68); transition-delay: 1400ms; }
.f2r-marg__op    { right: 72px; top: 100px; color: rgba(238, 214, 148, .78); transition-delay: 1800ms; }
.f2r-marg__src   { right: 72px; bottom: 16px; font-size: 8.5px; letter-spacing: .14em; color: rgba(212, 204, 182, .36); transition-delay: 1650ms; }
/* R-D: the attribution has a cell of its own in the operations band now, and
   two copies of it printed over each other. The marginalia line stands down
   while the band is up — the licence condition is still met, once. */
body[data-hub] .f2r-marg__src { opacity: 0 !important; transition-delay: 0ms; }

/* non-WebGL: the same field held by the baked GSI render — static, honest.
   The bake now carries the R02 city window (bay center), so the fallback
   frames the same world the live plate does. */
.f2r-flatrelief {
  position: absolute; left: 5%; right: 0; top: 0; bottom: 24%;
  width: auto; height: auto; max-width: none; object-fit: cover;
  opacity: 0; transition: opacity 600ms var(--ease);
  -webkit-mask-image: radial-gradient(125% 105% at 56% 44%, #000 58%, transparent 99%);
          mask-image: radial-gradient(125% 105% at 56% 44%, #000 58%, transparent 99%);
}
.f2r-flatrelief.is-on { opacity: .92; }
/* without a volume there is no stand-off: the flat sheet reads edge to edge */
html[data-hero="flat"] .f2folio { --notch-w: 0px; --notch-d: 0px; --notch-x: 0px; }
html[data-hero="flat"] .folio__band { padding-left: clamp(18px, 2.2vw, 32px); }

/* ================================================================ §2 THE FOLIO
   A low survey plate laid across the foot of the field — an insert of the
   MAP BOOK, cut where the volume stands. Inset on all four sides: an object
   in the world, never a browser-edge drawer. */
.f2folio {
  position: absolute; z-index: 10; background: none;
  /* R10: the index supports the world — it does not dominate it */
  left: clamp(56px, 8.4vw, 122px); right: clamp(52px, 7.2vw, 104px);
  bottom: clamp(26px, 4.8vh, 44px); height: clamp(200px, 25.5vh, 244px);
  color: var(--fo-ink);
  visibility: hidden; opacity: 0; transform: translateY(46px);
  transition:
    opacity 520ms var(--ease) , transform 640ms var(--ease-object),
    right 560ms var(--ease-object), visibility 0s linear 640ms;
  will-change: transform;
}
body[data-hub] .f2folio {
  visibility: visible; opacity: 1; transform: none;
  transition:
    opacity 460ms var(--ease) 720ms, transform 680ms var(--ease-object) 720ms,
    right 560ms var(--ease-object), visibility 0s;
}
/* R4 · the extraction — the sheet leaves the opened volume: released from the
   book's side, a brief airborne float, then it settles flat onto the field.
   The reverse (close) retracts it back toward the volume, not off-screen. */
@media (min-width: 1025px) {
  .f2folio {
    transform: perspective(1300px) translate3d(-72px, -148px, 84px)
               rotateX(16deg) rotateZ(-3.4deg) scale(.88);
    transform-origin: 14% 20%;
  }
  body[data-hub] .f2folio {
    transform: none;
    animation: f2r-folio-extract 1200ms var(--ease-object) 660ms both;
  }
  @keyframes f2r-folio-extract {
    0%   { opacity: 0; transform: perspective(1300px) translate3d(-72px, -148px, 84px)
                       rotateX(16deg) rotateZ(-3.4deg) scale(.88); }
    52%  { opacity: 1; transform: perspective(1300px) translate3d(-10px, -26px, 36px)
                       rotateX(7.5deg) rotateZ(-1.1deg) scale(.972); }
    82%  { transform: perspective(1300px) translate3d(2px, 7px, 9px)
                       rotateX(-1.8deg) rotateZ(.35deg) scale(1.006); }
    100% { transform: none; }
  }
}

/* one complete sheet — no carved silhouette */
.folio__paper {
  position: absolute; inset: 0; z-index: 0;
  /* R3: one register quieter — the sheet supports the field, it does not
     outshine it. Same archival stock, less studio light on it. */
  background:
    radial-gradient(120% 90% at 12% 4%, rgba(253, 250, 240, .62) 0%, rgba(253, 250, 240, 0) 50%),
    radial-gradient(70% 60% at 78% 90%, rgba(122, 106, 70, .13) 0%, rgba(122, 106, 70, 0) 60%),
    /* the packet's ivory measured at hue 31-32 / sat .083-.107 / val .84-.90;
       this stock was sitting at hue 43 and sat .15 - too yellow, too coloured */
    linear-gradient(172deg, #E6DCD1 0%, #DED4C8 58%, #D6CABD 100%);
  box-shadow:
    0 2px 3px rgba(3, 5, 11, .42),
    22px 30px 48px -14px rgba(3, 5, 11, .72),
    54px 82px 150px -30px rgba(2, 3, 8, .8);
}
.folio__paper > span { position: absolute; pointer-events: none; }
/* archival clouding — Pergamenata-like restrained variation, never dirt */
.folio__age {
  inset: 0; z-index: 1;
  background:
    radial-gradient(42% 60% at 30% 20%, rgba(250, 247, 238, .5), transparent 70%),
    radial-gradient(38% 52% at 62% 80%, rgba(164, 146, 104, .10), transparent 72%),
    radial-gradient(30% 44% at 88% 12%, rgba(164, 146, 104, .08), transparent 70%),
    radial-gradient(150% 130% at 50% 50%, transparent 62%, rgba(120, 104, 68, .12) 96%);
}
/* laid fibre — Awagami kozo surface, fine and physical */
.folio__fibre {
  inset: 0; z-index: 2;
  background-image: var(--grain); background-size: 148px 148px;
  opacity: .17; mix-blend-mode: multiply;
}
/* fold memory — the sheet has been in the volume; one quiet vertical set */
.folio__fold {
  inset: 0; z-index: 2;
  background:
    linear-gradient(90deg, transparent calc(26% - 5px), rgba(110, 96, 62, .075) calc(26% - 1px),
      rgba(255, 252, 242, .5) 26%, rgba(110, 96, 62, .05) calc(26% + 3px), transparent calc(26% + 8px));
}
/* cut stock: lit head, sunk foot — an edge, not a border */
.folio__cut {
  inset: 0; z-index: 3;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .62),
    inset 0 -1px 0 rgba(90, 78, 50, .34),
    inset 1px 0 0 rgba(255, 255, 255, .34),
    inset -1px 0 0 rgba(90, 78, 50, .26);
}
/* R4 · curl-bend memory — the sheet has been carried: the free corner holds a
   soft lift, read as light and shadow, not as a bent div */
.folio__curl {
  inset: 0; z-index: 2;
  background:
    radial-gradient(46% 34% at 99.4% 1%, rgba(20, 15, 6, .17) 0%, rgba(20, 15, 6, 0) 62%),
    radial-gradient(30% 22% at 97.5% 3%, rgba(255, 252, 242, .55) 0%, rgba(255, 252, 242, 0) 55%),
    radial-gradient(20% 15% at 100% 0%, rgba(120, 104, 68, .22) 0%, rgba(120, 104, 68, 0) 70%);
}
/* R4 · the fore-edge — stacked stock on the free (right) edge; with the foot
   block the sheet reads as cut paper with real thickness on two sides */
.folio__lip {
  top: 3px; bottom: -6px; right: -7px; width: 7px; z-index: 0;
  background: linear-gradient(90deg,
    var(--fo-edge) 0 1px, var(--fo-edge-l) 1px 2px, var(--fo-edge-d) 2px 3px,
    #DDD4BC 3px 5px, var(--fo-edge-d) 5px 6px, rgba(20, 16, 8, .55) 6px 7px);
  transform: skewY(1.1deg); transform-origin: 0 0;
}
/* THE PAGE BLOCK — stacked ivory along the foot: this sheet is of the volume */
.folio__block {
  left: 0; right: 0; bottom: -9px; height: 9px; z-index: 0;
  background: linear-gradient(180deg,
    var(--fo-edge) 0 1px, var(--fo-edge-l) 1px 3px, var(--fo-edge-d) 3px 4px,
    #E2DAC4 4px 6px, var(--fo-edge-d) 6px 7px, #EDE6D2 7px 8px, rgba(20, 16, 8, .6) 8px 9px);
}
/* ------------------------------------------------------------- band + body */
.folio__band {
  position: absolute; left: 0; right: 0; top: 0; z-index: 6;
  display: flex; align-items: center; gap: .8rem;
  padding: 10px clamp(16px, 2vw, 30px) 0;
}
.folio__band .pnl__k {
  color: var(--fo-ink-4); letter-spacing: .2em;
  min-width: 0; flex: 0 1 auto; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.folio__band .ev { flex: none; }
/* the band sits right of the cut, so it never collides with the volume */
.folio__band { padding-left: calc(var(--notch-x) + var(--notch-w) + 26px); }

.pnl-x {
  margin-left: auto; display: inline-flex; align-items: center; gap: .45rem;
  font-family: var(--font-data); font-size: var(--t-micro); letter-spacing: .18em;
  color: var(--fo-ink-2); padding: .42rem .55rem; margin-right: -.55rem;
  transition: color var(--m-micro) var(--ease);
}
.pnl-x svg { width: .58rem; height: .58rem; fill: none; stroke: currentColor; stroke-width: 1.5; }
.pnl-x:hover { color: var(--hot); }

.folio__body {
  position: absolute; inset: 0; z-index: 5;
  display: grid;
  grid-template-columns: clamp(220px, 23%, 300px) 1px minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr) auto;
  gap: 0 clamp(18px, 2.2vw, 30px);
  padding: 46px clamp(16px, 2vw, 30px) 9px clamp(18px, 2.2vw, 32px);
}
/* the sheet's content never prints past the sheet */
.folio__id, .ops { min-height: 0; overflow: hidden; }
/* at full measure every title is one line — the reserved second line
   exists only where columns narrow enough to wrap, so the state row
   (PUBLISHED / FORTHCOMING) always keeps its printed room */
@media (min-width: 1280px) {
  .op__t { min-height: 1.18em; }
}
.folio__gut { background: var(--fo-hair-2); margin: 4px 0 10px; }

/* ---------------------------------------------------- §3 LIVING TYPOGRAPHY
   Publication logic, in plotting order: the name prints, the datum registers,
   the index line plots, numbers lock, titles resolve, states last. */
.folio__id { min-width: 0; }
.folio__crumb {
  color: var(--fo-ink-3); letter-spacing: .22em;
  opacity: 0; transition: opacity 420ms var(--ease) 860ms;
}
.folio__name {
  font-family: var(--font-display); font-weight: 400; letter-spacing: -.032em;
  font-size: clamp(46px, 3.4vw + 1rem, 64px); line-height: .84;
  margin: 4px 0 0; color: var(--fo-ink);
  clip-path: inset(0 0 100% 0);
  transition: clip-path 620ms var(--ease-out-strong) 1200ms;
}
.folio__datum {
  margin-top: 6px;
  font-family: var(--font-data); font-size: 11px; letter-spacing: .3em;
  color: var(--fo-ink-2); line-height: 1.7; font-variant-numeric: tabular-nums;
  opacity: 0;
  transition: opacity 460ms var(--ease) 1500ms, letter-spacing 700ms var(--ease-out-strong) 1500ms;
}
.folio__datum b { font-weight: 400; color: var(--fo-ink); }
.folio__datum .brk { display: block; }
.folio__datum .sep { color: var(--fo-hair); padding: 0 .5em; }
.folio__gates {
  margin-top: 5px; font-family: var(--font-data); font-size: 9.5px;
  letter-spacing: .08em; color: var(--fo-ink-2); line-height: 1.5; max-width: 100%;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  opacity: 0; transition: opacity 460ms var(--ease) 1700ms;
}
body[data-hub] .folio__crumb, body[data-hub] .folio__datum, body[data-hub] .folio__gates { opacity: 1; }
body[data-hub] .folio__name { clip-path: inset(-4% -2% -8% -2%); }
body[data-hub] .folio__datum { letter-spacing: .07em; }

/* ------------------------------------------------------------ §4 OPERATIONS
   Four editorial columns under one plotted index line. */
.ops { min-width: 0; display: flex; flex-direction: column; }
.ops__k {
  color: var(--fo-ink-2); letter-spacing: .2em; padding: 4px 0 9px;
  position: relative; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  flex: none;   /* the index line never compresses into its own text */
  opacity: 0; transition: opacity 400ms var(--ease) 1430ms;
}
.ops__k::after {                      /* the index line — it plots first */
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: var(--fo-ink-4);
  transform: scaleX(0); transform-origin: 0 50%;
  transition: transform 720ms var(--ease-out-strong) 1490ms;
}
body[data-hub] .ops__k { opacity: 1; }
body[data-hub] .ops__k::after { transform: none; }

/* R08/R09 · FOUR EQUAL-RANK OPERATION COLUMNS (accepted FOLIO contract):
   same glyph box, same title token/size/baseline, same descriptor start,
   same state baseline. Asymmetry lives only in the glyph silhouettes and
   the publication state — never in padding, size or baseline drift. */
.ops__list { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); flex: 1; }
.ops__list li { min-width: 0; position: relative; }
.ops__list li + li::before {
  content: ""; position: absolute; left: 0; top: 10px; bottom: 12px; width: 1px;
  background: var(--fo-hair-2);
  opacity: 0; transition: opacity 400ms var(--ease) 1760ms;
}
body[data-hub] .ops__list li + li::before { opacity: 1; }

.op {
  display: flex; flex-direction: column; align-items: flex-start; text-align: left;
  width: 100%; height: 100%; min-height: 92px; position: relative;
  padding: 8px 16px 5px 0;
  transition: background var(--m-micro) var(--ease);
}
.ops__list li + li .op { padding-left: 16px; }
.op::before {                          /* struck head-band on the active domain */
  content: ""; position: absolute; left: 0; right: auto; top: -1px; height: 2px; width: 0;
  background: var(--plot); transition: width var(--m-struct) var(--ease);
}
.op__i {
  font-family: var(--font-data); font-size: 10px; letter-spacing: .14em;
  color: var(--plot-semantic); font-variant-numeric: tabular-nums;
  opacity: 0; transform: translateX(-7px);
  transition: opacity 360ms var(--ease), transform 460ms var(--ease-out-strong);
}
.op__i::after {
  content: ""; display: inline-block; vertical-align: 3px;
  width: 22px; height: 1px; background: var(--fo-hair); margin-left: 9px;
}
/* the printed semantic glyph — one box, one position, one stroke voice;
   asymmetry between operations lives ONLY in the silhouette */
.op__g {
  position: absolute; top: 8px; right: 16px; width: 27px; height: 27px;
  opacity: 0; transform: translateY(6px);
  transition: opacity 420ms var(--ease), transform 460ms var(--ease-out-strong);
}
.op__g svg { width: 100%; height: 100%; fill: none; stroke: var(--plot); stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.op__g .op__g-base { stroke: var(--fo-hair); }
.op__g .op__g-wave { stroke-width: 1.5; }
.op__t {
  display: block; font-family: var(--font-display); font-weight: 400;
  font-size: clamp(15.5px, 1vw + 4px, 19px); line-height: 1.14; letter-spacing: -.016em;
  color: var(--fo-ink); margin-top: 5px; min-height: 2.24em;
  text-wrap: balance;
  opacity: 0; transform: translateY(9px);
  transition: opacity 420ms var(--ease), transform 480ms var(--ease-out-strong), color var(--m-micro) var(--ease);
}
.op__sub {
  display: block; font-style: normal; font-family: var(--font-display);
  font-size: clamp(11.5px, .62vw + 4px, 13px); letter-spacing: 0;
  color: var(--fo-ink-2); margin-top: 3px; line-height: 1.38;
  max-width: 22ch;
  opacity: 0; transition: opacity 420ms var(--ease);
}
.op__ev { margin-top: auto; padding-top: 5px; opacity: 0; transition: opacity 400ms var(--ease); }
.op__ev .ev { border: 0; padding: 0; letter-spacing: .15em; font-size: 9px; }
/* the registration order, column by column */
.ops__list li:nth-child(1) .op__i { transition-delay: 1580ms; }
.ops__list li:nth-child(2) .op__i { transition-delay: 1650ms; }
.ops__list li:nth-child(3) .op__i { transition-delay: 1720ms; }
.ops__list li:nth-child(4) .op__i { transition-delay: 1790ms; }
.ops__list li:nth-child(1) .op__g { transition-delay: 1640ms; }
.ops__list li:nth-child(2) .op__g { transition-delay: 1710ms; }
.ops__list li:nth-child(3) .op__g { transition-delay: 1780ms; }
.ops__list li:nth-child(4) .op__g { transition-delay: 1850ms; }
.ops__list li:nth-child(1) .op__t { transition-delay: 1700ms; }
.ops__list li:nth-child(2) .op__t { transition-delay: 1770ms; }
.ops__list li:nth-child(3) .op__t { transition-delay: 1840ms; }
.ops__list li:nth-child(4) .op__t { transition-delay: 1910ms; }
.ops__list li:nth-child(1) .op__sub { transition-delay: 1810ms; }
.ops__list li:nth-child(2) .op__sub { transition-delay: 1880ms; }
.ops__list li:nth-child(3) .op__sub { transition-delay: 1950ms; }
.ops__list li:nth-child(4) .op__sub { transition-delay: 2020ms; }
.ops__list li:nth-child(1) .op__ev { transition-delay: 2050ms; }
.ops__list li:nth-child(2) .op__ev { transition-delay: 2110ms; }
.ops__list li:nth-child(3) .op__ev { transition-delay: 2170ms; }
.ops__list li:nth-child(4) .op__ev { transition-delay: 2230ms; }
body[data-hub] .op__i, body[data-hub] .op__g { opacity: 1; transform: none; }
body[data-hub] .op__t, body[data-hub] .op__sub, body[data-hub] .op__ev { opacity: 1; transform: none; }
/* after the entrance, responses answer immediately */
body[data-hub] .f2folio.is-live .op__i, body[data-hub] .f2folio.is-live .op__g,
body[data-hub] .f2folio.is-live .op__t,
body[data-hub] .f2folio.is-live .op__sub, body[data-hub] .f2folio.is-live .op__ev,
body[data-hub] .f2folio.is-live .folio__crumb, body[data-hub] .f2folio.is-live .folio__datum,
body[data-hub] .f2folio.is-live .folio__gates, body[data-hub] .f2folio.is-live .ops__k,
body[data-hub] .f2folio.is-live .folio__foot { transition-delay: 0ms; }

.op:hover { background: rgba(25, 22, 12, .05); }
.op:hover .op__t { color: var(--hot); }
/* the HUD addressing a gateway: the arrival index answers */
.op.is-hudlit { background: rgba(138, 116, 66, .10); }
.op.is-hudlit .op__t { color: var(--hot); }
.op.is-hudlit::before { width: 100%; }
/* active domain */
.op[aria-expanded="true"] { background: rgba(25, 22, 12, .055); }
.op[aria-expanded="true"]::before { width: 100%; }
.op[aria-expanded="true"] .op__i { color: var(--hot); }
.op[aria-expanded="true"] .op__t::after {
  content: "→"; font-family: var(--font-data); font-weight: 400; font-size: .72em;
  color: var(--hot); margin-left: .5em;
}

/* -------------------------------------------------------------- §5 FOLIO FOOT */
.folio__foot {
  grid-column: 1 / -1; display: flex; align-items: baseline; gap: 26px;
  padding-top: 7px; border-top: 1px solid var(--fo-hair);
  margin-top: auto;
  opacity: 0; transition: opacity 440ms var(--ease) 2160ms;
}
body[data-hub] .folio__foot { opacity: 1; }
.folio__guide {
  display: inline-flex; align-items: baseline; gap: 12px; flex: none;
  text-decoration: none; transition: background var(--m-micro) var(--ease);
}
.folio__guide b { font-family: var(--font-display); font-weight: 400; font-size: 15px; letter-spacing: -.012em; color: var(--fo-ink); transition: color var(--m-micro) var(--ease); }
.folio__guide .ev { border: 0; padding: 0; font-size: 9px; letter-spacing: .15em; }
.folio__guide:hover b { color: var(--hot); }
.folio__note {
  margin-left: auto; min-width: 0; font-family: var(--font-data); font-size: 7.5px;
  letter-spacing: .1em; text-transform: uppercase; color: var(--fo-ink-4);
  text-align: right; line-height: 1.5; max-width: 88ch;
}
@media (min-width: 1025px) {
  /* one registration line: the disclaimer never eats the identity column */
  .folio__foot .folio__note { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
}
.folio__back {
  flex: none; font-family: var(--font-data); font-size: 9px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--fo-ink-2);
  transition: color var(--m-micro) var(--ease);
}
.folio__back:hover { color: var(--hot); }

/* ====================================================== §6 S2 OPERATION PLATE
   R11 · SPATIAL OPERATIONAL PLATE — one low, wide smoked-glass surface
   standing IN the Terrain/HUD world (Packet B, 03): subtle physical
   thickness and tilt, the field alive beneath it, high readability.
   Context → Operational Intelligence → Action, left to right.
   Never a browser right drawer. */
.fnl {
  position: absolute; z-index: 11;
  /* R-S1: the plate starts further right and lower, so the city instrument
     it was generated FROM stays visible beside it. An operation plate that
     buries its own field is a browser drawer wearing a costume. */
  left: clamp(510px, 46vw, 720px); right: clamp(36px, 4.4vw, 72px);
  top: clamp(120px, 17vh, 168px);
  bottom: calc(clamp(26px, 4.8vh, 44px) + clamp(200px, 25.5vh, 244px) + 20px);
  display: flex; flex-direction: column;
  color: var(--pl-ink);
  background:
    radial-gradient(120% 90% at 16% 0%, rgba(255, 250, 235, .05), transparent 55%),
    linear-gradient(166deg, rgba(32, 34, 41, .88) 0%, rgba(23, 25, 30, .84) 46%, rgba(16, 18, 23, .88) 100%);
  -webkit-backdrop-filter: blur(6px) saturate(.92);
          backdrop-filter: blur(6px) saturate(.92);
  border: 1px solid rgba(196, 166, 98, .26);
  box-shadow:
    0 1px 0 rgba(255, 252, 240, .08) inset,
    0 -1px 0 rgba(0, 0, 0, .5) inset,
    1px 0 0 rgba(255, 252, 240, .04) inset,
    0 3px 5px rgba(2, 3, 8, .5),
    0 30px 60px -18px rgba(2, 3, 8, .8);
  visibility: hidden; opacity: 0;
  /* the plate is generated by the active operation: it stands up out of
     the folio's index edge below it, never slides in from browser chrome */
  transform: perspective(1600px) translate3d(-34px, 30px, -50px) rotateX(5deg) rotateY(-2.6deg) scale(.965);
  transform-origin: 12% 96%;
  transition: opacity 420ms var(--ease), transform 520ms var(--ease-object), visibility 0s linear 520ms;
  will-change: transform;
}
body[data-hub="detail"] .fnl {
  visibility: visible; opacity: 1;
  /* settled: a physical plate holds a breath of the world's perspective */
  transform: perspective(1600px) rotateX(1.3deg) rotateY(-1.7deg);
  transition: opacity 420ms var(--ease) 240ms, transform 560ms var(--ease-object) 240ms, visibility 0s;
}
/* the plate is plotted: a fine survey grid, not a texture */
.fnl::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 0;
  background:
    linear-gradient(rgba(173,146,87,.5), rgba(173,146,87,.5)) 9px 9px / 13px 1px no-repeat,
    linear-gradient(rgba(173,146,87,.5), rgba(173,146,87,.5)) 9px 9px / 1px 13px no-repeat,
    linear-gradient(rgba(173,146,87,.5), rgba(173,146,87,.5)) calc(100% - 22px) calc(100% - 10px) / 13px 1px no-repeat,
    linear-gradient(rgba(173,146,87,.5), rgba(173,146,87,.5)) calc(100% - 10px) calc(100% - 22px) / 1px 13px no-repeat,
    repeating-linear-gradient(90deg, var(--pl-hair-2) 0 1px, transparent 1px 44px),
    repeating-linear-gradient(0deg, var(--pl-hair-2) 0 1px, transparent 1px 44px);
  mask-image: linear-gradient(180deg, rgba(0,0,0,.8), rgba(0,0,0,.25) 40%, rgba(0,0,0,.6));
  -webkit-mask-image: linear-gradient(180deg, rgba(0,0,0,.8), rgba(0,0,0,.25) 40%, rgba(0,0,0,.6));
}
.fnl::after {                          /* smoked grain */
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 0;
  background-image: var(--grain); background-size: 190px 190px;
  opacity: .10; mix-blend-mode: overlay;
}
/* R-S2 · glass dressing: corner brackets and an edge glint, so the plate has
   machined corners instead of a CSS border */
.fnl__corners,
.fnl > .fnl__band::before { content: none; }
body[data-hub="detail"] .fnl {
  box-shadow:
    0 1px 0 rgba(255, 252, 240, .12) inset,
    0 -1px 0 rgba(0, 0, 0, .55) inset,
    1px 0 0 rgba(255, 252, 240, .06) inset,
    0 3px 6px rgba(2, 3, 8, .55),
    0 34px 70px -18px rgba(2, 3, 8, .84);
  border-color: rgba(210, 180, 110, .40);
}

/* R-S2 · THE KICKER — above the glass, on the field. It names the layer the
   reader has descended into before they meet the plate's own frame. */
.fnl__kick {
  position: absolute; left: 0; right: 0; bottom: 100%;
  display: flex; align-items: center; gap: .7rem;
  padding: 0 2px .5rem;
  font: 600 var(--t-micro, 10px)/1 var(--font-data, ui-monospace, monospace);
  letter-spacing: .30em; text-transform: uppercase;
  color: rgba(226, 205, 158, .92);
  text-shadow: 0 1px 3px rgba(0, 0, 0, .85);
  opacity: 0; transform: translateY(6px);
  transition: opacity 380ms var(--ease) 300ms, transform 420ms var(--ease-object) 300ms;
  pointer-events: none;
}
body[data-hub="detail"] .fnl__kick { opacity: 1; transform: none; }
.fnl__kick-r { flex: 1; height: 1px; background: linear-gradient(90deg, rgba(210,180,110,.55), rgba(210,180,110,.10)); }
.fnl__kick-b { color: rgba(226, 205, 158, .70); letter-spacing: .22em; }
.fnl__kick-b b { color: #F0DCAE; font-weight: 600; }

/* registration corner: the plate is generated from the field */
.fnl__band {
  display: flex; align-items: center; gap: .8rem; flex: none; position: relative; z-index: 2;
  padding: .8rem 1.35rem .72rem; border-bottom: 1px solid var(--pl-hair);
}
.fnl__band .pnl__k {
  color: #EBD3A0; letter-spacing: .30em; font-weight: 600;
  font-size: calc(var(--t-micro, 10px) * 1.18);
}
/* the sheet registration, the way a drawing carries its own sheet number */
.fnl__reg {
  margin-left: auto; margin-right: .9rem;
  font: 500 var(--t-micro, 10px)/1 var(--font-data, ui-monospace, monospace);
  letter-spacing: .24em; color: rgba(196, 176, 138, .58); white-space: nowrap;
}
.fnl__reg i { font-style: normal; color: rgba(196, 176, 138, .32); padding: 0 .12em; }
/* the operation's printed glyph registers the plate to its index column */
.fnl__g { width: 19px; height: 19px; flex: none; }
.fnl__g svg { width: 100%; height: 100%; fill: none; stroke: var(--pl-plot); stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.fnl__g .op__g-base { stroke: var(--pl-hair); }
.fnl .pnl-x { color: var(--pl-ink-2); }
.fnl .pnl-x:hover { color: var(--pl-ink); }

/* ---------------------------------------------- R-S2 · THE SPATIAL VIGNETTE
   An engraved chart of the working area, sitting in the plate's lower right
   where a survey sheet carries its locality inset. Every line in it is
   computed from geography this build already holds. */
.fnl__vig {
  position: absolute; z-index: 2; margin: 0; pointer-events: none;
  /* the locality inset, under the operation's own name in the head column:
     "this operation, in this place". Keeping it out of the right column
     leaves the NEXT-JOB control where it was — the strip below repeats the
     destination as a readout, it does not replace the button. */
  left: 1.35rem; bottom: 3.5rem;
  width: clamp(112px, 11.5vw, 148px); aspect-ratio: 1;
  opacity: 0; transform: translateY(10px) scale(.97);
  transition: opacity 520ms var(--ease) 470ms, transform 620ms var(--ease-object) 470ms;
}
body[data-hub="detail"] .fnl__vig { opacity: 1; transform: none; }
.fnl__vig .vig { width: 100%; height: 100%; overflow: visible; }
.fnl__vig .vig line,
.fnl__vig .vig circle,
.fnl__vig .vig path { vector-effect: non-scaling-stroke; fill: none; }

.vig__grid line { stroke: rgba(196, 166, 98, .13); stroke-width: 1; }
/* the real shoreline — the brightest engraved line on the chart */
.vig__coast path { stroke: rgba(226, 196, 132, .78); stroke-width: 1.15; stroke-linejoin: round; }
.vig__rings circle { stroke: rgba(196, 166, 98, .34); stroke-width: 1; stroke-dasharray: 3 4; }
.vig__rays line { stroke: rgba(226, 200, 142, .50); stroke-width: 1; }
.vig__node { fill: #F0DCAE; stroke: none; }
.vig__halo { stroke: rgba(240, 220, 174, .55); stroke-width: 1; }
.vig__corr { stroke: rgba(232, 201, 137, .60); stroke-width: 1.3; stroke-dasharray: 2 3; }
.vig__datum line { stroke: #F4E4BC; stroke-width: 1.2; }
.vig__datum circle { stroke: #F4E4BC; stroke-width: 1.2; }
.vig__leg line { stroke: rgba(196, 176, 138, .55); stroke-width: 1; }
.vig__leg text {
  fill: rgba(206, 186, 148, .72); font: 500 5.4px var(--font-data, ui-monospace, monospace);
  letter-spacing: .12em;
}
/* the active domain's real working radius, lit on the same chart */
.vig__work {
  stroke: rgba(240, 214, 150, .70); stroke-width: 1.4;
  fill: rgba(226, 190, 118, .055);
  transition: r 620ms var(--ease-object);
}

/* --------------------------------------------------- R-S2 · THE CELL STRIP
   Gateways and the next job, as instrument cells: label over value, hairline
   divided. Truth only — bearing and distance are computed, never authored. */
.fnl__strip {
  position: relative; z-index: 2; flex: none;
  display: grid; grid-template-columns: 1fr 1fr 1.15fr;
  border-top: 1px solid rgba(210, 180, 110, .26);
  background: linear-gradient(180deg, rgba(255,250,235,.035), rgba(0,0,0,.16));
  opacity: 0; transform: translateY(8px);
  transition: opacity 400ms var(--ease) 520ms, transform 460ms var(--ease-object) 520ms;
}
body[data-hub="detail"] .fnl__strip { opacity: 1; transform: none; }
.fnl__cell {
  display: flex; flex-direction: column; gap: .3rem;
  padding: .62rem 1.1rem .68rem;
  border-left: 1px solid var(--pl-hair-2);
}
.fnl__cell:first-child { border-left: 0; }
.fnl__cell-k {
  font: 500 var(--t-micro, 10px)/1 var(--font-data, ui-monospace, monospace);
  letter-spacing: .24em; color: rgba(196, 176, 138, .62);
}
.fnl__cell-v {
  font: 600 calc(var(--t-micro, 10px) * 1.24)/1.1 var(--font-data, ui-monospace, monospace);
  letter-spacing: .12em; color: #E4D2A8;
}
.fnl__cell--act .fnl__cell-v { color: #F0C97E; }

.pnl__scroll {
  flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  scrollbar-width: thin; scrollbar-color: var(--pl-ink-3) transparent;
  position: relative; z-index: 1;
  display: flex; flex-direction: column;
}
.fnl__scroll { padding: 1.25rem 1.35rem 1.1rem; gap: 1.2rem; }

.fnd { display: flex; flex-direction: column; gap: 1.15rem; }
.fnd { opacity: 0; transform: translateY(12px); transition: opacity 440ms var(--ease-out-strong), transform 440ms var(--ease-out-strong); }
body[data-hub="detail"] .fnd { opacity: 1; transform: none; transition-delay: 430ms; }
.fnd__t {
  font-family: var(--font-display); font-weight: 400; letter-spacing: -.02em;
  font-size: clamp(1.55rem, 1.2rem + .9vw, 2.05rem); line-height: 1.05; color: var(--pl-ink);
}
.fnd__lede { margin-top: .65rem; font-size: var(--t-small); line-height: 1.6; color: var(--pl-ink-2); max-width: 46ch; }
.fnd__scope { margin-top: .65rem; }
.fnd__gk { color: var(--pl-ink-3); letter-spacing: .22em; padding-bottom: .5rem; border-bottom: 1px solid var(--pl-hair); }

/* gateway rows — instrument data on graphite */
.gates { border-bottom: 1px solid var(--pl-hair); }
.gate {
  display: grid; grid-template-columns: 3rem minmax(0, 1fr) auto; gap: .9rem;
  align-items: baseline; padding: .68rem .1rem;
}
.gate + .gate { border-top: 1px solid var(--pl-hair-2); }
.gate__code { font-family: var(--font-data); font-size: 1rem; letter-spacing: .08em; color: var(--pl-plot); font-variant-numeric: tabular-nums; }
.gate__t b { font-family: var(--font-display); font-weight: 400; font-size: 1rem; letter-spacing: -.01em; color: var(--pl-ink); }
.gate__t i { display: block; font-style: normal; font-family: var(--font-data); font-size: var(--t-micro); letter-spacing: .1em; color: var(--pl-ink-3); margin-top: .2rem; }
.gate__rel { align-self: center; font-family: var(--font-data); font-size: var(--t-micro); letter-spacing: .1em; color: #A99A72; white-space: nowrap; }
/* The plate is a bronze-and-ink surface. Two cool accents were still live in
   it after the palette pass: this gateway relation string, and .ev--pub
   inheriting v2's --evidence teal through a rule the earlier fix did not
   reach. Both are restated here in the plate's own metal. */
.fnl .ev--pub, .fnl .ev--pub::before { color: #C9B47E; }
.fnl .ev, .fnl .ev::before { --evidence: #C9B47E; }

/* operation rows */
.fnrows li + li { border-top: 1px solid var(--pl-hair-2); }
.fnrow {
  display: flex; align-items: baseline; justify-content: space-between; gap: .9rem;
  padding: .72rem .1rem; text-decoration: none;
  transition: background var(--m-micro) var(--ease), padding-left var(--m-struct) var(--ease);
}
.fnrow__t b { display: block; font-family: var(--font-display); font-weight: 400; font-size: 1.02rem; line-height: 1.3; letter-spacing: -.01em; color: var(--pl-ink); }
.fnrow__t i { display: block; font-style: normal; font-family: var(--font-data); font-size: var(--t-micro); letter-spacing: .12em; color: var(--pl-ink-3); margin-top: .24rem; }
.fnrow .ev { flex: none; align-self: center; border: 0; padding: 0; }
/* published state reads in the plate's own brass, not in a stray teal — the
   folio already made this correction and the plate had kept the old hue */
.fnl .ev--pub { color: #C9B47E; }
.fnl .ev--none { color: var(--pl-ink-3); }
.fnl .ev--illus { color: #B0A184; }
a.fnrow:hover { background: rgba(240, 236, 220, .05); padding-left: .5rem; }
a.fnrow:hover .fnrow__t b { color: #E8C989; }
.fnrow--none .fnrow__t b { color: var(--pl-ink-2); }

.fnd__empty { font-size: var(--t-small); line-height: 1.6; color: var(--pl-ink-3); border-top: 1px solid var(--pl-hair-2); padding-top: .75rem; max-width: 44ch; }
.fnd__next { display: flex; align-items: baseline; gap: 1rem; flex-wrap: wrap; border-top: 1px solid var(--pl-hair); padding-top: .85rem; }
.fnd__next .u-label { color: var(--pl-ink-3); }
.fnd__next button {
  font-family: var(--font-display); font-weight: 400; font-size: 1rem; letter-spacing: -.01em;
  color: var(--pl-ink); border-bottom: 1px solid var(--pl-ink-3); padding-bottom: .14rem;
  transition: color var(--m-micro) var(--ease), border-color var(--m-micro) var(--ease);
}
.fnd__next button:hover { color: #E8C989; border-color: #E8C989; }
.fnl__foot { margin-top: auto; padding-top: .85rem; border-top: 1px solid var(--pl-hair-2); }
.fnl__foot .folio__note, .fnl__foot .hub__note {
  margin: 0; font-family: var(--font-data); font-size: 8.5px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--pl-ink-3); line-height: 1.7; white-space: normal; text-align: left;
}
@media (min-width: 1025px) {
  /* the plate's registration line never reads as a torn sentence */
  .fnl__foot .folio__note { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
}

/* -------------------------------------------------- §7 S2 RECOMPOSITION
   The plate stands ABOVE the settled sheet: the folio keeps its full
   measure and stays the index — quieter, the active column lit. */
@media (min-width: 1025px) {
  body[data-hub="detail"] .f2folio .op:not([aria-expanded="true"]) .op__t { color: var(--fo-ink-2); }
  body[data-hub="detail"] .f2folio .op:not([aria-expanded="true"]) .op__g { opacity: .55; }
  /* the world above the sheet belongs to the plate now: the index recedes
     one register, the way the terrain does */
  body[data-hub="detail"] .folio__paper { filter: brightness(.94); }

  /* R11 · Context → Operational Intelligence → Action, left to right */
  /* R-S1/R-S2: the plate gave up 9vw of width so the city instrument could
     stay in open air, and three text columns no longer fit in what is left —
     they were overrunning each other and the vignette. Two columns: the
     operation's own identity and its locality inset on the left, everything
     it lists stacked on the right. */
  .fnl .fnd {
    display: grid; flex: 1;
    grid-template-columns: minmax(196px, .86fr) minmax(0, 1.30fr);
    grid-auto-rows: min-content;
    align-content: start;
    gap: .95rem clamp(20px, 2vw, 32px);
  }
  /* the action column stacks its state under the title — no squeezed wrap */
  .fnl .fnd__grp + .fnd__grp .fnrow { flex-direction: column; align-items: flex-start; gap: .3rem; }
  .fnl .fnd__grp + .fnd__grp .fnrow .ev { align-self: flex-start; }
  .fnl .fnd__head {
    grid-column: 1; grid-row: 1 / -1;
    border-right: 1px solid var(--pl-hair); padding-right: clamp(16px, 1.6vw, 26px);
    /* the locality inset is absolutely placed at the foot of this column, so
       the lede is given a floor it must not cross */
    padding-bottom: calc(clamp(112px, 11.5vw, 148px) + 1.1rem);
  }
  .fnl .fnd__grp,
  .fnl .fnd__empty,
  .fnl .fnd__next { grid-column: 2; min-width: 0; }
  .fnl__scroll { overflow-y: auto; }
}

/* ---------------------------------------------------- §8 SCENE ANSWERS
   While the field is operational the browsing chrome stands down; the way
   back stays lit. (Carried from the accepted F2 behavior.) */
body[data-hub] .hero__head, body[data-hub] .colophon, body[data-hub] .spine-rail { opacity: 0; }
body[data-hub] .finder { opacity: 0; pointer-events: none; }
body[data-hub] .rail__row { opacity: 0; pointer-events: none; }
body[data-hub] .finder, body[data-hub] .colophon { animation: none; opacity: 0; }
/* the rail itself stays alive: it carries the descent instrument, which the
   city state lifts to the top of the world (R13). Its resting opacity
   normally comes from the entrance animation's fill — killing the
   animation must not leave it at the keyframe start. */
/* R-C FUNCTIONAL CLOSURE. The rail as a container must not intercept input
   over the scene, but the descent instrument it carries MUST stay live — with
   `pointer-events: none` here and nothing restoring it, the scale control was
   inert to mouse and touch in exactly the state where it is lifted to the top
   of the world and reads as the primary navigation. Keyboard still worked,
   which is the signature that made it look like a working control. */
body[data-hub] .rail { animation: none; opacity: 1; pointer-events: none; }
body[data-hub] .rail #crumb,
body[data-hub] .rail #crumb * { pointer-events: auto; }
body[data-hub] .rail__k { opacity: 0; }
body[data-hub] .rail__head { border-bottom-color: transparent; }
.dock .brand, .dock__nav, .seg { transition: opacity 340ms var(--ease) 120ms; }
@media (min-width: 1025px) {
  /* the City owns the top of the world: the browsing chrome stands down so
     the descent instrument never collides with the dock (UI/UX review F2) */
  body[data-hub] .dock .brand { opacity: 0; pointer-events: none; }
  body[data-hub] .dock__nav, body[data-hub] .seg { opacity: 0; pointer-events: none; }
}
/* the field scene keeps its light: soften the page vignette while the hub is up */
body[data-hub] .hero__scrim { opacity: .5; }
/* The dock is fully stood down while the City is up (brand, nav and the
   language segment are each opacity:0 + pointer-events:none above), but the
   container still sat over the lifted instrument and swallowed its clicks:
   the crumb lives inside #atlas's stacking context, so its z-index cannot
   clear a header painted outside it. A stood-down dock takes no input. */
body[data-hub] .dock__in { opacity: .6; }
/* The header element itself is the one that wins the hit test: it spans the
   full width at top:0 and paints outside #atlas's stacking context, so the
   lifted instrument can never rise above it however high its z-index. Every
   interactive child of the dock is already opacity:0 + pointer-events:none in
   this state, so the whole header takes no input while the City is up. */
body[data-hub] .dock { pointer-events: none; }
/* R1: the recessed world's DOM labels leave with its input ownership — the
   old scale keeps no live chrome under the city */
body[data-hub] .hero__labels { visibility: hidden; }

/* ---------------------------------------------------- §9 SHEETS · MOBILE
   Recomposed, not shrunk: SPATIAL BAND (book + terrain + HUD) above,
   FOLIO sheet below, OPERATION PLATE sheet above that. Same thesis. */
@media (max-width: 1024px) {
  body[data-hub] .hero { isolation: auto; }
  .f2folio, .fnl {
    position: fixed; inset: auto 0 0 0; width: auto; z-index: 40;
    left: 0; right: 0; bottom: 0; top: auto;
    /* R12: the Living Atlas band keeps real presence above the sheets —
       the world is the subject, the sheet is the reading surface.
       BR-06: 42dvh left the band shorter than the readout that sits in it. */
    height: calc(100dvh - var(--sheet-eye, 50dvh));
    transform: translateY(106%); opacity: 1;
    transition: transform 560ms var(--ease-object), visibility 0s linear 560ms;
    -webkit-backdrop-filter: none; backdrop-filter: none;
  }
  body[data-hub] .f2folio { transform: none; transition: transform 640ms var(--ease-object), visibility 0s; }
  .fnl { height: calc(100dvh - var(--sheet-eye-2, 42dvh)); z-index: 41; }
  body[data-hub="detail"] .fnl { transform: none; transition: transform 560ms var(--ease-object), visibility 0s; }

  /* the folio sheet: no cut (the volume stands in the band above), page block on the head */
  .f2folio { --notch-w: 0%; --notch-d: 0px; }
  .folio__paper, .folio__body, .folio__band { clip-path: none; }
  .folio__paper { box-shadow: 0 -30px 70px -18px rgba(2, 3, 8, .85); }
  .folio__block {
    left: 0; right: 0; top: -8px; bottom: auto; height: 8px;
    background: linear-gradient(0deg,
      var(--fo-edge) 0 1px, var(--fo-edge-l) 1px 3px, var(--fo-edge-d) 3px 4px,
      #E2DAC4 4px 6px, rgba(20, 16, 8, .6) 7px 8px);
  }
  .folio__band { position: relative; padding: 12px 18px 0; }
  .folio__body {
    position: relative; inset: auto; display: flex; flex-direction: column;
    padding: 6px 18px 12px; overflow-y: auto; overscroll-behavior: contain;
    min-height: 0; flex: 1;
  }
  .f2folio { display: flex; flex-direction: column; }
  .folio__gut { display: none; }
  .folio__name { font-size: clamp(46px, 13vw, 64px); }
  .folio__gates { white-space: normal; }
  .ops { margin-top: 14px; }
  .ops__list { grid-template-columns: 1fr; }
  .ops__list li + li { border-top: 1px solid var(--fo-hair-2); }
  .ops__list li + li::before { display: none; }
  .op { min-height: 56px; padding: 10px 4px; display: grid; grid-template-columns: 2rem minmax(0, 1fr) 24px auto; align-items: center; gap: .2rem .8rem; }
  .ops__list li + li .op { padding-left: 4px; }
  .op__i { grid-row: 1; }
  .op__t { margin: 0; min-height: 0; grid-column: 2; font-size: 17px; }
  .op__sub { grid-column: 2; margin-top: 2px; min-height: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .op__g { position: static; grid-column: 3; grid-row: 1 / span 2; width: 24px; height: 24px; align-self: center; transform: none; }
  .op__ev { grid-column: 4; grid-row: 1 / span 2; margin: 0; padding: 0; align-self: center; }
  .folio__foot { flex-wrap: wrap; gap: 10px 18px; padding-bottom: 4px; }
  .folio__note { margin-left: 0; white-space: normal; text-align: left; flex: 1 1 100%; order: 3; }

  /* the plate sheet keeps its graphite identity — opaque over the ivory
     folio sheet beneath it, so the two reading surfaces never interleave */
  .fnl {
    top: auto; right: 0; width: auto;
    background:
      radial-gradient(120% 80% at 20% 0%, rgba(255, 250, 235, .05), transparent 55%),
      linear-gradient(168deg, var(--pl-3) 0%, var(--pl) 46%, #121419 100%);
    transform: translateY(106%);
  }
  body[data-hub="detail"] .fnl { transform: none; }
  /* BR-06: the scale control belongs TO the band, not across the seam where
     it meets the reading surface. It used to sit under the folio and be
     invisible; once the band grew, half of it appeared through the join. It is
     parked on the band's own bottom edge instead, which is where an instrument
     that measures the field should be. */
  body[data-hub] #crumb {
    position: fixed; left: 14px; right: 14px; z-index: 41;
    /* the control sits on the band's own foot, which is the TOP of the reading
       surface: the surface's height is 100dvh - sheet-eye, and using sheet-eye
       itself only happened to land right while it was exactly 50dvh. At S2's
       42dvh the same expression put the control 118 px INSIDE the plate, where
       it was drawn behind it -- the scale control simply was not on the phone
       in S2. */
    bottom: calc(100dvh - var(--sheet-eye, 50dvh) + 10px);
    margin: 0; padding: 6px 10px;
    /* an instrument standing ON a live field needs its own ground: at .62/.34
       the stops' measured contrast swung between 2.1:1 and 3.3:1 depending on
       what the terrain was doing underneath them. */
    background: linear-gradient(180deg, rgba(9,11,16,.90), rgba(9,11,16,.78));
    border: 1px solid rgba(214,196,150,.16); border-radius: 3px;
    -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
  }
  body[data-hub="detail"] #crumb { bottom: calc(100dvh - var(--sheet-eye-2, 42dvh) + 10px); }
  /* the instrument's bezels are sized for a 1440 frame; at 390 two of them
     eat the whole control, so the roundels come down and the path scrolls
     rather than truncating a stop the reader needs to reach */
  body[data-hub] #crumb.crumb::before,
  body[data-hub] #crumb.crumb::after { width: 40px; height: 40px; margin-top: -20px; }
  /* Hiding a bezel to buy path width was tried and reverted: the bezels are
     absolutely positioned, so removing one frees no layout at all -- measured,
     the path stayed at 194 px -- and it costs the instrument identity R13
     asks for. The current stop is scrolled into view instead (syncCrumb). */
  body[data-hub] #crumb .crumb__path { overflow-x: auto; scrollbar-width: none; }
  body[data-hub] #crumb .crumb__path::-webkit-scrollbar { display: none; }
  /* every stop has to be reachable AND the current one has to be visible: a
     path that scrolls the reader's own location off the end is worse than a
     smaller one. Compacted until all four fit inside 390. */
  body[data-hub] #crumb { gap: .35rem; font-size: 9px; letter-spacing: .08em; }
  /* Two adjacent stops each expanding their hit area to 44 px INTO a .28rem
     gap simply take it from each other: probed outward with elementFromPoint
     the reachable width came back 42 and 40. The stops are given room instead
     of a bigger promise, and the path already scrolls. */
  body[data-hub] #crumb .crumb__path { gap: .62rem; }
  body[data-hub] #crumb .crumb__path li + li::before { margin-right: .34rem; }
  /* the stops are given the floor as WIDTH rather than as a promise: an
     ::after that expands into a neighbour's expander is taken back by it, and
     the reachable width came back 42 and 40 px when probed outward */
  body[data-hub] #crumb .crumb__path button { padding: .22rem .25rem; position: relative; min-width: 44px; }
  /* the stops are compacted to fit, which took two of them under the 44px
     touch floor by WIDTH while their height was fine.

     THAT EXPANDER WAS PAINTING ITSELF. ::after on a stop is the registration
     dot -- a 5 px disc with a background, a rim and, on the addressed stop, an
     opaque brass fill and a glow. Blowing it up to 44x44 to serve as a hit
     area blew up its PAINT with it, so every stop on the phone was covered by
     a filled ellipse and the addressed one had its own name printed in cream
     on a cream disc: measured 240,228,194 ink over a 222,203,152 fill, which
     is about 1.2:1, and the reader's location was legible as a colour and not
     as a word. It was never a hit-area problem after that; the stops now carry
     the 44 px floor as their own min-width/min-height (above), so the dot goes
     back to being a dot. */
  body[data-hub] #crumb .crumb__back,
  body[data-hub] #crumb #reset { font-size: 9px; letter-spacing: .1em; }
  /* the current stop carries its scope name ("TOKYO · CITY FIELD"), which is
     134px of a 205px path at this width -- it pushed itself off the end of its
     own control. The name is clamped rather than the path truncated, so every
     stop stays reachable and the reader's own location stays visible. */
  body[data-hub] #crumb .crumb__path button[aria-current="location"] {
    /* with the painted expander gone the stop can carry more of its own name:
       the reader's location reads as a WORD again, and the path's own scroll
       (plus syncCrumb keeping the addressed stop in view) still reaches the
       ones that fall off the end */
    max-width: 8.2em; margin-right: .2rem; overflow: hidden; text-overflow: ellipsis;
    white-space: nowrap; display: inline-block; vertical-align: bottom;
  }
  /* the rest of the rail -- the scale cards -- stays where it was, under the
     reading surface: it is 193px tall and parking THAT in the band would put
     it straight through the city readout. Only the control travels. */
  body[data-hub] .rail__row { display: none; }
  .pnl-x, .op, .folio__back, .fnd__next button, a.fnrow { min-height: 44px; }
  body.f2-lock { overflow: hidden; }

  /* the field: marginalia compresses to the sheet line + source line */
  .f2r-marg__sheet { left: 16px; top: 64px; font-size: 8.5px; letter-spacing: .16em; }
  .f2r-marg__datum { display: none; }
  .f2r-marg__op { right: 16px; top: 64px; font-size: 8.5px; }
  .f2r-marg__src { right: 16px; bottom: auto; top: 84px; font-size: 7.5px; letter-spacing: .1em; }
  .hud-plq__sub { display: none; }
  .hud-scale { display: none; }
  .hud-fuji { display: none; }
  .f2r-flatrelief { left: 0; bottom: 30%; }
}

/* ---------------------------------------------------- §10 REDUCED MOTION */
@media (prefers-reduced-motion: reduce) {
  .f2folio, .fnl {
    transition: opacity 180ms linear, visibility 0s linear 180ms; transform: none; opacity: 0;
    animation: none !important;
  }
  body[data-hub] .f2folio, body[data-hub="detail"] .fnl {
    opacity: 1; transition: opacity 180ms linear, visibility 0s;
    animation: none !important;
  }
  .folio__name { clip-path: none; transition: opacity 160ms linear; opacity: 0; }
  body[data-hub] .folio__name { opacity: 1; }
  .folio__crumb, .folio__datum, .folio__gates, .ops__k, .op__i, .op__t, .op__sub, .op__ev,
  .folio__foot, .fnd { transition: opacity 160ms linear !important; transform: none !important; }
  .folio__datum { letter-spacing: .07em; }
  .ops__k::after { transition: none; }
  .f2r-field, .f2r-marg__t, .hud-datum, .hud-gate, .hud-plq,
  .hud-fuji, .hud-scale { transition-duration: 160ms; transition-delay: 0ms !important; }
  .hud-trace { transition: opacity 160ms linear; stroke-dashoffset: 0; }
  .hud-datum__pulse { animation: none; opacity: 0; }
}

/* ====================================================== §11 ATLAS SCALE-CONTROL
   R13 · the descent instrument (Packet B, 04): one dark machined rail —
   compass roundel, plotted stops with luminous registration dots, the
   addressed field in a brass-washed cell, a graduated rule along the foot.
   Semantics and behavior untouched (v2.js); the city stop is injected by
   f2hub.js while the hub is up. */
/* R-C · the rail is MACHINED: a bevelled body with a seam under its lip and
   panel insets between the stops, not a bordered box. The two ends carry
   roundels that overlap the rail the way real instrument bezels do. */
.crumb {
  gap: 0; align-items: stretch; flex-wrap: nowrap; position: relative;
  min-height: 48px;
  border: 1px solid var(--rule-strong);
  border-radius: 3px;
  background:
    linear-gradient(180deg,
      rgba(255, 252, 240, .085) 0 1px,
      rgba(255, 252, 240, .045) 1px 45%,
      rgba(0, 0, 0, .16) 55%,
      rgba(0, 0, 0, .30) 100%);
  box-shadow:
    0 1px 0 rgba(255, 252, 240, .10) inset,
    0 -1px 0 rgba(0, 0, 0, .55) inset,
    0 2px 5px rgba(2, 3, 8, .45);
  /* an instrument body, not a tinted pane: a bright plate sliding under it
     washed FIELD and RESET out (Hero closeout R-02) */
  background-color: #0A0D16;
  /* the roundels hang off both ends */
  margin: 0 34px;
}
/* THE TWO ROUNDELS — bezel, tick dial, needle, luminous core. The BACK end
   carries the compass, the RESET end the return rose; both are the same
   instrument, turned to different work. */
.crumb::before,
.crumb::after {
  content: ""; position: absolute; top: 50%; z-index: 3;
  width: 62px; height: 62px; margin-top: -31px; border-radius: 50%;
  pointer-events: none;
  border: 1px solid rgba(196, 166, 98, .62);
  box-shadow:
    0 0 0 1px rgba(12, 11, 9, .85),
    0 0 0 3px rgba(150, 126, 76, .30),
    0 2px 6px rgba(2, 3, 8, .6);
  background:
    /* the luminous core */
    radial-gradient(circle, rgba(255, 236, 186, .95) 0 1.6px, rgba(255, 226, 160, .35) 2.2px, transparent 3.4px),
    /* the four-point needle — the thing that must read as a compass */
    conic-gradient(from 0deg,
      rgba(246, 228, 178, .95) 0 1.6deg, transparent 1.6deg 88.4deg,
      rgba(198, 178, 130, .62) 88.4deg 91.6deg, transparent 91.6deg 178.4deg,
      rgba(246, 228, 178, .95) 178.4deg 181.6deg, transparent 181.6deg 268.4deg,
      rgba(198, 178, 130, .62) 268.4deg 271.6deg, transparent 271.6deg 358.4deg,
      rgba(246, 228, 178, .95) 358.4deg 360deg),
    /* the tick dial, kept quiet: at full strength the ring read as a sunburst
       and swallowed the needle it is supposed to be graduated for */
    repeating-conic-gradient(from 0deg,
      rgba(206, 184, 134, .30) 0 1deg, transparent 1deg 30deg),
    /* the bezel well */
    radial-gradient(circle,
      rgba(18, 17, 14, .97) 0 21px,
      rgba(44, 40, 32, .96) 21px 25px,
      rgba(14, 13, 11, .98) 25px 31px);
}
.crumb::before { left: -34px; }
.crumb::after  { right: -34px; }

/* the graduated rule — the instrument measures, along its own foot */
.crumb__rule {
  position: absolute; left: 10px; right: 10px; bottom: 3px; height: 7px;
  z-index: 1; pointer-events: none;
  background:
    repeating-linear-gradient(90deg,
      rgba(196, 178, 132, .30) 0 1px, transparent 1px 4px),
    repeating-linear-gradient(90deg,
      rgba(206, 188, 142, .46) 0 1px, transparent 1px 16px),
    repeating-linear-gradient(90deg,
      rgba(224, 206, 158, .70) 0 1px, transparent 1px 64px);
  background-size: 100% 3px, 100% 5px, 100% 7px;
  background-position: 0 100%, 0 100%, 0 100%;
  background-repeat: repeat-x;
}
/* the end buttons clear the roundels that overlap the rail's ends */
.crumb__back, .crumb__reset {
  border: 0; padding: .42rem .8rem .52rem; letter-spacing: .18em;
  color: var(--ink-3); display: inline-flex; align-items: center; gap: .45rem;
}
.crumb__back { padding-left: 32px; }
.crumb__reset { padding-right: 32px; }
.crumb__back { border-right: 1px solid var(--rule-strong); }
.crumb__reset { border-left: 1px solid var(--rule-strong); }
.crumb__reset::before {
  content: ""; width: 9px; height: 9px; flex: none; border-radius: 50%;
  border: 1px solid currentColor;
  background: radial-gradient(circle, currentColor 0 1.2px, transparent 1.6px);
}
.crumb__back:hover, .crumb__reset:hover {
  color: var(--ink); background: rgba(255, 252, 240, .06);
  border-color: var(--rule-strong);
}
/* R14 · Pro Max 2 `touch-spacing`: the stops' hit boxes were measured 1.0 px
   apart at 1440. A separation the rule can see costs nothing here. */
.crumb__path { gap: .5rem; padding: 0 .55rem; align-items: stretch; }
.crumb__path li { display: inline-flex; align-items: center; position: relative; }
/* R-C: the drawn "⊣" tick between stops is retired — the machined seam on
   `li + li` now divides the face, and running both read as clutter */
.crumb__path li + li::before { content: none; }
/* R-C · the etched stop glyph, and the luminous registration dot that plots
   the stop onto the rule below it. Glyphs are masks of currentColor, so they
   take the stop's own state colour and survive v2.js rewriting the label. */
.crumb__path button {
  padding: .42rem .55rem .62rem; border-bottom: 1px solid transparent; position: relative;
  display: inline-flex; align-items: center; gap: .42rem;
  /* a scale detent is a fixed stop on a rail: letting its label wrap made the
     active chip three lines tall and pushed it through the rail's own chrome */
  white-space: nowrap;
}
.crumb__path button::before {
  content: ""; width: 14px; height: 14px; flex: none;
  background: currentColor; opacity: .70;
  -webkit-mask: var(--g) center / contain no-repeat;
          mask: var(--g) center / contain no-repeat;
  transition: opacity 220ms var(--ease);
}
.crumb__path [data-go="world"] {
  --g: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14' fill='none' stroke='black' stroke-width='1'><circle cx='7' cy='7' r='5.4'/><ellipse cx='7' cy='7' rx='2.4' ry='5.4'/><path d='M1.6 7h10.8M2.6 4.2h8.8M2.6 9.8h8.8'/></svg>");
}
.crumb__path [data-go="continent"] {
  --g: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14' fill='black'><circle cx='4' cy='4' r='.9'/><circle cx='7' cy='3.2' r='.9'/><circle cx='10' cy='4.4' r='.9'/><circle cx='3.4' cy='7.2' r='.9'/><circle cx='7' cy='7' r='1.3'/><circle cx='10.6' cy='7.4' r='.9'/><circle cx='4.4' cy='10.2' r='.9'/><circle cx='7.6' cy='10.6' r='.9'/></svg>");
}
.crumb__path [data-go="country"] {
  --g: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14' fill='none' stroke='black' stroke-width='1'><circle cx='7' cy='7' r='5'/><circle cx='7' cy='7' r='1.7'/></svg>");
}
#crumb-city button {
  --g: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14' fill='none' stroke='black' stroke-width='1'><circle cx='7' cy='7' r='4.4'/><circle cx='7' cy='7' r='1.5'/><path d='M7 .8v3M7 10.2v3M.8 7h3M10.2 7h3'/></svg>");
}
.crumb__path button[aria-current="location"]::before,
.crumb__path button:hover::before { opacity: 1; }
/* the panel inset between stops: a seam, the way a machined face is divided */
.crumb__path li + li { border-left: 1px solid rgba(0, 0, 0, .5); box-shadow: 1px 0 0 rgba(255, 252, 240, .05) inset; }
/* every stop carries its registration dot on the rule */
/* R-C · the registration dot sits ON the rule, so it reads as the stop being
   plotted against the scale rather than as a bullet under a word */
.crumb__path button::after {
  content: ""; position: absolute; left: 50%; bottom: 2px; width: 5px; height: 5px;
  margin-left: -2.5px; border-radius: 50%;
  background: rgba(190, 172, 128, .45);
  box-shadow: 0 0 0 1px rgba(10, 9, 7, .85);
  transition: background 220ms var(--ease), box-shadow 220ms var(--ease);
}
/* the addressed stop is marked in the instrument's own brass — the inherited
   underline was the one cool accent left on this surface */
.crumb__path button[aria-current="location"] { color: var(--ink); border-bottom-color: rgba(226, 196, 132, .60); }
.crumb__path button[aria-current="location"]::after {
  background: rgba(242, 220, 166, .98);
  box-shadow: 0 0 0 1px rgba(10, 9, 7, .85), 0 0 8px 1.5px rgba(240, 208, 132, .60);
}
/* the addressed field: a brass-washed cell with the surveyor's reticle */
#crumb-city button {
  color: #F0E4C2; letter-spacing: .16em;
  background: linear-gradient(180deg, rgba(196, 166, 98, .17), rgba(196, 166, 98, .06));
  border: 1px solid rgba(196, 166, 98, .45); border-bottom-color: rgba(196, 166, 98, .45);
  padding: .34rem .6rem .44rem; margin-block: .14rem;
  display: inline-flex; align-items: center; gap: .45rem;
}
#crumb-city button::before {
  content: ""; width: 11px; height: 11px; flex: none; border-radius: 50%;
  border: 1px solid rgba(240, 216, 150, .8);
  background:
    radial-gradient(circle, rgba(240, 216, 150, .95) 0 1px, transparent 1.4px),
    linear-gradient(rgba(240, 216, 150, .6), rgba(240, 216, 150, .6)) center / 100% 1px no-repeat,
    linear-gradient(rgba(240, 216, 150, .6), rgba(240, 216, 150, .6)) center / 1px 100% no-repeat;
}
@media (max-width: 1024px) {
  /* touch targets keep the v2 measure inside the strip — and the end labels
     keep clear of the roundels that overlap the strip's ends (Hero closeout:
     at 800 px the dials covered BACK and RESET) */
  .crumb__back, .crumb__reset { padding: .48rem .85rem; }
  .crumb__back { padding-left: 32px; }
  .crumb__reset { padding-right: 32px; }
}

/* while the City is up, the instrument stands at the top of the world —
   same DOM, same semantics, lifted out of the recessed rail */
@media (min-width: 1025px) {
  body[data-hub] .crumb {
    position: fixed; top: clamp(12px, 1.9vh, 18px); left: 50%; transform: translateX(-50%);
    z-index: 42; pointer-events: auto;
    background: linear-gradient(180deg, #1A1C22, #101216 58%, #0C0E12);
    border-color: rgba(196, 166, 98, .32);
    box-shadow:
      0 1px 0 rgba(255, 248, 226, .07) inset,
      0 -1px 0 rgba(0, 0, 0, .6) inset,
      0 4px 9px rgba(2, 3, 8, .55),
      0 14px 34px -12px rgba(2, 3, 8, .8);
  }
  body[data-hub] .crumb .crumb__back[hidden],
  body[data-hub] .crumb .crumb__reset[hidden] { display: inline-flex; visibility: hidden; }
}

/* the paper speaks its own material family: publication state and stamps
   restate in bronze/ink on the sheet — no cool browser accents on print
   (final Impeccable pass, palette unification) */
.f2folio .ev--pub { color: var(--plot-semantic); border-color: var(--fo-hair); }
.f2folio .ev--none { color: var(--fo-ink-4-semantic); }
.f2folio .ev--sample { color: var(--plot-semantic); border-color: var(--fo-hair); background: none; }
.f2folio .ev--illus { color: var(--fo-ink-4-semantic); border-color: var(--fo-hair); }

/* focus discipline: items carry the site ring on paper and graphite; the
   containers are intentional focus targets, never controls */
.f2folio :focus-visible, .fnl :focus-visible { outline: 2px solid var(--hot); outline-offset: 3px; }
.fnl :focus-visible { outline-color: #E8C989; }
.f2folio:focus, .fnl:focus, .f2folio:focus-visible, .fnl:focus-visible { outline: none; }

/* ====================================================== §12 THE RELEASED LEAF
   H·L — with WebGL on a desktop screen the Folio's paper IS the 3-D released
   leaf (assets/f2r_leaf.js): one complete sheet that visibly leaves the
   opened volume and settles here. The DOM keeps the semantics and the type,
   surrenders its painted stock, and resolves only once the sheet has
   settled. Flat fallback and narrow screens keep the CSS paper above. */
/* While the sheet is IN FLIGHT the 3-D leaf is the only paper — that is the
   Packet C moment and nothing may sit on top of it. */
html[data-leaf="3d"] .folio__paper { opacity: 0; }
/* ONCE SETTLED, the DOM stock stays surrendered. There is ONE paper.

   It used to come back at .93 opacity here, because the rendered sheet fell
   from luma ~230 at the top of the panel to ~126 at the bottom and the D4
   column sat on visibly darker stock than D1. That falloff was chased out of
   the albedo, the post chain and the page background and still survived an
   UNLIT, UNTEXTURED, WHITE material — which should be a mathematical constant
   — so it was recorded as unexplained and compensated for.

   IT IS EXPLAINED. It was `.hero__scrim` (v2.css): a full-viewport DOM
   vignette at z-index 1, painted ABOVE the WebGL canvas, whose bottom band
   inks exactly where the settled sheet lies. It survived an unlit white
   material because it was never on the material. Every overlay probe missed it
   because it is `pointer-events: none` and `elementsFromPoint` skips those.
   Proof, leaf solo on a white unlit material: scrim on, luma down the sheet
   630:230 720:190 800:133 835:124; scrim off, 230 at every one of them.

   So the compensation is withdrawn and the cause is treated instead: the
   scrim is windowed to the paper's own footprint below. The DOM keeps the
   semantics, the type and the focus targets, and surrenders its stock for
   good. What the reader sees is the sheet that left the volume. */
html[data-leaf="3d"][data-leaf-at="settled"] .folio__paper { opacity: 0; }

/* BR-02 · THE SCRIM'S WINDOW.
   Bounded twice, and in this order: by STATE, to the lifecycle in which a
   physical paper is on screen at all; and by SPACE, to that paper's own
   footprint, published as --fol-* by f2r_leaf.js from the same rect the sheet
   registers its settle pose to. Everything else the vignette does — the
   terrain foreground, the volume's grounding, the instrument's lower depth,
   the cinematic bottom of the frame — is untouched, because everything else
   is outside the window.

   The gate is a LIFECYCLE gate, not a desktop gate: the rule below keys off
   the paper's own state, so it applies at whatever viewport that state exists
   at, and stands down wherever the DOM stock is the paper instead.

   Two mask layers, unioned (the default `add`): the first keeps the vignette
   everywhere outside the footprint's columns, the second everywhere outside
   its rows. Their union is opaque everywhere except where BOTH are clear —
   the footprint itself. A mask on the element covers `::after` with it, so
   the deeper-in vignette needs no separate rule and no gradient is rewritten. */
html[data-leaf="3d"][data-leaf-at="settled"] body[data-hub] .hero__scrim,
html[data-leaf="3d"][data-leaf-at="settled"] .hero__scrim {
  --fol-fade: 26px;
  --fol-bite: 10px;
  -webkit-mask-image:
    linear-gradient(to right, #000 0,
      #000 calc(var(--fol-x) - var(--fol-fade)),
      transparent calc(var(--fol-x) + var(--fol-bite)),
      transparent calc(var(--fol-x) + var(--fol-w) - var(--fol-bite)),
      #000 calc(var(--fol-x) + var(--fol-w) + var(--fol-fade)), #000 100%),
    linear-gradient(to bottom, #000 0,
      #000 calc(var(--fol-y) - var(--fol-fade)),
      transparent calc(var(--fol-y) + var(--fol-bite)),
      transparent calc(var(--fol-y) + var(--fol-h) - var(--fol-bite)),
      #000 calc(var(--fol-y) + var(--fol-h) + var(--fol-fade)), #000 100%);
  mask-image:
    linear-gradient(to right, #000 0,
      #000 calc(var(--fol-x) - var(--fol-fade)),
      transparent calc(var(--fol-x) + var(--fol-bite)),
      transparent calc(var(--fol-x) + var(--fol-w) - var(--fol-bite)),
      #000 calc(var(--fol-x) + var(--fol-w) + var(--fol-fade)), #000 100%),
    linear-gradient(to bottom, #000 0,
      #000 calc(var(--fol-y) - var(--fol-fade)),
      transparent calc(var(--fol-y) + var(--fol-bite)),
      transparent calc(var(--fol-y) + var(--fol-h) - var(--fol-bite)),
      #000 calc(var(--fol-y) + var(--fol-h) + var(--fol-fade)), #000 100%);
}
html[data-leaf="3d"] .f2folio {
  transform: none; animation: none;
  transition: opacity 140ms var(--ease), visibility 0s linear 140ms;
}
html[data-leaf="3d"] body[data-hub] .f2folio {
  animation: none; transform: none;
  transition: opacity 140ms var(--ease), visibility 0s;
}
/* R07 · the essential index is readable AS the sheet settles (~3.0 s):
   identity and selection labels land with the paper, never seconds after.
   Only the decorative micro-detail (hairlines, foot) trails the landing. */
html[data-leaf="3d"] .folio__band { opacity: 0; transition: opacity 420ms var(--ease); }
html[data-leaf="3d"] body[data-hub] .folio__band { opacity: 1; transition-delay: 2820ms; }
html[data-leaf="3d"] body[data-hub] .folio__name { transition-delay: 2780ms; }
html[data-leaf="3d"] body[data-hub] .folio__datum { transition-delay: 2980ms; }
html[data-leaf="3d"] body[data-hub] .folio__gates { transition-delay: 3120ms; }
html[data-leaf="3d"] body[data-hub] .ops__k { transition-delay: 2880ms; }
html[data-leaf="3d"] body[data-hub] .ops__k::after { transition-delay: 2960ms; }
html[data-leaf="3d"] body[data-hub] .ops__list li + li::before { transition-delay: 3300ms; }
html[data-leaf="3d"] body[data-hub] .ops__list li:nth-child(1) .op__i { transition-delay: 2900ms; }
html[data-leaf="3d"] body[data-hub] .ops__list li:nth-child(2) .op__i { transition-delay: 2960ms; }
html[data-leaf="3d"] body[data-hub] .ops__list li:nth-child(3) .op__i { transition-delay: 3020ms; }
html[data-leaf="3d"] body[data-hub] .ops__list li:nth-child(4) .op__i { transition-delay: 3080ms; }
html[data-leaf="3d"] body[data-hub] .ops__list li:nth-child(1) .op__g { transition-delay: 2950ms; }
html[data-leaf="3d"] body[data-hub] .ops__list li:nth-child(2) .op__g { transition-delay: 3010ms; }
html[data-leaf="3d"] body[data-hub] .ops__list li:nth-child(3) .op__g { transition-delay: 3070ms; }
html[data-leaf="3d"] body[data-hub] .ops__list li:nth-child(4) .op__g { transition-delay: 3130ms; }
html[data-leaf="3d"] body[data-hub] .ops__list li:nth-child(1) .op__t { transition-delay: 2990ms; }
html[data-leaf="3d"] body[data-hub] .ops__list li:nth-child(2) .op__t { transition-delay: 3050ms; }
html[data-leaf="3d"] body[data-hub] .ops__list li:nth-child(3) .op__t { transition-delay: 3110ms; }
html[data-leaf="3d"] body[data-hub] .ops__list li:nth-child(4) .op__t { transition-delay: 3170ms; }
html[data-leaf="3d"] body[data-hub] .ops__list li:nth-child(1) .op__sub { transition-delay: 3090ms; }
html[data-leaf="3d"] body[data-hub] .ops__list li:nth-child(2) .op__sub { transition-delay: 3150ms; }
html[data-leaf="3d"] body[data-hub] .ops__list li:nth-child(3) .op__sub { transition-delay: 3210ms; }
html[data-leaf="3d"] body[data-hub] .ops__list li:nth-child(4) .op__sub { transition-delay: 3270ms; }
html[data-leaf="3d"] body[data-hub] .ops__list li:nth-child(1) .op__ev { transition-delay: 3200ms; }
html[data-leaf="3d"] body[data-hub] .ops__list li:nth-child(2) .op__ev { transition-delay: 3260ms; }
html[data-leaf="3d"] body[data-hub] .ops__list li:nth-child(3) .op__ev { transition-delay: 3320ms; }
html[data-leaf="3d"] body[data-hub] .ops__list li:nth-child(4) .op__ev { transition-delay: 3380ms; }
html[data-leaf="3d"] body[data-hub] .folio__foot { transition-delay: 3460ms; }
/* once live, answers stay immediate */
html[data-leaf="3d"] body[data-hub] .f2folio.is-live .op__i,
html[data-leaf="3d"] body[data-hub] .f2folio.is-live .op__g,
html[data-leaf="3d"] body[data-hub] .f2folio.is-live .op__t,
html[data-leaf="3d"] body[data-hub] .f2folio.is-live .op__sub,
html[data-leaf="3d"] body[data-hub] .f2folio.is-live .op__ev,
html[data-leaf="3d"] body[data-hub] .f2folio.is-live .folio__datum,
html[data-leaf="3d"] body[data-hub] .f2folio.is-live .folio__gates,
html[data-leaf="3d"] body[data-hub] .f2folio.is-live .folio__name,
html[data-leaf="3d"] body[data-hub] .f2folio.is-live .ops__k,
html[data-leaf="3d"] body[data-hub] .f2folio.is-live .ops__k::after,
html[data-leaf="3d"] body[data-hub] .f2folio.is-live .folio__band,
html[data-leaf="3d"] body[data-hub] .f2folio.is-live .folio__foot { transition-delay: 0ms; }

/* the instrument's plotted lines never print across the settled sheet — the
   svg layer fades out above the folio zone (the HTML marginalia, including
   the GSI attribution line, lives outside this mask and stays printed) */
html[data-leaf="3d"] body[data-hub] .f2r-hud {
  -webkit-mask-image: linear-gradient(180deg, #000 0, #000 calc(100% - 318px), transparent calc(100% - 250px));
          mask-image: linear-gradient(180deg, #000 0, #000 calc(100% - 318px), transparent calc(100% - 250px));
}


/* the descent instrument prints the true width of the addressed field —
   computed from the live camera, updated by hero3d.js (H·N1) */
.crumb__scale {
  display: inline-flex; align-items: center; gap: .5rem;
  padding: .42rem .7rem; border-left: 1px solid var(--rule-strong);
  font-family: var(--font-data); font-size: var(--t-micro);
  letter-spacing: .14em; color: var(--ink-3);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.crumb__scale::before {
  content: ""; width: 16px; height: 7px; flex: none; opacity: .8;
  background:
    linear-gradient(currentColor, currentColor) 0 50% / 100% 1px no-repeat,
    linear-gradient(currentColor, currentColor) 0 0 / 1px 100% no-repeat,
    linear-gradient(currentColor, currentColor) 100% 0 / 1px 100% no-repeat;
}
@media (max-width: 760px) { .crumb__scale { display: none; } }
/* Hero visual repair · on a phone the scale strip at COUNTRY carried five
   stops and ran RESET off the right edge (438 px in a 390 px frame). RESET
   is the WORLD stop's own act, so the phone keeps WORLD and lets RESET go;
   the stops close up to fit the frame. */
@media (max-width: 560px) {
  .crumb .crumb__reset { display: none; }
  .crumb { letter-spacing: .06em; }
  .crumb__back { padding-right: .55rem; }
  .crumb__path { padding-right: 30px; }             /* room under the end roundel */
  .crumb__path button { padding-inline: .34rem; }
}
/* the flat atlas has no live field to measure */
[data-hero="flat"] .crumb__scale, .no-js .crumb__scale { display: none; }

/* depth-aware stand-down: a printed HUD mark behind the opened volume */
.f2r-hud .is-occl { opacity: .12 !important; transition: opacity 300ms var(--ease); }

/* ==================================================== §13 OPERATIONS FOOTER
   R-D · Packet D's base line. The hero composition previously ran off the
   bottom of the frame with nothing to close it, which is a large part of why
   the whole picture read as unresolved. This is a slim instrument band:
   label over value, hairline-divided cells, live truth only.

   It appears with the city hub and stands down with it, so it never competes
   with the planetary view's own footer. Desktop only — the phone sheet has
   its own composition and no room for a six-cell band. */
.opsbar {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 6;
  display: grid;
  /* the attribution is the longest cell and must not wrap — a two-line band
     grew tall enough to collide with the folio's own foot line */
  grid-template-columns: minmax(168px, auto) .80fr .72fr .92fr .78fr 1.62fr;
  border-top: 1px solid rgba(196, 166, 98, .30);
  background:
    linear-gradient(180deg, rgba(255, 250, 235, .045), rgba(6, 7, 10, .58) 60%, rgba(4, 5, 8, .72));
  -webkit-backdrop-filter: blur(5px) saturate(.94);
          backdrop-filter: blur(5px) saturate(.94);
  box-shadow: 0 1px 0 rgba(255, 252, 240, .07) inset, 0 -14px 30px -12px rgba(2, 3, 8, .7);
  opacity: 0; visibility: hidden; transform: translateY(10px);
  transition: opacity 460ms var(--ease), transform 560ms var(--ease-object),
              visibility 0s linear 560ms;
  pointer-events: none;
}
body[data-hub] .opsbar {
  opacity: 1; visibility: visible; transform: none;
  transition: opacity 460ms var(--ease) 520ms, transform 560ms var(--ease-object) 520ms,
              visibility 0s;
}
.opsbar__cell {
  display: flex; flex-direction: column; gap: .26rem; min-width: 0;
  padding: .58rem clamp(12px, 1.5vw, 26px) .62rem;
  border-left: 1px solid rgba(196, 178, 132, .16);
}
.opsbar__cell:first-child { border-left: 0; }
.opsbar__k {
  font: 500 var(--t-micro, 10px)/1 var(--font-data, ui-monospace, monospace);
  letter-spacing: .26em; color: rgba(190, 172, 130, .58);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.opsbar__v {
  font: 500 calc(var(--t-micro, 10px) * 1.18)/1.15 var(--font-data, ui-monospace, monospace);
  letter-spacing: .13em; color: rgba(228, 214, 182, .92);
  font-variant-numeric: tabular-nums;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* the wordmark cell is the band's own registration, so it reads as the
   instrument speaking rather than as one more readout */
.opsbar__cell--mark { padding-right: clamp(14px, 1.2vw, 20px); }
.opsbar__cell--mark .opsbar__k { color: rgba(226, 196, 132, .72); letter-spacing: .16em; }
.opsbar__cell--mark .opsbar__v {
  font-family: var(--font-display, serif); font-size: calc(var(--t-micro, 10px) * 1.55);
  letter-spacing: .22em; color: #EBD3A0;
}
/* the source cell quotes its attribution in full and never truncates it out
   of existence — it is a licence condition, not a caption. It is set smaller
   and tighter so the whole name fits on the band's single line. */
.opsbar__cell--src .opsbar__v {
  font-size: calc(var(--t-micro, 10px) * 1.02);
  letter-spacing: .035em; text-overflow: clip;
}
@media (max-width: 1024px) { .opsbar { display: none; } }
@media (prefers-reduced-motion: reduce) {
  .opsbar { transition: opacity 160ms linear !important; transform: none !important; }
}

/* ================================================ §14 HIT TARGETS (R14/UI-UX)
   Audited with the UI/UX Pro Max touch rules: focus visibility passed on every
   interactive element and tab order already matched visual order, but a set of
   controls sat under the 44px minimum — the scale detents at 32–35px, the two
   panel closes at 30px, and .folio__back at 165×17. The last one matters most:
   it is now the interior-reveal trigger as well as the way back, so it was a
   17px-tall target carrying two jobs.

   The fix extends the HIT AREA without moving anything visually, which is what
   the rule asks for: the drawn control stays exactly where it was. */
.crumb__path button,
.crumb__back,
.crumb__reset { min-height: 44px; }
#hub-close, #fn-close { min-height: 44px; }
.folio__back {
  position: relative;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}
/* the reveal trigger reads as one: a hairline that lights with the gesture */
.folio__back::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 11px; height: 1px;
  background: currentColor; opacity: .28;
  transition: opacity 220ms var(--ease);
}
.folio__back:hover::after, .folio__back:focus-visible::after { opacity: .7; }
.fnd__next button { min-height: 44px; }

/* ===========================================================================
   BR-06 · 390 x 844 — THE SPATIAL WORLD IS THE VIEWPORT, NOT A STRIP

   This did not fail on offsets, it failed on STRUCTURE, and the structure was
   only visible from the running page. Measured at 390 x 844:

     #atlas.hero      970 px tall   (its own stacked DOM column, not the frame)
     window.scrollY   489 px        (frameSheet scrolls the stage into view)
     #stage           y -50 .. 321  (its top is off the screen)
     #readout         y 128 .. 321  (193 px of panel ON the stage)
     visible band     y   0 .. 422

   So the WebGL canvas was 970 px tall inside an 844 px frame, the authored
   composition sat around the canvas centre -- which the scroll had put at
   y ~ -4, off the top of the screen -- and a 193 px readout panel was laid
   over what was left. No plate offset can repair that: the stage the scene is
   composed in is not the stage the reader is looking at.

   So while the city hub is up on a narrow screen, the hero IS the frame. The
   field runs the full height behind the reading surface exactly as it does on
   the desktop, the sheet lies ON it rather than starting a document under it,
   and the readout stops being a panel and becomes what it is on every other
   surface in this product: marginalia, printed on the field.
   =========================================================================== */
@media (max-width: 1024px) {
  body[data-hub] #atlas.hero {
    position: fixed; inset: 0; height: 100dvh; min-height: 0;
    padding: 0; margin: 0; overflow: hidden; z-index: 1;
  }
  body[data-hub] #atlas .hero__in {
    display: block; height: 100%; max-width: none;
    padding: 0; margin: 0; gap: 0;
  }
  /* the DOM argument belongs to the page the reader arrived on, not to the
     hub: it was already stood down to opacity 0, but it was still occupying
     the column that made the hero 970 px tall */
  body[data-hub] #atlas .hero__head,
  body[data-hub] #atlas .search,
  body[data-hub] #atlas .finder__k,
  body[data-hub] #atlas .finder__now,
  body[data-hub] #atlas .rail__row,
  body[data-hub] #atlas .colophon { display: none; }
  /* the brand bar belongs to the page the reader arrived on. In the hub it is
     already inert (pointer-events: none, so the scale control can be hit
     through it) and on the desktop it is scrolled away; pinning the hero to
     the frame is what brought it back into the picture. */
  body[data-hub] .dock { opacity: 0; }
  /* two marginalia lines set at opposite ends of a 1440 frame meet in the
     middle of a 390 one. They are stacked instead, at the head of the band. */
  body[data-hub] .f2r-marg__sheet { left: 16px; top: 56px; max-width: 358px; overflow: hidden; text-overflow: ellipsis; }
  body[data-hub] .f2r-marg__op { left: 16px; right: auto; top: 70px; }
  /* the S2 state prints its own pair of lines at the band's foot; at 390 they
     were set from opposite margins and met in the middle, with the left one
     running off the frame */
  body[data-hub="detail"] .f2r-marg__sheet,
  body[data-hub="detail"] .f2r-marg__op { max-width: 358px; white-space: nowrap;
    overflow: hidden; text-overflow: ellipsis; }
  /* S2's kicker is set directly on top of the plate, which on a phone is also
     where the scale control stands. It ran through the control and off the
     left edge of the frame; it moves clear of both and keeps its margins. */
  .fnl__kick {
    left: 16px; right: 16px; bottom: calc(100% + 60px); padding: 0;
    gap: .5rem; letter-spacing: .14em; font-size: 9px;
  }
  .fnl__kick-a, .fnl__kick-b { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
  .fnl__kick-r { display: none; }
  body[data-hub] #atlas .hero__stage {
    position: absolute; inset: 0; height: auto; min-height: 0; margin: 0;
  }

  /* THE CITY'S FACTS BELONG TO THE READING SURFACE.
     The console's readout used to be printed as a 193 px card across the
     middle of the band with the volume standing behind it -- the panel read
     the contract rules out. It is not moved, it is dropped: the desktop hub
     does not show it either, because the FOLIO carries the city's identity.
     The reason the phone needed it was a clipping bug, not a missing surface:
     .folio__id is `overflow: hidden` with a min-height meant for the desktop
     grid, and in the phone's flex column it collapsed to 52 px and cut the
     coordinates, the clock and the gateways off the sheet. Measured: name
     488-531, datum 537-574, gateways 579-593, box ending at 536.
     One reading surface, and it carries what it says it carries. */
  body[data-hub] #atlas .finder { display: none; }
  /* `flex: 0 1 auto` in the phone's scrolling column let this shrink below its
     own content -- 52 px against 94 px of content -- which is what cut the
     coordinates and the gateways off. It keeps its height and the column
     scrolls, which is what the column is for. */
  .f2folio .folio__id { overflow: visible; min-height: 0; flex: none; }
  /* the operations list is the sheet's subject and was being clipped by the
     same desktop-grid rule: D2, D3 and D4 simply were not on the phone */
  .f2folio .ops { overflow: visible; flex: none; }
  .f2folio .folio__datum { margin-top: 6px; }
  .f2folio .folio__gates { overflow: visible; white-space: normal; margin-top: 4px; }
}
/* ^ the narrow block ends here. It had been left OPEN by an edit earlier in this
   repair -- 461 braces against 460 -- so every rule appended after it was
   silently swallowed into `@media (max-width: 1024px)` and never applied on the
   desktop. That is how the MAP BOOK's own hit region came to be laid out as a
   static flex child at (0, 738) while its inline left/top said (217, 267). */


/* ---------------------------------------------------------------------------
   THE VOLUME IS ITS OWN AFFORDANCE (interior gesture).
   The hit region tracks the MAP BOOK's real screen rect, published by
   FOW_HERO._.bookRect() once per rendered frame. It draws nothing: the volume
   is already there and already reads as an object. It exists so that pointing
   at the book, or tabbing to it, does what pointing at "BACK TO THE MAP BOOK"
   does, and so that a CLICK can latch the interior open.
   --------------------------------------------------------------------------- */
.mapbook-hit {
  position: absolute; z-index: 7; margin: 0; padding: 0;
  background: none; border: 0; cursor: pointer; color: inherit;
  -webkit-appearance: none; appearance: none;
}
.mapbook-hit[hidden] { display: none; }
.mapbook-hit:focus-visible {
  outline: 2px solid var(--meridian, #C9B278);
  outline-offset: 6px; border-radius: 2px;
}
body[data-hub="detail"] .mapbook-hit { display: none; }
@media (max-width: 1024px) { .mapbook-hit { display: none; } }
