/* ============================================================
   SERVICE 04 — SALES TAX COMPLIANCE
   Page-specific styles only. Everything structural lives in
   css/main.css; this file adds the page's spine, its paired
   panels, its signature device (three divergent state rulebooks
   that the scroll standardises into one system) and the shelf
   of four rulebook volumes that carries the questions.
   ============================================================ */

/* ---------- you are here ---------- */
.nav-links a.is-here { color: var(--text); }
.nav-links a.is-here::after { transform: scaleX(1); opacity: 0.6; }
.mobile-links a.is-here { color: var(--text); }
.mobile-links a.is-here .mono { color: var(--pink-soft); }
.footer-col a.is-here { color: var(--purple-soft); }
.footer-col a.is-here::before {
  content: "";
  display: inline-block;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--purple);
  margin-right: 8px;
  vertical-align: middle;
  box-shadow: 0 0 10px rgba(91, 76, 255, 0.8);
}

/* ---------- the page spine: every section mark reads the same ---------- */
.sec-h2 {
  display: flex; align-items: center; gap: 14px;
  font-size: 11.5px; letter-spacing: 0.22em;
  text-transform: uppercase;
  font-weight: 400;
  color: var(--faint);
  margin-bottom: clamp(30px, 5vh, 56px);
}
.sec-h2::before {
  content: "";
  flex: none;
  width: 30px; height: 1px;
  background: linear-gradient(90deg, var(--purple), transparent);
}

/* ============================================================
   SCENE 01 — the service title
   ============================================================ */
#open { height: 190vh; }
.open-block { position: relative; z-index: 2; max-width: 1060px; }
@media (prefers-reduced-motion: no-preference) {
  .js .open-block {
    opacity: var(--blockop, 1);
    transform: translateY(var(--blocky, 0px));
  }
}
.open-h1 {
  font-size: clamp(33px, 5.1vw, 72px);
  margin: 0;
}
.open-lede {
  margin: clamp(28px, 4.4vh, 54px) auto 0;
  max-width: 60ch;
}
@media (prefers-reduced-motion: no-preference) {
  .js .open-lede {
    opacity: var(--ledeop, 0);
    transform: translateY(calc((1 - var(--ledeop, 0)) * 20px));
  }
}

/* the three states, named once before the device names them again */
.open-strip {
  position: absolute;
  left: 50%; bottom: clamp(24px, 5vh, 58px);
  z-index: 2;
  display: flex; gap: 10px;
  transform: translateX(-50%);
}
@media (prefers-reduced-motion: no-preference) {
  .js .open-strip {
    opacity: var(--stripop, 0);
    transform: translateX(-50%) translateY(calc((1 - var(--stripop, 0)) * 16px));
  }
}
.ost {
  display: inline-flex; flex-direction: column; align-items: center; gap: 9px;
  padding: 11px 17px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface);
  backdrop-filter: blur(12px) saturate(160%);
  -webkit-backdrop-filter: blur(12px) saturate(160%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);
  font-size: 11px; letter-spacing: 0.16em;
  color: var(--mist);
}
.ost b { font-weight: 400; }
.ost i {
  display: block; width: 28px; height: 2px; border-radius: 2px;
  background: var(--pink);
  opacity: 0.75;
}
.ost-more { color: var(--faint); }
.ost-more i { background: var(--line-strong); opacity: 1; }

/* ============================================================
   REST — the problem, set unhurried
   ============================================================ */
.read-col { max-width: 62ch; }
.read-lead {
  font-size: clamp(19px, 2.05vw, 27px);
  line-height: 1.56;
  letter-spacing: -0.016em;
  color: var(--text);
  max-width: 44ch;
}
.read-lead + .body-lg { margin-top: clamp(28px, 4.2vh, 46px); }

/* ============================================================
   REST — what we do / what changes for you (rhymed panels)
   ============================================================ */
.pair-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(20px, 2.6vw, 34px);
}
.panel {
  position: relative;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  backdrop-filter: blur(14px) saturate(160%);
  -webkit-backdrop-filter: blur(14px) saturate(160%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.09);
  padding: clamp(28px, 3.4vw, 48px);
  overflow: hidden;
}
/* keep the reveal timing but give the glass its own hover response */
.js .panel.reveal {
  transition: opacity 0.75s cubic-bezier(0.22, 0.6, 0.2, 1),
              transform 0.75s cubic-bezier(0.22, 0.6, 0.2, 1),
              border-color 0.4s ease, box-shadow 0.4s ease;
}
.panel-rule {
  position: absolute; left: 0; top: 0; bottom: 0;
  width: 2px;
}
.panel-do .panel-rule {
  background: linear-gradient(180deg, transparent, var(--purple) 24%, var(--purple) 76%, transparent);
}
.panel-change .panel-rule {
  background: linear-gradient(180deg, transparent, var(--pink) 24%, var(--pink) 76%, transparent);
}
.panel-h2 { margin-bottom: var(--s3); }
.panel-body {
  font-size: clamp(16px, 1.45vw, 18.5px);
  line-height: 1.8;
  color: var(--mist);
}
.panel-lift {
  color: var(--pink);
  text-shadow: 0 0 26px rgba(255, 77, 128, 0.3);
}
.panel-do:hover {
  border-color: rgba(148, 138, 255, 0.45);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.09), 0 20px 52px rgba(0, 0, 0, 0.45), 0 0 30px rgba(91, 76, 255, 0.12);
}
.panel-change:hover {
  border-color: rgba(255, 125, 161, 0.42);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.09), 0 20px 52px rgba(0, 0, 0, 0.45), 0 0 30px rgba(255, 77, 128, 0.11);
}

/* ============================================================
   SCENE 02 — THE THREE RULEBOOKS
   Michigan, Ohio and Indiana arrive as three separate books,
   tilted, offset, each keeping its rows on its own grid. The
   scroll squares them up, matches the rows, and closes one
   frame around all three: one system across locations.
   ============================================================ */
#standardise { height: 340vh; }
.rb-stage {
  gap: clamp(18px, 3.2vh, 40px);
  justify-content: center;
}
/* THE UNSTANDARDISED STATE, ON EVERY WIDTH.
   This was gated to min-width:981px, so below it every var(--std, 1) fell
   back to the FINISHED value: three books already squared up, already
   sharing one row pattern, under a heading that reads THREE STATES · THREE
   RULEBOOKS — and .rb-t0/.rb-t1/.rb-t2 below are opacity: calc(1 - --std),
   which made the MI, OH and IN filing rails invisible outright. The whole
   argument of the scene was missing on a phone. js/service-sales-tax.js now
   scrubs --std on narrow off the section's travel through the viewport, so a
   resting 0 is safe here. Both fallbacks still resolve it to 1 and are
   untouched: .no-js .rb-stage and the reduced-motion block at the foot of
   this file (main.js does not run scenes at all under reduced motion). */
@media (prefers-reduced-motion: no-preference) {
  .js .rb-stage { --std: 0; }
}

.rb-head { position: relative; z-index: 2; text-align: center; }
.rb-head .chapter-line { margin-bottom: clamp(14px, 2.2vh, 26px); }
.rb-h2 {
  font-size: clamp(15px, 1.9vw, 25px);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 400;
  color: var(--text);
}
.rb-h2 i {
  font-style: normal;
  color: var(--purple-soft);
  padding: 0 4px;
}

.rb-deck-wrap {
  position: relative; z-index: 2;
  width: min(1060px, 100%);
}
.rb-frame {
  position: absolute; inset: -16px;
  border: 1px solid rgba(148, 138, 255, 0.5);
  border-radius: 20px;
  box-shadow: 0 0 46px rgba(91, 76, 255, 0.14), inset 0 0 44px rgba(91, 76, 255, 0.05);
  opacity: var(--std, 1);
  pointer-events: none;
}
.rb-frame-label {
  position: absolute; left: 24px; top: -8px;
  padding: 0 10px;
  background: var(--bg);
  font-size: 9.5px; letter-spacing: 0.22em;
  color: var(--purple-soft);
  white-space: nowrap;
  max-width: calc(100% - 48px);
  overflow: hidden;
}
.rb-deck {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(12px, 1.8vw, 24px);
}
.rb {
  position: relative;
  border: 1px solid;
  border-color: color-mix(in srgb, var(--line-strong), rgba(148, 138, 255, 0.55) calc(var(--std, 1) * 100%));
  border-radius: 14px;
  background: rgba(16, 16, 23, 0.66);
  backdrop-filter: blur(12px) saturate(160%);
  -webkit-backdrop-filter: blur(12px) saturate(160%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.07), 0 18px 44px rgba(0, 0, 0, 0.45);
  padding: 16px 18px 20px;
  /* --spread scales the scatter without touching the per-card --dx/--dy set
     inline on each rulebook. Now that the scrub runs on phones too, the
     third card's +24px pushed 3px past a 379px viewport and gave the whole
     document a horizontal scrollbar; the mobile block below pulls the
     spread in rather than overriding three inline properties. */
  transform:
    translate(calc(var(--dx) * var(--spread, 1) * (1 - var(--std, 1))),
              calc(var(--dy) * var(--spread, 1) * (1 - var(--std, 1))))
    rotate(calc(var(--rot) * var(--spread, 1) * (1 - var(--std, 1))));
}
.rb-top {
  display: flex; align-items: baseline; gap: 10px;
  border-bottom: 1px solid var(--line);
  padding-bottom: 11px;
}
.rb-code {
  font-size: 13px; letter-spacing: 0.08em;
  color: color-mix(in srgb, var(--pink-soft), var(--purple-soft) calc(var(--std, 1) * 100%));
}
.rb-name { font-size: 9.5px; letter-spacing: 0.2em; color: var(--faint); }
.rb-fact {
  display: inline-block;
  margin: 13px 0 15px;
  padding: 6px 11px;
  border: 1px solid;
  border-color: color-mix(in srgb, rgba(255, 77, 128, 0.42), rgba(148, 138, 255, 0.45) calc(var(--std, 1) * 100%));
  border-radius: 100px;
  font-size: 9.5px; letter-spacing: 0.13em; line-height: 1.4;
  color: color-mix(in srgb, var(--pink-soft), var(--purple-soft) calc(var(--std, 1) * 100%));
}
.rb-fact b { font-weight: 500; color: var(--text); }
.rb-rows {
  display: flex; flex-direction: column; gap: 9px;
  transform: translateY(calc(var(--drift) * (1 - var(--std, 1))));
}
.rb-bar {
  display: block;
  height: 5px; border-radius: 3px;
  background: rgba(255, 255, 255, 0.13);
  width: calc(var(--w0) + (var(--w1) - var(--w0)) * var(--std, 1));
}

/* three filing calendars that converge onto one */
.rb-rail {
  position: relative; z-index: 2;
  width: min(1060px, 100%);
  height: 96px;
}
.rb-track {
  position: absolute; left: 0; right: 0; top: 50%;
  margin-top: -4px;
  display: flex; align-items: center; gap: 6px;
}
.rb-track b {
  flex: none;
  width: 36px;
  font-weight: 400;
  font-size: 9.5px; letter-spacing: 0.18em;
  color: var(--faint);
}
.rb-track i {
  flex: 1;
  height: 7px; border-radius: 2px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.05);
}
.rb-track i.on {
  background: rgba(255, 125, 161, 0.5);
  border-color: rgba(255, 77, 128, 0.55);
  box-shadow: 0 0 10px rgba(255, 77, 128, 0.3);
}
.rb-t0, .rb-t1, .rb-t2 {
  transform: translateY(calc(var(--off) * (1 - var(--std, 1))));
  opacity: calc(1 - var(--std, 1));
}
.rb-one { opacity: var(--std, 1); }
.rb-one b { color: var(--purple-soft); }
.rb-one i.on {
  background: rgba(148, 138, 255, 0.5);
  border-color: rgba(148, 138, 255, 0.6);
  box-shadow: 0 0 10px rgba(91, 76, 255, 0.45);
}

.rb-meter {
  position: relative; z-index: 2;
  display: flex; align-items: center; gap: 12px;
  font-size: 10.5px; letter-spacing: 0.2em;
  color: var(--faint);
}
.rb-meter-val {
  font-size: 11px; letter-spacing: 0.06em;
  color: var(--purple-soft);
}
.rb-meter em {
  font-style: normal;
  font-size: 13px; letter-spacing: 0.06em;
  color: var(--purple-soft);
}
.rb-meter-track {
  width: min(280px, 42vw); height: 1px;
  background: var(--line);
  position: relative;
}
.rb-meter-track i {
  position: absolute; inset: 0;
  background: linear-gradient(90deg, var(--pink), var(--purple));
  box-shadow: 0 0 12px rgba(91, 76, 255, 0.6);
  transform-origin: 0 50%;
  transform: scaleX(var(--std, 1));
}

/* ============================================================
   REST — scope of work. The length is the argument.
   ============================================================ */
.scope { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); }
.scope-item {
  display: grid;
  grid-template-columns: 58px 1fr 20px;
  gap: var(--s2);
  align-items: center;
  border-bottom: 1px solid var(--line);
  padding: clamp(16px, 2.4vh, 26px) 0;
}
.js .scope-item.reveal {
  transition: opacity 0.75s cubic-bezier(0.22, 0.6, 0.2, 1),
              transform 0.75s cubic-bezier(0.22, 0.6, 0.2, 1),
              padding-left 0.4s cubic-bezier(0.3, 0.7, 0.3, 1);
}
.scope-item:hover { padding-left: 12px; }
.scope-n { font-size: 11.5px; letter-spacing: 0.12em; color: var(--purple-soft); }
.scope-t {
  font-size: clamp(16px, 1.5vw, 19.5px);
  line-height: 1.5;
  color: var(--text);
}
.scope-tick {
  position: relative;
  width: 18px; height: 18px;
  border-radius: 50%;
  border: 1px solid var(--line-strong);
  justify-self: end;
}
.scope-tick::after {
  content: "";
  position: absolute; left: 4px; top: 5px;
  width: 7px; height: 3px;
  border-left: 1.5px solid var(--purple-soft);
  border-bottom: 1.5px solid var(--purple-soft);
  transform: rotate(-45deg) scale(0);
  transform-origin: 50% 50%;
  transition: transform 0.5s cubic-bezier(0.3, 0.7, 0.3, 1) 0.15s;
}
.js .scope-item.in .scope-tick::after { transform: rotate(-45deg) scale(1); }
.no-js .scope-tick::after { transform: rotate(-45deg) scale(1); }
.scope-item:hover .scope-tick {
  border-color: rgba(148, 138, 255, 0.6);
  box-shadow: 0 0 16px rgba(91, 76, 255, 0.25);
}

/* ============================================================
   SCENE 03 — THE SHELF.
   Four rulebooks stand edge-on, packed flush. The scroll pulls
   one volume at a time sideways out of the stack; it opens on
   the plate to the right, holds its question, then settles back
   into its groove as the next one slides out. The move is
   lateral on purpose — nothing else on this page travels sideways.

   Default (no JS / reduced motion / narrow): every volume is a
   plain open card, all four questions readable, nothing hidden.
   ============================================================ */
#registering { height: 320vh; }
.shelf-stage { justify-content: center; }
.shelf-inner { position: relative; z-index: 2; width: min(1060px, 100%); }

.shelf-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s3);
  border-bottom: 1px solid var(--line);
  padding-bottom: 14px;
  margin-bottom: clamp(22px, 4vh, 44px);
}
.shelf-h2 {
  font-size: clamp(10.5px, 1.15vw, 12.5px);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  font-weight: 400;
  color: var(--faint);
}
.shelf-count {
  flex: none;
  font-size: 10.5px; letter-spacing: 0.2em;
  color: var(--faint);
}
.shelf-count em { font-style: normal; color: var(--purple-soft); }

/* ---- the volumes: static, open, readable with nothing running ---- */
.shelf { position: relative; }
.shelf-books {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column;
  gap: 12px;
}
.vol { display: grid; grid-template-columns: 58px 1fr; }
.vol-spine {
  position: relative;
  display: flex; flex-direction: column;
  align-items: center; justify-content: space-between;
  gap: 14px;
  padding: 15px 0 16px;
  border: 1px solid var(--line-strong);
  border-right: 0;
  border-radius: 12px 0 0 12px;
  background: rgba(16, 16, 23, 0.66);
  backdrop-filter: blur(12px) saturate(160%);
  -webkit-backdrop-filter: blur(12px) saturate(160%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.07);
}
.vol-num { font-size: 12px; letter-spacing: 0.08em; color: var(--purple-soft); }
.vol-title {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  font-size: 9.5px; letter-spacing: 0.24em;
  color: var(--faint);
  white-space: nowrap;
}
.vol-edge { display: flex; flex-direction: column; gap: 3px; }
.vol-edge i { display: block; width: 14px; height: 1px; background: var(--line-strong); }
.vol-page {
  display: flex; flex-direction: column; justify-content: center;
  gap: 13px;
  border: 1px solid var(--line);
  border-left: 0;
  border-radius: 0 12px 12px 0;
  background:
    repeating-linear-gradient(180deg, rgba(255, 255, 255, 0.045) 0 1px, transparent 1px 30px),
    rgba(16, 16, 23, 0.5);
  backdrop-filter: blur(12px) saturate(160%);
  -webkit-backdrop-filter: blur(12px) saturate(160%);
  box-shadow: inset 1px 0 0 rgba(148, 138, 255, 0.28);
  padding: clamp(20px, 2.4vw, 34px);
}
.vol-tag { font-size: 9.5px; letter-spacing: 0.22em; color: var(--faint); }
.vol-tag em { font-style: normal; color: var(--pink-soft); }
.vol-q {
  font-size: clamp(19px, 2.2vw, 30px);
  line-height: 1.32;
  letter-spacing: -0.018em;
  font-weight: 500;
  color: var(--text);
  text-wrap: balance;
}
.shelf-base {
  display: block;
  height: 1px;
  margin-top: 14px;
  background: linear-gradient(90deg, var(--line-strong), rgba(148, 138, 255, 0.5) 26%, transparent 82%);
}

/* ---- enhanced: the stack, and the volume that slides out of it ---- */
@media (prefers-reduced-motion: no-preference) and (min-width: 981px) {
  .js .shelf {
    --spine-w: 70px;
    --pitch: 84px;
    --plate-x: 372px;
    height: clamp(330px, 46vh, 460px);
  }
  /* The four tabs are a fixed, flush strip on the left — they never move, so
     no tab ever leaves a gap. The open volume's page shows as the panel on the
     right. */
  .js .shelf-books { display: block; position: absolute; inset: 0; }
  .js .vol {
    position: absolute; inset: 0;
    display: block;
    pointer-events: none;
    z-index: 1;
  }
  .js .vol.is-open { z-index: 3; }

  .js .vol-spine {
    position: absolute; bottom: 0;
    left: calc(var(--i) * var(--pitch));
    width: var(--spine-w);
    height: var(--h);
    border-right: 1px solid var(--line-strong);
    border-radius: 12px;
    padding: 18px 0 19px;
    pointer-events: auto;
    cursor: pointer;
    transition: border-color 0.4s ease, box-shadow 0.4s ease, background 0.4s ease, transform 0.45s cubic-bezier(0.22, 0.6, 0.2, 1);
  }
  .js .vol.is-open .vol-spine { transform: translateY(-6px); }
  .js .vol-spine:hover { border-color: rgba(148, 138, 255, 0.45); }
  .js .vol-spine:focus-visible { z-index: 4; outline-offset: 2px; }
  .js .vol.is-open .vol-spine {
    border-color: rgba(148, 138, 255, 0.55);
    background: rgba(20, 19, 30, 0.78);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.09), 0 18px 44px rgba(0, 0, 0, 0.45);
  }
  .js .vol.is-open .vol-num { color: var(--pink-soft); }
  .js .vol.is-open .vol-title { color: var(--text); }
  .js .vol.is-read .vol-edge i { background: rgba(255, 125, 161, 0.55); }
  .js .vol.is-read .vol-num { color: var(--pink-soft); }

  .js .vol-page {
    position: absolute; top: 0; bottom: 0;
    left: var(--plate-x); right: 0;
    border-left: 1px solid var(--line);
    border-radius: 14px;
    pointer-events: none;
    opacity: 0;
    visibility: hidden;
    transform: translateX(16px);
    transition: opacity 0.5s ease, transform 0.6s cubic-bezier(0.22, 0.6, 0.2, 1), visibility 0s linear 0.5s;
  }
  .js .vol.is-open .vol-page {
    pointer-events: auto;
    opacity: 1;
    visibility: visible;
    transform: none;
    transition: opacity 0.5s ease, transform 0.6s cubic-bezier(0.22, 0.6, 0.2, 1);
    box-shadow: inset 1px 0 0 rgba(148, 138, 255, 0.28), 0 18px 44px rgba(0, 0, 0, 0.45);
  }
  .js .vol-tag,
  .js .vol-q {
    opacity: 0;
    transform: translateX(-20px);
    transition: opacity 0.5s ease 0.12s, transform 0.6s cubic-bezier(0.22, 0.6, 0.2, 1) 0.12s;
  }
  .js .vol.is-open .vol-tag,
  .js .vol.is-open .vol-q { opacity: 1; transform: none; }

  .js .shelf-base { position: absolute; left: 0; right: 0; bottom: -13px; margin-top: 0; }
}

/* ---- narrow: the stack cannot exist, the reading of it can ----
   Three 84px pitches plus a 70px spine is a 322px strip, and the plate
   beside it wants another ~300px. That is 620px of width on a 360px screen:
   this is the one device on the page where true parity is impossible, and
   forcing it would mean collapsing four approved questions behind a tap.

   So the cards stay exactly as the base stylesheet ships them — four open
   volumes, four questions, nothing hidden — and what comes back is the half
   of the scene that was never about the geometry: which volume is current,
   which ones you have passed (the pink read marks), and, from the JS, the
   VOL 0n/04 counter and the title scramble. The lateral pull survives at
   phone scale too: the current volume slides 6px out of the row, still the
   only sideways move on this page, and well inside the --pad gutter (24px
   minimum) so it can never push the document sideways.

   EVERY declaration in here is emphasis — colour, border, shadow, a 6px
   transform. There is no opacity, no clip-path and no display change, so no
   state this block can reach makes a question unreadable. That is the point:
   the spines are tappable, but a tap that never binds costs the reader
   nothing. Enhancement only — the .no-js and reduced-motion statics at the
   foot of this file are untouched. */
@media (prefers-reduced-motion: no-preference) and (max-width: 980px) {
  .js .vol {
    transform: translateX(0);
    transition: transform 0.45s cubic-bezier(0.22, 0.6, 0.2, 1);
  }
  .js .vol.is-open { transform: translateX(-6px); }

  .js .vol-spine {
    cursor: pointer;
    /* the spine is a real control here (see shelfArmFlat) and fills its grid
       row, so it clears 44px on its own; this only kills the tap delay */
    touch-action: manipulation;
    transition: border-color 0.4s ease, background-color 0.4s ease, box-shadow 0.4s ease;
  }
  .js .vol-spine:focus-visible { outline-offset: 2px; }
  .js .vol.is-open .vol-spine {
    border-color: rgba(148, 138, 255, 0.55);
    background-color: rgba(20, 19, 30, 0.92);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.09), 0 14px 34px rgba(0, 0, 0, 0.45);
  }
  .js .vol.is-open .vol-num { color: var(--pink-soft); }
  .js .vol.is-open .vol-title { color: var(--text); }
  .js .vol.is-open .vol-page { box-shadow: inset 1px 0 0 rgba(148, 138, 255, 0.55); }

  /* the read marks the stack leaves behind it, unchanged */
  .js .vol.is-read .vol-edge i { background: rgba(255, 125, 161, 0.55); }
  .js .vol.is-read .vol-num { color: var(--pink-soft); }
}

/* ============================================================
   REST — the close
   ============================================================ */
.close-top { text-align: center; }
.close .chapter-line-rest { text-align: center; }
.close .contact-chips { margin-top: var(--s5); }
.sib-wrap { margin-top: var(--s7); }
.sib-head {
  font-size: 10.5px; letter-spacing: 0.22em;
  color: var(--faint);
  border-top: 1px solid var(--line);
  padding-top: var(--s4);
  margin-bottom: var(--s4);
}
/* related services — the lean row list the other service pages share */
.sib-row { display: block; }
.sib {
  display: grid;
  grid-template-columns: 62px 1fr 24px;
  align-items: center;
  gap: var(--s2);
  border-bottom: 1px solid rgba(255, 255, 255, 0.055);
  padding: var(--s3) 0;
  transition: padding-left 0.35s cubic-bezier(0.3, 0.7, 0.3, 1), border-color 0.35s ease;
}
.sib:hover { padding-left: 10px; border-bottom-color: rgba(148, 138, 255, 0.35); }
.sib-num { font-size: 11.5px; letter-spacing: 0.1em; color: var(--purple-soft); }
.sib-name { font-size: clamp(16px, 1.5vw, 19px); font-weight: 500; letter-spacing: -0.01em; }
.sib-arrow {
  justify-self: end;
  font-size: 15px; color: var(--faint);
  transform: translateX(-4px);
  transition: transform 0.3s cubic-bezier(0.3, 0.7, 0.3, 1), color 0.3s ease;
}
.sib:hover .sib-arrow { transform: translateX(0); color: var(--purple-soft); }
.js .svc-card.reveal {
  transition: opacity 0.75s cubic-bezier(0.22, 0.6, 0.2, 1),
              transform 0.35s cubic-bezier(0.3, 0.7, 0.3, 1),
              border-color 0.35s ease, box-shadow 0.35s ease, background 0.35s ease;
}

/* ============================================================
   responsive
   ============================================================ */
@media (min-width: 981px) and (max-height: 880px) {
  .rb { padding: 12px 14px 15px; }
  .rb-fact { margin: 10px 0 12px; }
  .rb-rows { gap: 7px; }
  .rb-rail { height: 84px; }
  .js .shelf { height: clamp(268px, 40vh, 360px); }
  .vol-q { font-size: clamp(18px, 2vw, 26px); }
  .vol-page { padding: clamp(18px, 2vw, 28px); }
}

@media (max-width: 980px) {
  /* pinned scenes go static: all content flows and stays readable */
  #open { height: auto; }
  /* ...but #open's stage stays sticky at a fixed 100svh with overflow:hidden,
     and its children are centred, so anything the group cannot fit is clipped
     at BOTH ends with no scroll position that would ever reveal it. main.js's
     fit guard does not catch this one: stageContentH() skips aria-hidden
     children by design (the ghost numeral is meant to bleed), and .open-strip
     is aria-hidden — so on a short handset the MI/OH/IN/+47 strip can fall
     off the bottom of a stage that measures as fitting. Growing instead of
     clipping costs nothing: when the content fits, min-height reproduces
     today's full-viewport hero exactly. */
  /* vh first, svh second — the same two-step css/main.css uses, so a browser
     without svh still gets a viewport-tall hero rather than a collapsed one */
  #open .scene-stage { height: auto; min-height: 100vh; min-height: 100svh; }
  #standardise, #registering { height: auto; }
  #standardise .scene-stage,
  #registering .scene-stage {
    position: static;
    height: auto;
    overflow: visible;
    padding-top: var(--section-gap);
    padding-bottom: 0;
  }
  #standardise .ghost-center, #registering .ghost-center { display: none; }

  .open-strip {
    position: static;
    transform: none;
    margin: var(--s5) auto 0;
    flex-wrap: wrap; justify-content: center;
  }
  /* the strip rejoins the flow, so the centring transform goes — but the
     opacity is handed back to --stripop, which the prologue's intro clock
     now drives on narrow too (it used to be pinned at 1 here because the
     mobile branch resolved the whole scene on frame one). Only the .js path
     loses the hard 1: .no-js .open-strip and the reduced-motion block below
     both still force opacity 1, and neither can reach a scene function. */
  .js .open-strip { transform: none; }
  .open-h1 { font-size: clamp(30px, 7.6vw, 44px); }

  .pair-grid { grid-template-columns: 1fr; }
  .rb-deck { grid-template-columns: 1fr; gap: var(--s2); }
  .rb-frame { inset: -12px; border-radius: 16px; }
  .rb-frame-label { left: 16px; font-size: 8.5px; letter-spacing: 0.16em; }
  .rb-rail { height: 76px; }
  .rb-meter-track { width: 40vw; }
  .vol-q { font-size: clamp(18px, 4.6vw, 25px); }
}

@media (max-width: 640px) {
  .scope-item { grid-template-columns: 42px 1fr 18px; gap: 12px; }
  .sib { grid-template-columns: 52px 1fr 20px; }
  .close .cta-row .btn { width: 100%; justify-content: center; }
  .rb-track b { width: 30px; }
  .rb-track i { height: 6px; }
  .open-strip { gap: 8px; }
  .ost { padding: 9px 12px; font-size: 10px; }
  .shelf-head { flex-direction: column; align-items: flex-start; gap: 8px; }
  .vol { grid-template-columns: 46px 1fr; }
  .vol-page { padding: 18px 18px 20px; }
  .vol-spine { padding: 13px 0 14px; gap: 12px; }
  .vol-edge i { width: 12px; }
}

/* ============================================================
   statics — no JS and reduced motion get the resolved page
   ============================================================ */
.no-js .open-lede { opacity: 1; transform: none; }
.no-js .rb-stage { --std: 1; }
/* every volume lies open: four questions, no stack, no clipping */
.no-js .shelf { height: auto; }
.no-js .vol-page { clip-path: none; }
.no-js .vol-tag,
.no-js .vol-q { opacity: 1; transform: none; }
/* the stage stops being a positioned sticky box, so the strip rejoins the flow */
.no-js .open-strip {
  position: static;
  transform: none;
  opacity: 1;
  margin: var(--s5) auto 0;
  justify-content: center;
  flex-wrap: wrap;
}

@media (prefers-reduced-motion: reduce) {
  .rb-stage { --std: 1; }
  .shelf { height: auto; }
  .shelf-books { display: flex; }
  .vol { position: static; width: auto; height: auto; transform: none; }
  .vol-page { clip-path: none; }
  .vol-tag, .vol-q { opacity: 1; transform: none; }
  .scope-tick::after { transform: rotate(-45deg) scale(1); }
  .open-strip {
    position: static;
    transform: none;
    opacity: 1;
    margin: var(--s5) auto 0;
    justify-content: center;
    flex-wrap: wrap;
  }
}


/* ============================================================
   GLASS, COSTED FOR A PHONE (page-scoped)
   css/main.css flattens its OWN glass components below 980px, but it cannot
   reach the devices this page declares. backdrop-filter re-blurs everything
   behind an element on every frame it moves, and these sit inside a
   scrolling film — it is the most expensive thing a handset does here.

   Blur removed below 980px. Where the surface was too sheer to survive
   without it (var(--surface) is 3.5% white) an opaque base is added as
   background-COLOR, not background, so any ruled gradient painted on top
   of it is left intact.
   ============================================================ */
@media (max-width: 980px) {
  .ost {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    background-color: var(--glass-flat);
  }
  .panel {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    background-color: var(--glass-flat);
  }
  .rb {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    /* the deck still scatters, just within the screen it has */
    --spread: 0.4;
  }
  .vol-spine {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
  .vol-page {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
}
