/* ============================================================
   XQUBE GLOBAL — SERVICE 06 · India–US Cross-Border
   Page-specific styles only. The design system lives in main.css.

   The page's centrepiece is THE SEAM: two shores — UNITED STATES
   and INDIA — held vertically apart by a lit gap, with the reader
   standing in it, shearing into one joined panel as the scroll
   closes the offset. The engine's `seam` choreography drives one
   custom property (--shear, 1 = apart, 0 = joined) and the whole
   device is written as a function of it, so no-JS, reduced motion
   and narrow screens simply hold the closed end state.
   ============================================================ */

/* the cold open belongs to the homepage title sequence — an inner
   page must never blank its own chrome */
.js.cold .nav-inner,
.js.cold .scroll-progress { opacity: 1; }

/* current page marker in the nav */
.nav-links a.is-here { color: var(--text); }
.nav-links a.is-here::after { transform: scaleX(1); opacity: 0.75; }
.mobile-links a.is-here { color: var(--text); }
.mobile-links a.is-here .mono { color: var(--pink); }
.footer-col a.is-here { color: var(--text); }
.footer-col a.is-here::before {
  content: "";
  display: inline-block;
  width: 12px; height: 1px;
  margin-right: 8px;
  vertical-align: middle;
  background: var(--pink);
}

/* ============================================================
   1 · THE TITLE SCENE
   ============================================================ */
#xb-title.scene { height: 220vh; }
#xb-title .scene-stage {
  position: sticky;
  height: 100vh; height: 100svh;
  overflow: hidden;
  justify-content: center;
  padding: calc(var(--nav-h) + var(--s6)) var(--pad) var(--s6);
}
.xb-title-stage .title-block { max-width: 1060px; }
.xb-h1 {
  font-size: clamp(31px, 4.4vw, 62px);
  line-height: 1.08;
  letter-spacing: -0.028em;
  font-weight: 600;
  text-wrap: balance;
  max-width: 26ch;
  margin: 0 auto;
}
.xb-sub {
  margin: clamp(30px, 5vh, 54px) auto 0;
  max-width: 60ch;
  opacity: var(--subop, 1);
  transform: translateY(var(--suby, 0px));
}
@media (prefers-reduced-motion: no-preference) {
  /* SAFETY: only this page's own prologue scene ever raises --subop again, so
     the zero is scoped to .xb-live — a class js/service-cross-border.js adds
     once it has registered. Without it the approved standfirst would sit at
     opacity 0 forever whenever this page's script fails but the engine does not. */
  .js.xb-live .xb-title-stage { --subop: 0; --suby: 26px; }
}

/* ============================================================
   2 · THE PROBLEM — a reading rest, set narrow and unhurried
   ============================================================ */
.xb-problem .problem-h2 { max-width: 14ch; }
.xb-problem .problem-body {
  margin-top: clamp(36px, 6vh, 64px);
  display: flex; flex-direction: column;
  gap: var(--s5);
  border-left: 1px solid var(--line);
  padding-left: clamp(22px, 3vw, 44px);
}
.xb-problem .body-lg { max-width: 62ch; }

/* ============================================================
   3 · PAIRED PANELS — what we do / what changes for you
   ============================================================ */
.pair-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(20px, 2.6vw, 34px);
  align-items: stretch;
}
.pair-panel {
  position: relative;
  display: flex; flex-direction: column;
  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.2vw, 46px);
  overflow: hidden;
}
.pair-panel::before {
  content: "";
  position: absolute; left: 0; top: 0; bottom: 0;
  width: 2px;
  background: linear-gradient(180deg, transparent, var(--purple) 22%, var(--purple) 78%, transparent);
  opacity: 0.7;
}
.pair-panel-alt::before {
  background: linear-gradient(180deg, transparent, var(--pink) 22%, var(--pink) 78%, transparent);
}
.pair-num {
  font-size: 11px; letter-spacing: 0.22em;
  color: var(--purple-soft);
  margin-bottom: var(--s3);
}
.pair-panel-alt .pair-num { color: var(--pink-soft); }
.pair-h2 {
  font-size: clamp(24px, 2.6vw, 33px);
  font-weight: 600; letter-spacing: -0.02em; line-height: 1.15;
  margin-bottom: var(--s3);
}
.pair-body {
  font-size: clamp(15.5px, 1.3vw, 17px);
  line-height: 1.8;
  color: var(--mist);
  max-width: 46ch;
}

/* ============================================================
   4 · THE SEAM — the signature device
   Everything below is a function of --shear (1 apart, 0 joined),
   which the engine writes onto .seam-shores every frame.
   ============================================================ */
#xb-seam.scene { height: 300vh; }
#xb-seam .scene-stage {
  position: sticky;
  height: 100vh; height: 100svh;
  overflow: hidden;
  justify-content: center;
  gap: clamp(26px, 4.6vh, 58px);
  padding: calc(var(--nav-h) + var(--s4)) var(--pad) var(--s5);
  --off: clamp(26px, 4.4vh, 56px);   /* how far apart the shores sit */
  --gapw: clamp(40px, 6.5vw, 104px); /* how wide the lit gap opens   */
}
/* SAFETY: --shear is written by THIS page's own `seam` scene, and by nothing
   else on the site. If js/service-cross-border.js never runs, .xb-live is
   never added and nothing would ever pay the offset back — so hold the
   closed end state from the start rather than an open gap that stays open.
   Same posture as --subop above. (The narrow block's !important pair
   overrides both of these, as it must: there the entry class is in charge.) */
.js:not(.xb-live) .xb-seam-stage .seam-shores,
.no-js .xb-seam-stage .seam-shores { --shear: 0; }

.seam-head { max-width: 940px; }
.seam-head .chapter-line { margin-bottom: clamp(18px, 3vh, 34px); }
.xb-seam-stage .seam-h2 {
  font-size: clamp(25px, 3.3vw, 48px);
  line-height: 1.1;
  max-width: 24ch;
  margin: 0 auto;
}

.seam-rig {
  position: relative; z-index: 2;
  width: min(980px, 100%);
}
.xb-seam-stage .seam-shores {
  display: flex;
  align-items: stretch;
  justify-content: center;
  margin-top: 0;
  width: 100%;
  letter-spacing: 0.2em;
}

/* --- the two shores ---
   THE CLOSING AXIS IS THE LAYOUT'S OWN AXIS. Side by side (>=981px) the two
   files close HORIZONTALLY: .seam-gap between them narrows from --gapw to a
   2px slot and the cards slide together. Stacked (<=980px) they close
   VERTICALLY, and there the motion is a transform on the cards themselves —
   see the narrow block near the foot of this file. Both are functions of the
   same --shear, so the device tells one story on either shape. */
.xb-seam-stage .shore {
  display: flex; flex-direction: column;
  flex: 1 1 0;
  min-width: 0;
  max-width: 420px;
  gap: 0;
  /* a shore is a FILE — two of them are what the readout counts as
     "TWO FILES". The edge was never declared, so every border-color rule
     written to light the shores as they join (immediately below, and again
     in the narrow block) had nothing to colour and the join lit nothing on
     ANY viewport. The inset highlight on .joined is the site's standard
     card treatment and only reads against an edge. */
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(16px, 2.2vh, 26px) clamp(16px, 2vw, 28px);
  transition: border-color 0.6s ease, box-shadow 0.6s ease;
}
.xb-seam-stage.joined .shore,
.xb-seam-stage.is-closed .shore {
  border-color: rgba(148, 138, 255, 0.5);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 0 40px rgba(91, 76, 255, 0.16);
}

.shore-top {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px;
  font-size: clamp(8.5px, 0.85vw, 10px);
  letter-spacing: 0.22em;
}
.shore-qual {
  flex: none;
  border: 1px solid rgba(148, 138, 255, 0.45);
  border-radius: 100px;
  padding: 3px 9px;
  font-size: 9px; letter-spacing: 0.16em;
  color: var(--purple-soft);
}
.shore-in .shore-qual { border-color: rgba(255, 125, 161, 0.45); color: var(--pink-soft); }

/* the shore's time zones — the US spans six, India keeps one (IST) */
.shore-zones {
  display: grid;
  grid-template-columns: repeat(2, auto);
  gap: clamp(7px, 1.2vh, 11px) clamp(16px, 2vw, 30px);
  justify-content: start;
  margin-top: clamp(10px, 1.8vh, 18px);
}
.shore-zones-lead { grid-template-columns: auto; align-content: center; }
.szone { display: flex; align-items: baseline; gap: 9px; }
.szone .tz-abbr {
  min-width: 30px;
  font-size: 10.5px; letter-spacing: 0.12em;
  color: var(--purple-soft);
}
.shore-in .szone .tz-abbr { color: var(--pink-soft); }
.xb-seam-stage .szone .seam-tz {
  font-size: clamp(17px, 1.7vw, 22px);
  line-height: 1;
  color: var(--text);
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
}
.szone-lead .tz-abbr { min-width: 42px; font-size: 12px; }
.xb-seam-stage .szone-lead .seam-tz { font-size: clamp(26px, 3vw, 38px); }
/* the ledger anchors to the foot of each card so the two stay balanced */
.xb-seam-stage .shore .ledger { margin-top: auto; }

.ledger {
  display: flex; flex-direction: column;
  gap: clamp(5px, 0.9vh, 8px);
  margin-top: clamp(12px, 2vh, 20px);
  border-top: 1px solid var(--line);
  padding-top: clamp(12px, 2vh, 18px);
}
.shore-us .ledger { align-items: flex-end; }
.shore-in .ledger { align-items: flex-start; }
.lrow {
  display: block;
  width: calc(var(--w, 0.6) * 100%);
  height: 5px;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.13);
  transition: background 0.6s ease;
}
.xb-seam-stage.joined .lrow,
.xb-seam-stage.is-closed .lrow { background: rgba(148, 138, 255, 0.42); }

/* --- the gap the reader has been standing in ---
   Side by side, the corridor IS the width of this element: it opens to
   --gapw and shuts to a 2px slot, which is the whole closing beat at
   >=981px. The two shores are at their max-width there, so nothing but the
   corridor changes size and no text re-wraps. */
.xb-seam-stage .seam-gap {
  flex: none;
  width: calc(2px + var(--shear, 1) * var(--gapw));
}
.gap-you {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
  white-space: nowrap;
  font-size: 9px; letter-spacing: 0.26em;
  color: var(--pink-soft);
  border: 1px solid rgba(255, 77, 128, 0.5);
  border-radius: 100px;
  background: rgba(10, 10, 14, 0.92);
  padding: 5px 11px;
  opacity: calc((var(--shear, 1) - 0.12) * 2);
}
.gap-tie {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--purple);
  box-shadow: 0 0 16px rgba(91, 76, 255, 0.95);
  opacity: calc((0.3 - var(--shear, 1)) * 3.4);
}

/* --- the readout under the instrument --- */
.seam-foot {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s2);
  margin-top: clamp(14px, 2.4vh, 26px);
  border-top: 1px solid var(--line);
  padding-top: clamp(10px, 1.6vh, 14px);
  font-size: 9.5px; letter-spacing: 0.2em;
  color: var(--faint);
}
.seam-state { color: var(--purple-soft); transition: color 0.6s ease; }
.seam-state::after { content: "ONE FILE"; }
.seam-delta { white-space: nowrap; }
.seam-delta em { font-style: normal; color: var(--mist); margin-left: 8px; }
.seam-note { opacity: 0.8; }
@media (prefers-reduced-motion: no-preference) {
  .js .seam-state { color: var(--pink-soft); }
  .js .seam-state::after { content: "TWO FILES"; }
  .js .xb-seam-stage.joined .seam-state,
  .js .xb-seam-stage.is-closed .seam-state { color: var(--purple-soft); }
  .js .xb-seam-stage.joined .seam-state::after,
  .js .xb-seam-stage.is-closed .seam-state::after { content: "ONE FILE"; }
}

/* ============================================================
   5 · SCOPE OF WORK — the length is the argument
   ============================================================ */
.scope-h2 {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s2);
  font-size: 11px; letter-spacing: 0.24em;
  font-weight: 400;
  color: var(--faint);
  border-bottom: 1px solid var(--line);
  padding-bottom: var(--s2);
}
.scope-h2 em { font-style: normal; color: var(--purple-soft); }
.scope-list { list-style: none; margin: 0; padding: 0; }
.scope-item {
  display: grid;
  grid-template-columns: 78px 1fr;
  gap: var(--s3);
  align-items: baseline;
  border-bottom: 1px solid rgba(255, 255, 255, 0.055);
  padding: clamp(18px, 2.4vh, 28px) 0;
  transition: padding-left 0.4s cubic-bezier(0.3, 0.7, 0.3, 1), border-color 0.4s ease;
}
.scope-item:hover { padding-left: 10px; border-bottom-color: rgba(148, 138, 255, 0.35); }
.scope-num {
  font-size: 12px; letter-spacing: 0.14em;
  color: var(--purple-soft);
  opacity: 0.85;
}
.scope-text {
  font-size: clamp(17px, 1.9vw, 24px);
  line-height: 1.4;
  letter-spacing: -0.012em;
  color: var(--text);
}
.js .scope-list .reveal:nth-child(1) { transition-delay: 0.02s; }
.js .scope-list .reveal:nth-child(2) { transition-delay: 0.06s; }
.js .scope-list .reveal:nth-child(3) { transition-delay: 0.10s; }
.js .scope-list .reveal:nth-child(4) { transition-delay: 0.14s; }
.js .scope-list .reveal:nth-child(5) { transition-delay: 0.18s; }
.js .scope-list .reveal:nth-child(6) { transition-delay: 0.22s; }
.js .scope-list .reveal:nth-child(7) { transition-delay: 0.26s; }

/* ============================================================
   6 · QUESTIONS WE ASK — TWO SHORES
   The four questions are posted on either side of a live border:
   United States west, India east, a corridor two hairlines wide
   between them. One thread is stitched through all four by the
   scroll — crossing the border four times — and the corridor
   closes behind it to a single line.

   The thread's geometry is measured and written into the SVG by
   js/service-cross-border.js; everything else is a function of
   two custom properties the engine writes onto the stage:
     --corr  the width of the border corridor (1px = closed)
     --knot  the tie at the foot of the border
   and one per question:
     --qop / --qx  how far the thread has reached it.
   Every default below is the FINISHED state, so no-JS, reduced
   motion and narrow screens land on a closed border with all
   four questions fully lit and fully readable.
   ============================================================ */
#xb-ask.scene { height: 320vh; }
#xb-ask .scene-stage {
  position: sticky;
  height: 100vh; height: 100svh;
  overflow: hidden;
  justify-content: center;
  gap: clamp(16px, 2.6vh, 40px);
  padding: calc(var(--nav-h) + var(--s2)) var(--pad) var(--s4);
}
/* the two knobs the whole device is written against — kept off the
   id selector above so a single class can override them */
.cross-stage {
  --corr: 1px;   /* border corridor width; 1px = the two lines are one */
  --knot: 1;     /* the tie at the foot of the border */
}
.cross-h2 {
  position: relative; z-index: 3;
  font-size: clamp(10px, 1.05vw, 12.5px);
  font-weight: 400;
  letter-spacing: 0.26em;
  line-height: 1.9;
  text-align: center;
  color: var(--faint);
  max-width: 48ch;
}
.cross-track {
  position: relative; z-index: 2;
  width: min(1120px, 100%);
}
.cross-field { position: relative; padding: clamp(10px, 1.7vh, 26px) 0; }

/* ---- the border itself: two hairlines and the corridor between ---- */
.cross-seam {
  position: absolute; z-index: 1;
  top: 0; bottom: 0; left: 50%;
  width: var(--corr);
  transform: translateX(-50%);
  /* the corridor is lit, not filled — the two edges are the border */
  background: linear-gradient(180deg,
    transparent,
    rgba(91, 76, 255, 0.09) 14%,
    rgba(255, 77, 128, 0.07) 86%,
    transparent);
  pointer-events: none;
}
.cross-edge {
  position: absolute; top: 0; bottom: 0;
  width: 1px;
  background: linear-gradient(180deg, transparent, currentColor 6%, currentColor 94%, transparent);
}
.cross-edge-w { left: 0;  color: rgba(148, 138, 255, 0.78); }
.cross-edge-e { right: 0; color: rgba(255, 125, 161, 0.7); }
.cross-knot {
  position: absolute; left: 50%; bottom: -3px;
  width: 7px; height: 7px;
  border-radius: 50%;
  transform: translateX(-50%);
  background: var(--purple);
  box-shadow: 0 0 16px rgba(91, 76, 255, 0.9);
  opacity: var(--knot);
}

/* ---- the thread ---- */
.cross-thread {
  position: absolute; inset: 0; z-index: 1;
  width: 100%; height: 100%;
  overflow: hidden;
  pointer-events: none;
}
.cross-path {
  fill: none;
  stroke: url(#cxThreadGrad);
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.cross-node {
  fill: rgba(255, 255, 255, 0.16);
  stroke: rgba(255, 77, 128, 0);
  stroke-width: 0;
  transition: fill 0.45s ease, stroke 0.55s ease,
              stroke-width 0.55s cubic-bezier(0.22, 0.6, 0.2, 1);
}
.cross-node.on {
  fill: var(--pink-soft);
  stroke: rgba(255, 77, 128, 0.26);
  stroke-width: 12;
}

/* ---- the questions, posted on their own side of the line ---- */
.cross-list {
  list-style: none;
  position: relative; z-index: 2;
  margin: 0; padding: 0;
  display: flex; flex-direction: column;
  gap: clamp(14px, 2.8vh, 34px);
}
.cross-q {
  position: relative;
  width: 34%;
  opacity: var(--qop, 1);
  transform: translateX(var(--qx, 0px));
}
.side-us {
  margin-right: auto;
  text-align: right;
  --side: var(--purple-soft);
  --side-dim: rgba(148, 138, 255, 0.45);
}
.side-in {
  margin-left: auto;
  text-align: left;
  --side: var(--pink-soft);
  --side-dim: rgba(255, 125, 161, 0.45);
}
.cross-tag {
  position: relative;
  display: flex; align-items: center;
  gap: 10px;
  font-size: clamp(8.5px, 0.78vw, 10px);
  letter-spacing: 0.24em;
  line-height: 1.6;
  color: var(--faint);
  margin-bottom: clamp(6px, 1vh, 12px);
}
.side-us .cross-tag { justify-content: flex-end; }
.side-in .cross-tag { justify-content: flex-start; }
.cross-jur { white-space: nowrap; }
.cross-n {
  flex: none;
  font-size: 10px; letter-spacing: 0.1em; line-height: 1;
  color: var(--side);
  border: 1px solid var(--side-dim);
  border-radius: 100px;
  padding: 4px 8px 3px;
  background: rgba(10, 10, 14, 0.75);
}
/* the static tie from each question to the border — the thread's
   understudy for no-JS, reduced motion and narrow screens */
.cross-tag::before {
  content: "";
  position: absolute; top: 50%;
  width: 47%; height: 1px;
  background: linear-gradient(90deg, transparent, var(--side-dim));
}
.side-us .cross-tag::before {
  right: -47%;
  background: linear-gradient(270deg, transparent, var(--side-dim));
}
.side-in .cross-tag::before { left: -47%; }
.cross-track.is-live .cross-tag::before { opacity: 0; }

.cross-text {
  font-size: clamp(15px, min(1.5vw, 2.35vh), 20.5px);
  line-height: 1.42;
  letter-spacing: -0.018em;
  font-weight: 500;
  color: var(--text);
  text-wrap: balance;
}
@media (hover: hover) {
  .cross-q:hover { opacity: 1; }
}

/* ---- the readout under the border ---- */
.cross-foot {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s2);
  margin-top: clamp(10px, 1.6vh, 20px);
  border-top: 1px solid var(--line);
  padding-top: clamp(8px, 1.2vh, 14px);
  font-size: 9.5px; letter-spacing: 0.2em;
  color: var(--faint);
}
.cross-count { font-style: normal; color: var(--text); margin: 0 1px; }
.cross-state { color: var(--purple-soft); white-space: nowrap; }
.cross-state::after { content: "STITCHED"; }

/* the live instrument: the border opens, and only the scroll closes it */
@media (prefers-reduced-motion: no-preference) and (min-width: 981px) {
  .js .cross-stage { --corr: 34px; --knot: 0; }
  .js .cross-state { color: var(--pink-soft); }
  .js .cross-state::after { content: "UNSTITCHED"; }
  .js .cross-stage.is-sewn .cross-state { color: var(--purple-soft); }
  .js .cross-stage.is-sewn .cross-state::after { content: "STITCHED"; }
}
/* The same readout below 981px, where the phone now gets the same rig — but
   keyed off .is-live rather than the width, because .is-live is only added
   once buildRig has actually measured a thread and is driving --corr/--knot
   inline. A width gate would announce UNSTITCHED on a viewport where nothing
   was ever going to stitch it; this cannot say it unless something can
   answer it. Deliberately NOT merged with the block above: desktop reaches
   UNSTITCHED on first paint today and must keep doing so, rather than
   flickering STITCHED for the ~60ms before the rig is cut. */
@media (prefers-reduced-motion: no-preference) and (max-width: 980px) {
  .js .cross-stage.is-live .cross-state { color: var(--pink-soft); }
  .js .cross-stage.is-live .cross-state::after { content: "UNSTITCHED"; }
  .js .cross-stage.is-live.is-sewn .cross-state { color: var(--purple-soft); }
  .js .cross-stage.is-live.is-sewn .cross-state::after { content: "STITCHED"; }
}
@media (min-width: 981px) and (max-height: 720px) {
  .cross-text { font-size: 14.5px; line-height: 1.38; }
  .cross-list { gap: 14px; }
  .cross-h2 { font-size: 10px; letter-spacing: 0.22em; }
  .cross-field { padding: 10px 0; }
}

/* ============================================================
   7 · THE CLOSE
   ============================================================ */
.xb-close { text-align: center; }
.close-h2 { margin: 0 auto; max-width: 18ch; }
.xb-close .chapter-line-rest { text-align: center; }
.xb-close .cta-row { justify-content: center; margin-top: var(--s5); }
.siblings {
  margin-top: var(--s7);
  border-top: 1px solid var(--line);
  padding-top: var(--s4);
  text-align: left;
}
.sib-head {
  font-size: 10.5px; letter-spacing: 0.24em;
  color: var(--faint);
  margin-bottom: var(--s2);
}
.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); }

/* ============================================================
   RESPONSIVE — every pinned scene collapses to static flow
   ============================================================ */
@media (max-width: 1100px) {
  .scope-item { grid-template-columns: 62px 1fr; gap: var(--s2); }
}

@media (max-width: 980px) {
  #xb-title.scene { height: auto; }
  #xb-title .scene-stage {
    position: static;
    height: auto;
    min-height: 82svh;
    overflow: visible;
    padding: calc(var(--nav-h) + var(--s6)) var(--pad) var(--s6);
  }
  #xb-title .ghost-center { display: none; }
  #xb-title .scroll-cue { display: none; }
  .xb-h1 { max-width: 100%; font-size: clamp(28px, 7.6vw, 44px); }

  .pair-grid { grid-template-columns: 1fr; }

  /* the seam holds its closed end state and flows with the page */
  #xb-seam.scene { height: auto; }
  #xb-seam .scene-stage {
    position: static;
    height: auto;
    overflow: visible;
    gap: var(--s5);
    padding: var(--section-gap) var(--pad) 0;
    /* --off is now the TRAVEL of each card, and the corridor below reserves
       exactly twice it, so the two shores end flush. --gapw is a
       side-by-side measurement and has nothing to describe once the cards
       stack, so it is not overridden here. */
    --off: 34px;
  }
  #xb-seam .ghost-center { display: none; }
  /* the device still performs: it arrives apart and closes once, on
     entry, instead of being scrubbed by a pin that would not fit.
     Both live rules are keyed on .xb-live, not on .js: it is
     js/service-cross-border.js that adds .is-closed, so if that file alone
     fails to run, "apart" would be a state nothing could ever leave. The
     closed default above is what a page with no working script must land on. */
  .xb-seam-stage .seam-shores { --shear: 0 !important; }
  .js.xb-live .xb-seam-stage .seam-shores { --shear: 1 !important; }
  .js.xb-live .xb-seam-stage.is-closed .seam-shores { --shear: 0 !important; }
  /* THE CLOSING BEAT, STACKED. Side by side the corridor is the width of
     .seam-gap; stacked, a width means nothing — the corridor has to be its
     HEIGHT, and animating a height is the one thing a phone must not be
     asked to do sixty times a second. So the corridor is reserved in LAYOUT
     at its full open size and the two cards TRANSFORM into it: --shear 1
     leaves them at rest with the corridor open between them, --shear 0
     brings them together onto one seam. Nothing reflows, only transform and
     opacity move, and neither card can ride over the headline above or the
     readout below the way an outward shear would. */
  .xb-seam-stage .seam-gap {
    position: relative;       /* YOU and the tie dot belong to the corridor,
                                 not to .seam-rig — which is what they were
                                 resolving against, landing them on the
                                 INDIA card's header */
    width: 100%;
    height: calc(var(--off) * 2);
  }
  .xb-seam-stage .shore { transform: translateY(var(--sy, 0px)); }
  .xb-seam-stage .shore-us { --sy: calc(var(--off) * (1 - var(--shear, 1))); }
  .xb-seam-stage .shore-in { --sy: calc(var(--off) * (1 - var(--shear, 1)) * -1); }
  .js .xb-seam-stage .shore {
    transition: transform 0.95s cubic-bezier(0.22, 0.6, 0.2, 1),
                border-color 0.7s ease, box-shadow 0.7s ease;
  }
  .js .gap-you, .js .gap-tie, .js .xb-seam-stage .seam-gap i { transition: opacity 0.8s ease; }
  /* the pinned scene's own "joined" flag is meaningless once the scene
     flows: here the entry class is the only thing that closes the seam */
  .js .xb-seam-stage.joined .shore {
    border-color: var(--line);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.09);
  }
  .js .xb-seam-stage.joined .lrow { background: rgba(255, 255, 255, 0.13); }
  .js .xb-seam-stage.joined .seam-state { color: var(--pink-soft); }
  .js .xb-seam-stage.joined .seam-state::after { content: "TWO FILES"; }
  .js .xb-seam-stage.is-closed .shore {
    border-color: rgba(148, 138, 255, 0.5);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 0 40px rgba(91, 76, 255, 0.16);
  }
  .js .xb-seam-stage.is-closed .lrow { background: rgba(148, 138, 255, 0.42); }
  .js .xb-seam-stage.is-closed .seam-state { color: var(--purple-soft); }
  .js .xb-seam-stage.is-closed .seam-state::after { content: "ONE FILE"; }
  .xb-seam-stage .seam-h2 { max-width: 100%; font-size: clamp(24px, 6.6vw, 34px); }
  /* the scene no longer has the travel to scrub the line word by word,
     so the line is simply lit */
  .js .xb-seam-stage [data-words] .w { opacity: 1; }
  /* narrow: the two shores stack full-width instead of sitting side by side */
  .xb-seam-stage .seam-shores { flex-direction: column; }
  .xb-seam-stage .shore { padding: var(--s3) var(--s2); max-width: none; }
  .xb-seam-stage .shore .ledger { margin-top: clamp(12px, 2vh, 20px); }
  .xb-seam-stage .shore-zones { grid-template-columns: repeat(3, auto); }
  .seam-foot { flex-wrap: wrap; row-gap: 8px; justify-content: flex-start; }
  /* the world runs behind the whole page — on a small screen the
     device needs its own ground to stay legible */
  .xb-seam-stage .shore {
    background: rgba(14, 14, 20, 0.72);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
  }

  /* TWO SHORES on a narrow screen: the border cannot be a centre line
     with a column either side, so it becomes a margin rule down the
     left and the questions hang off it, still tagged and still
     alternating by colour.

     The thread is NOT a wide-screen instrument any more. It is the thing
     that makes this section a scene rather than a list, so it runs here
     too: js/service-cross-border.js measures the rule and the four badges
     and stitches a thread down the margin that loops out to each question
     in turn — four departures from the line and four returns to it, the
     four crossings the readout counts, at a width a phone actually has.
     The static ties are still the understudy: .cross-track.is-live hides
     them, and .is-live only exists while a measured rig is driving. */
  #xb-ask.scene { height: auto; }
  #xb-ask .scene-stage {
    position: static;
    height: auto;
    overflow: visible;
    align-items: flex-start;
    gap: var(--s4);
    padding: var(--section-gap) var(--pad) 0;
  }
  .cross-h2 { text-align: left; max-width: 32ch; }
  .cross-track { width: 100%; }
  .cross-field { padding: var(--s2) 0; }
  .cross-seam { left: 10px; }
  .cross-list { gap: var(--s4); }
  .cross-q {
    width: 100%;
    margin: 0;
    text-align: left;
    padding-left: 48px;
    /* the 18px horizontal slide stays OFF here: the row is already the full
       column width, so translating it either way pushes content past the
       document edge. The lift out of 0.4 opacity carries the beat instead,
       and the rig writes --qx as 0 on this shape so nothing fights it. */
    transform: none;
  }
  .side-us .cross-tag { flex-direction: row-reverse; justify-content: flex-end; }
  .side-in .cross-tag { justify-content: flex-start; }
  .side-us .cross-tag::before,
  .side-in .cross-tag::before {
    left: -38px; right: auto;
    width: 28px;
    background: linear-gradient(90deg, transparent, var(--side-dim));
  }
  .cross-text { font-size: clamp(17px, 2.6vw, 21px); }
  .cross-foot { flex-wrap: wrap; row-gap: 8px; }
}

/* narrow + reduced motion: no entry animation, the seam is closed.
   Selector matched to the live rule above deliberately — that one is
   `.js.xb-live ...` and carries !important, so a shorter selector here
   would lose on specificity and leave the seam standing open for exactly
   the reader who asked for no motion. seamOnEntry bails under reduced
   motion, so nothing else would ever close it. */
@media (max-width: 980px) and (prefers-reduced-motion: reduce) {
  .js.xb-live .xb-seam-stage .seam-shores { --shear: 0 !important; }
}

@media (max-width: 640px) {
  .scope-item { grid-template-columns: 46px 1fr; }
  .scope-text { font-size: clamp(16px, 4.6vw, 20px); }
  .xb-seam-stage .shore-top { flex-direction: column; align-items: flex-start; gap: 6px; }
  .xb-close .cta-row .btn { width: 100%; justify-content: center; }
  .sib { grid-template-columns: 52px 1fr 20px; }

  .cross-seam { left: 7px; }
  .cross-q { padding-left: 38px; }
  .side-us .cross-tag::before,
  .side-in .cross-tag::before { left: -31px; width: 24px; }
  .cross-tag { gap: 8px; letter-spacing: 0.2em; }
  .cross-list { gap: var(--s5); }
  .cross-foot { font-size: 9px; letter-spacing: 0.16em; }
}

/* ============================================================
   REDUCED MOTION — the whole page, static and complete,
   the seam already closed
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  #xb-title.scene, #xb-seam.scene, #xb-ask.scene { height: auto !important; }
  #xb-title .scene-stage,
  #xb-seam .scene-stage,
  #xb-ask .scene-stage {
    position: static; height: auto; overflow: visible;
    padding-top: var(--section-gap);
  }
  #xb-title .ghost-center, #xb-seam .ghost-center { display: none; }
  .xb-sub { opacity: 1; transform: none; }
  .xb-seam-stage .seam-shores { --shear: 0; }
  .xb-seam-stage .lrow { background: rgba(148, 138, 255, 0.42); }
  /* TWO SHORES: the border is already closed and every question is
     already lit — the drawing is finished, it just never moves */
  .cross-q { opacity: 1 !important; transform: none !important; }
  .cross-stage { --corr: 1px !important; --knot: 1 !important; }
}

/* ============================================================
   NO-JS — same static, complete play
   ============================================================ */
.no-js #xb-title .scene-stage,
.no-js #xb-seam .scene-stage,
.no-js #xb-ask .scene-stage {
  position: static;
  height: auto;
  overflow: visible;
  padding-top: var(--section-gap);
}
.no-js #xb-title .ghost-center,
.no-js #xb-seam .ghost-center,
.no-js #xb-title .scroll-cue { display: none; }
.no-js .xb-sub { opacity: 1; transform: none; }
.no-js .xb-seam-stage .lrow { background: rgba(148, 138, 255, 0.42); }
.no-js .cross-q { opacity: 1; transform: none; }
.no-js .cross-thread { display: none; }
.no-js .cross-stage { --corr: 1px; --knot: 1; }


/* ============================================================
   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) {
  .pair-panel {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    background-color: var(--glass-flat);
  }
  .xb-seam-stage .shore {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
}
