/* The front end.
 *
 * Four pages living inside one #title-screen, shown one at a time by
 * data-page on the container. Everything is centred: the title page is a title
 * and nothing else, and the choices that used to crowd it now have a page of
 * their own where they have room to explain themselves.
 */

/* ===========================================================================
   MENU — one paper-and-ink 1940s skin for every page.
   Everything lives on a single `--paper` tone so the cards stop reading as a
   stack of black slabs. Buttons are the same shape everywhere: the mbtn is a
   bordered 3px slab, `.primary` is the only red one on the page, and hover /
   active / tap feedback all come through the same two-tone gradient.
   =========================================================================== */

/* Local fallbacks only. Canonical blood/paper/soot live in theme.css :root
   (loads later and wins). Do not reintroduce a second --blood-hot here (U04). */
:root {
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 16px;
  --space-4: 24px;
  --ease-out: cubic-bezier(.2, .8, .2, 1);
  --dur-fast: .12s;
  --dur-med: .28s;
  --paper:   var(--cream-700);
  --paper-dim: var(--paper-mute);
  --edge:    rgba(190,170,135,.28);
  --edge-hot:rgba(212,91,80,.72);
  --focus-ring: var(--amber);
}

/* ── home ────────────────────────────────────────────────────────────── */
#title-screen { justify-content: center; }
/* Ft. Rot night gate — cover every aspect (16:10 / 21:9 / 4:3), no letterbox. */
#title-bg {
  background: url('../assets/img/menu_bg.jpg') center / cover no-repeat;
}
#title-bg img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

.site-strip {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  width: min(720px, 94vw);
  margin: 10px auto 4px;
  z-index: 2;
}
.site-card {
  position: relative;
  min-height: 92px;
  padding: 10px 10px 12px;
  overflow: hidden;
  cursor: pointer;
  text-align: left;
  color: var(--cream-500);
  background:
    linear-gradient(180deg, rgba(8,10,12,.55), rgba(4,6,8,.88)),
    repeating-linear-gradient(135deg, rgba(18,22,26,.9) 0 8px, rgba(8,10,12,.95) 8px 16px);
  border: 1px solid rgba(190,170,135,.22);
  border-radius: 2px;
}
.site-card::before {
  content: "";
  position: absolute;
  inset: 8px 10px auto auto;
  width: 28px;
  height: 42px;
  /* Evidence-tag motif. The plain dark gradient read as a broken thumbnail
     slot; the hairline edge and punched hanger hole say "tag" on purpose. */
  background:
    radial-gradient(circle 3px at 50% 7px, rgba(5,6,8,.95) 0 2.2px, rgba(190,170,135,.38) 2.6px 3px, transparent 3.4px),
    linear-gradient(180deg, rgba(48,56,60,.95), rgba(14,16,18,.92));
  border: 1px solid rgba(190,170,135,.24);
  clip-path: polygon(20% 0, 80% 0, 100% 18%, 100% 100%, 0 100%, 0 18%);
  opacity: .8;
  pointer-events: none;
}
.site-card.is-locked {
  color: var(--paper-mute);
  filter: grayscale(.35) brightness(.72);
}
.site-card.is-locked .site-name { letter-spacing: .4em; }
.site-card.is-selected {
  border-color: var(--edge-hot);
  box-shadow: 0 0 18px rgba(180, 40, 30, .28);
}
.site-card.is-stub.is-open { border-color: rgba(180,160,110,.4); }
.site-card:focus-visible { outline: 1px solid var(--focus-ring); outline-offset: 2px; }
.site-file {
  display: block;
  color: var(--amber);
  font: 700 8px/1.2 var(--font-mono);
  letter-spacing: .16em;
  text-transform: uppercase;
}
.site-name {
  display: block;
  margin-top: 6px;
  font: 800 13px/1.1 var(--font-display);
  letter-spacing: .08em;
  text-transform: uppercase;
}
.site-intel {
  display: block;
  margin-top: 6px;
  color: var(--paper-mute);
  font: 600 10px/1.35 var(--font-ui);
}
.site-strip-note {
  min-height: 0;
  margin: 0 0 6px;
  color: var(--tone-e8b473);
  font: 700 11px/1.3 var(--font-mono);
  letter-spacing: .06em;
}
.site-strip-note:empty { display: none; margin: 0; }

/* The dotted foreground that drifted in over time. One static layer of
   faint hash-marks so the cards and the title read as printed on a surface,
   not as floating shapes on a gradient. */
#title-screen::after {
  content:""; position:absolute; inset:0; pointer-events:none; z-index:1;
  background-image:
    repeating-linear-gradient(0deg, transparent 0 2px, rgba(0,0,0,.06) 2px 3px),
    repeating-linear-gradient(90deg, transparent 0 2px, rgba(0,0,0,.06) 2px 3px);
  mix-blend-mode: multiply;
  opacity:.4;
}
/* The pages float above the grain — z-index 2 here puts them over the ::after,
   which would otherwise sit on top of the cards. */

.mpage {
  position: relative; z-index: 2;
  display: none;
  flex-direction: column;
  align-items: center;
  text-align: center;
  width: min(1080px, 94vw);
  max-height: 100vh;
  /* top inset keeps the page heading clear of a notch; the bottom bar of the
     loadout/coop pages carries its own inset */
  padding: calc(var(--space-4, 28px) + env(safe-area-inset-top,0px))
           var(--space-3, 20px)
           calc(var(--space-4, 28px) + env(safe-area-inset-bottom,0px));
  overflow-y: auto;
  overscroll-behavior: contain;
}
/* Any page whose name matches the container's data-page. Written as an
   attribute match on the pair rather than one selector per page, so removing a
   page cannot decapitate the rule — which is exactly what happened when the
   archive line was deleted and it took the opening brace with it, leaving every
   page display:none and the game unreachable past the title screen. */
#title-screen[data-page="home"]     .mpage[data-for="home"],
#title-screen[data-page="loadout"]  .mpage[data-for="loadout"],
#title-screen[data-page="treatments"] .mpage[data-for="treatments"],
#title-screen[data-page="night"]    .mpage[data-for="night"],
#title-screen[data-page="site"]     .mpage[data-for="site"],
#title-screen[data-page="online"]   .mpage[data-for="online"],
#title-screen[data-page="ready"]    .mpage[data-for="ready"],
#title-screen[data-page="more"]     .mpage[data-for="more"],
#title-screen[data-page="controls"] .mpage[data-for="controls"],
#title-screen[data-page="coop"]     .mpage[data-for="coop"],
#title-screen[data-page="lobby"]    .mpage[data-for="lobby"],
#title-screen[data-page="legal"]    .mpage[data-for="legal"],
#title-screen[data-page="credits"]  .mpage[data-for="credits"] {
  display: flex;
  /* fill `backwards`, never `both`: a retained `forwards` keyframe leaves
     transform: translateY(0) on the .mpage — an identity transform still makes
     IT the containing block for the fixed action bar (.menu-col), so Deploy
     scrolled with the content and covered the callsign row at 844x390
     (measured live: btn-deploy y 269 -> 71 after a 198px scroll). */
  animation: mpIn var(--dur-med, .28s) var(--ease-out, cubic-bezier(.2,.8,.2,1)) backwards;
}
@keyframes mpIn { from { opacity: 0; transform: translateY(9px); } }
@media (prefers-reduced-motion: reduce) {
  #title-screen[data-page="home"]     .mpage[data-for="home"],
  #title-screen[data-page="loadout"]  .mpage[data-for="loadout"],
  #title-screen[data-page="treatments"] .mpage[data-for="treatments"],
  #title-screen[data-page="night"]    .mpage[data-for="night"],
  #title-screen[data-page="site"]     .mpage[data-for="site"],
  #title-screen[data-page="online"]   .mpage[data-for="online"],
  #title-screen[data-page="ready"]    .mpage[data-for="ready"],
  #title-screen[data-page="more"]     .mpage[data-for="more"],
  #title-screen[data-page="controls"] .mpage[data-for="controls"],
  #title-screen[data-page="coop"]     .mpage[data-for="coop"],
  #title-screen[data-page="credits"]  .mpage[data-for="credits"] {
    animation: none;
  }
}

.mpage-title {
  font: 700 12px/1 var(--font-mono);
  letter-spacing: .42em; text-transform: uppercase;
  color: var(--tone-7a756a);
  margin: var(--space-4, 24px) 0 var(--space-3, 14px);
}
.mpage-title:first-child { margin-top: var(--space-1, 4px); }
/* A hairline either side, so the heading reads as a divider rather than a label. */
.mpage-title::before, .mpage-title::after {
  content: ""; display: inline-block; vertical-align: middle;
  width: clamp(20px, 7vw, 90px); height: 1px; margin: 0 16px;
  background: linear-gradient(90deg, transparent, rgba(190,160,110,.4), transparent);
}

/* ---------------------------------------------------------------- personas */

/* The roster is a row of five on a wide screen, wrapping as it narrows. Flex
   rather than grid specifically so a wrapped row of two or three still centres
   under the row above it — in a fixed grid an orphan row strands itself on the
   left and reads as a mistake. */
/* Five cards on one row, or one row of five you scroll — never four with a
   fifth stranded underneath, which is what a wrapping flex row produced at
   every width between 760px and 920px and read as a layout mistake. */
#persona-grid {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 12px;
  width: 100%;
  max-width: 940px;
}
#persona-grid .p-card { min-width: 0; }
@media (max-width: 920px) {
  #persona-grid {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: minmax(150px, 1fr);
    overflow-x: auto;
    scroll-snap-type: x proximity;
    padding-bottom: 8px;
    /* the scroller must not clip the selected card's ring */
    scroll-padding-inline: 12px;
  }
  #persona-grid .p-card { scroll-snap-align: center; }
}
@media (max-width: 560px) { #persona-grid { grid-auto-columns: minmax(132px, 1fr); } }
.p-card {
  position: relative;
  cursor: pointer; pointer-events: auto;
  display: flex; flex-direction: column; align-items: stretch;
  padding: 0; overflow: hidden;
  background: linear-gradient(168deg, rgba(28,32,37,.94), rgba(10,12,15,.98));
  border: 1px solid var(--edge);
  border-radius: 4px;
  color: inherit; font-family:var(--font-ui);
  box-shadow: 0 12px 28px rgba(0,0,0,.55);
  transition: border-color .18s, transform .18s, box-shadow .18s, background .18s;
}
/* A hairline of light along the top edge. One pixel, and it is most of the
   difference between a panel that looks lit and a rectangle with a border. */
.p-card::before {
  content: ""; position: absolute; inset: 0 0 auto; height: 1px; z-index: 3;
  background: linear-gradient(90deg, transparent, rgba(255,240,215,.24) 22%, rgba(255,240,215,.24) 78%, transparent);
}
.p-card:hover {
  border-color: rgba(200,175,130,.5); transform: translateY(-4px);
  box-shadow: 0 16px 34px rgba(0,0,0,.62);
}
.p-card:focus-visible {
  border-color: rgba(200,175,130,.5); transform: translateY(-4px);
  box-shadow: 0 16px 34px rgba(0,0,0,.62);
  outline: 1px solid var(--focus-ring, var(--amber));
  outline-offset: 2px;
}
.p-card.sel {
  border-color: var(--denied);
  background: linear-gradient(168deg, rgba(44,22,19,.92), rgba(10,8,9,.97));
  box-shadow: 0 0 0 1px rgba(176,69,58,.45), 0 16px 38px rgba(0,0,0,.72),
              0 0 30px rgba(150,34,25,.2);
}
.p-card.sel::after {
  content: "SELECTED";
  position: absolute; top: 9px; right: 9px; z-index: 4;
  padding: 4px 8px; border-radius: 999px;
  background: rgba(150,32,24,.92);
  box-shadow: 0 2px 10px rgba(0,0,0,.5), inset 0 1px rgba(255,210,190,.3);
  font: 700 8px/1 var(--font-mono); letter-spacing: .16em; color: var(--tone-ffe7df);
}

/* ---- the portrait ----
   Framed as a shot rather than dropped in as an image: the figure is rendered
   on transparency (see portrait3d.js), so the light behind it belongs to the
   card and can respond to hover and selection. A flat <img> with its own baked
   backdrop could do none of that. */
.p-card .p-shot {
  position: relative; display: block; overflow: hidden;
  aspect-ratio: 3 / 4;
  background:
    radial-gradient(ellipse 74% 56% at 50% 34%, rgba(126,142,164,.22), transparent 70%),
    linear-gradient(178deg, var(--tone-171b21) 0%, var(--tone-0d1014) 58%, var(--tone-070809) 100%);
  transition: background .2s;
}
.p-card.sel .p-shot {
  background:
    radial-gradient(ellipse 74% 56% at 50% 34%, rgba(196,96,74,.26), transparent 70%),
    linear-gradient(178deg, var(--tone-1d1517) 0%, var(--tone-100b0c) 58%, var(--tone-070506) 100%);
}
/* The floor the figure stands on — a pool of shadow, so the bust is planted
   instead of floating in a gradient. */
.p-card .p-shot::after {
  content: ""; position: absolute; left: 12%; right: 12%; bottom: 0; height: 26%;
  background: radial-gradient(ellipse 50% 100% at 50% 100%, rgba(0,0,0,.72), transparent 72%);
  pointer-events: none;
}
.p-card .p-portrait {
  position: relative; z-index: 1;
  display: block; width: 100%; height: 100%; object-fit: cover;
  background: transparent;
  filter: contrast(1.04) saturate(.94);
  transition: transform .3s ease;
}
/* Only the rendered bust gets the push-in; the painted fallback is a fixed
   composition and cropping into it just loses the shoulders. */

/* Unit stencil, low in the frame — the dossier marking the painting used to
   carry in pixels, now real text that stays sharp at any size. */
.p-card .p-tag {
  position: absolute; left: 9px; bottom: 7px; z-index: 2;
  font: 700 7.5px/1 var(--font-mono);
  letter-spacing: .22em; text-transform: uppercase;
  color: rgba(214,204,182,.34); text-shadow: 0 1px 2px var(--ink);
}

.p-card .p-body {
  padding: 11px 12px 13px; text-align: left;
  border-top: 1px solid rgba(190,175,145,.09);
}
.p-card .p-name {
  display: block;
  font: 700 13px/1.1 var(--font-ui);
  letter-spacing: .14em; text-transform: uppercase; color: var(--tone-e5ddc9);
}
.p-card.sel .p-name { color: var(--cream-100); }
.p-card .p-role {
  display: block; margin-top: 5px;
  font: 400 11.5px/1.35 var(--font-ui); font-style: normal; letter-spacing: .04em; color: var(--tone-9a9488); opacity: .86;
}

.soldier-detail {
  width: min(640px, 100%);
  margin-top: 12px;
  padding: 10px 14px;
  text-align: center;
  border: 1px solid rgba(190,170,135,.16);
  border-radius: 4px;
  background: rgba(6,8,10,.62);
}
.soldier-detail .sd-blurb {
  margin: 0;
  font: 400 13px/1.5 var(--font-ui); font-style: normal; letter-spacing: .04em; color: var(--tone-c6bda8); opacity: .9;
}
.soldier-detail .sd-perk {
  margin: 6px 0 0;
  font: 700 10px/1.3 var(--font-mono);
  letter-spacing: .16em; text-transform: uppercase; color: var(--tone-c4a56a);
}
/* The perk is the one mechanical fact on the card, so it reads as a token
   rather than as a third line of prose. */
/* The badge carries the colour, so it must not be dimmed with the label. */

#callsign-row {
  display: flex; align-items: center; justify-content: center; gap: 11px;
  margin-top: 15px;
}

/* Earned treatments reuse the survivor rig; these compact cards describe
   progression without turning the soldier picker into a second full page. */
#cosmetic-loadout {
  width: min(900px, 100%);
  margin-top: 14px;
}
#cosmetic-title {
  margin: 0 0 7px;
  font: 700 11px/1.2 var(--font-mono);
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--tone-9f9786);
}
#cosmetic-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px;
}
.cosmetic-card {
  min-width: 0;
  min-height: 74px;
  padding: 9px;
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr);
  gap: 9px;
  text-align: left;
  color: var(--tone-d8d0be);
  border: 1px solid rgba(190,170,135,.25);
  border-radius: 4px;
  background: rgba(8,10,13,.88);
  font-family:var(--font-ui);
  cursor: pointer;
}
.cosmetic-card:hover {
  border-color: rgba(218,192,143,.68);
}
.cosmetic-card:focus-visible {
  border-color: rgba(218,192,143,.68);
  outline: 1px solid var(--focus-ring, var(--amber));
  outline-offset: 2px;
}
.cosmetic-card.sel {
  border-color: var(--danger);
  box-shadow: 0 0 0 1px rgba(192,68,54,.34);
}
.cosmetic-card.locked {
  color: var(--tone-77746c);
  cursor: not-allowed;
}
.cosmetic-swatch {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,.22);
  box-shadow: inset 0 0 9px rgba(0,0,0,.68);
}
.cosmetic-standard { background: var(--tone-6d7a5e); }
.cosmetic-cobalt { background: linear-gradient(135deg,var(--tone-263a42),var(--tone-5a9bb3)); }
.cosmetic-signal { background: linear-gradient(135deg,var(--tone-1a343d),var(--tone-83efff)); box-shadow: 0 0 10px rgba(120,231,255,.25); }
.cosmetic-afterglow { background: radial-gradient(circle,var(--tone-e69455) 0 18%,var(--tone-713218) 45%,var(--tone-17110d) 75%); }
.cosmetic-copy, .cosmetic-name, .cosmetic-description, .cosmetic-progress, .cosmetic-meter {
  display: block;
  min-width: 0;
}
.cosmetic-name {
  font: 700 12px/1.2 var(--font-ui);
  letter-spacing: .1em;
  text-transform: uppercase;
}
.cosmetic-description {
  margin-top: 3px;
  font: 400 12px/1.4 var(--font-ui);
  color: var(--paper-dim);
}
.cosmetic-progress {
  margin-top: 5px;
  font: 700 11px/1.3 var(--font-mono);
  letter-spacing: .05em;
  color: var(--tone-c9b184);
}
.cosmetic-meter {
  height: 3px;
  margin-top: 5px;
  overflow: hidden;
  background: rgba(255,255,255,.08);
}
.cosmetic-meter i {
  display: block;
  height: 100%;
  background: var(--tone-a34135);
}
#cosmetic-feedback {
  min-height: 16px;
  margin-top: 7px;
  text-align: center;
  font: 700 11px/1.3 var(--font-mono);
  letter-spacing: .08em;
  color: var(--tone-c7b481);
}

@media (max-width: 720px) {
  #cosmetic-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (orientation: landscape) and (max-height: 500px) {
  #cosmetic-loadout { width: min(900px, 86vw); margin-top: 7px; }
  #cosmetic-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 5px; }
  .cosmetic-card { min-height: 52px; padding: 7px; grid-template-columns: 20px minmax(0,1fr); gap: 6px; }
  .cosmetic-description { font-size: 10.5px; }
  .cosmetic-swatch { width: 20px; height: 20px; }
  .cosmetic-description, .cosmetic-meter { display: none; }
  .cosmetic-progress { margin-top: 3px; }
  #cosmetic-feedback { display: none; }
}
.cs-label {
  font: 700 9px/1 var(--font-mono); letter-spacing: .3em;
  text-transform: uppercase; color: var(--paper-faint);
}
#callsign {
  color: var(--tone-d8d0bb);
  font: 700 14px/1 var(--font-mono); letter-spacing: .16em;
}
#callsign-reroll {
  cursor: pointer; pointer-events: auto;
  width: 26px; height: 26px; border-radius: 3px;
  background: rgba(10,13,16,.75); border: 1px solid rgba(150,150,150,.24);
  color: var(--paper-mute); font-size: 14px; line-height: 1;
  transition: color .15s, border-color .15s;
}
#callsign-reroll:hover { color: var(--cream-500); border-color: var(--amber-dim); }

/* ------------------------------------------------------------ difficulty */

#diff-grid {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 11px; width: 100%; max-width: 900px;
}
#diff-grid .diff-card { flex: 1 1 200px; max-width: 260px; }
.diff-card {
  cursor: pointer; pointer-events: auto;
  display: flex; flex-direction: column; gap: 7px;
  padding: 14px 16px; text-align: left;
  background: linear-gradient(168deg, rgba(28,32,37,.94), rgba(10,12,15,.98));
  border: 1px solid var(--edge);
  border-radius: 4px; font-family:var(--font-ui);
  box-shadow: 0 10px 24px rgba(0,0,0,.5);
  transition: border-color .15s, background .15s, transform .15s;
}
.diff-card:hover { border-color: rgba(190,160,110,.5); transform: translateY(-2px); }
.diff-card.sel { background: rgba(96,22,16,.4); border-color: var(--denied); }
.dc-name {
  font: 700 14px/1 var(--font-ui);
  letter-spacing: .18em; text-transform: uppercase; color: var(--cream-600);
}
.diff-card.sel .dc-name { color: var(--cream-100); }
.dc-line { font: 400 11.5px/1.5 var(--font-ui); font-style: normal; letter-spacing: .04em; color: var(--tone-8b857a); opacity: .86; }

/* -------------------------------------------------------------- controls */

.ctl-tabs { display: flex; gap: 7px; margin-bottom: 15px; flex-wrap: wrap; justify-content: center; }
.ctl-tab {
  cursor: pointer; pointer-events: auto;
  padding: 10px 16px; border-radius: 3px; font-family:var(--font-ui);
  background: linear-gradient(168deg, rgba(28,32,37,.94), rgba(10,12,15,.98));
  border: 1px solid var(--edge);
  color: var(--tone-8b8579); font: 700 12px/1 var(--font-mono);
  letter-spacing: .16em; text-transform: uppercase;
  transition: color .15s, border-color .15s, background .15s;
}
.ctl-tab:hover { color: var(--cream-600); border-color: var(--steel-400); }
.ctl-tab.sel { color: var(--cream-100); background: rgba(96,22,16,.42); border-color: var(--denied); }
#ctl-list { margin-top: 0; min-width: min(520px, 90vw); }

/* -------------------------------------------------------------- touch fit */

/* Restore safe-area (the old 16/12 shorthand wiped notch insets) and hug edges. */
html.is-touch .mpage {
  width: min(1080px, 100%);
  padding: calc(6px + env(safe-area-inset-top,0px))
           max(6px, env(safe-area-inset-right,0px))
           calc(6px + env(safe-area-inset-bottom,0px))
           max(6px, env(safe-area-inset-left,0px));
}
html.is-touch .mpage-title { margin: 10px 0 6px; }
html.is-touch .menu-col { margin-top: 12px; gap: 6px; }
html.is-touch .menu-grid { margin-top: 10px; gap: 6px; }
html.is-touch h1.game-title { font-size: clamp(40px, 11vw, 72px); }
html.is-touch .subtitle { margin-top: 10px; }
html.is-touch #persona-grid { gap: 9px; }
html.is-touch #persona-grid .p-card { flex: 0 1 124px; }   /* the portrait and name carry it */
html.is-touch #diff-grid .diff-card { flex: 1 1 100%; max-width: none; }

/* On a phone the hover skew reads as a mistake and the transparent label is
   hard to hit with a thumb — give every menu button a real surface. */
html.is-touch .mbtn {
  transform: none;
  border: 1px solid var(--edge); border-radius: 0;
  background: linear-gradient(180deg, rgba(28,32,37,.94), rgba(10,12,15,.96));
  box-shadow: 0 10px 24px rgba(0,0,0,.5);
  padding: 13px 18px;
  min-height: 46px;
  font-size: 15px; letter-spacing: .13em;
  filter: none;
}
html.is-touch .mbtn::before { display: none; }
html.is-touch .mbtn:hover, html.is-touch .mbtn:focus-visible {
  transform: none;
  border-color: var(--edge-hot);
  background: linear-gradient(180deg, rgba(118,26,18,.88), rgba(58,12,8,.94));
}
html.is-touch .mbtn:focus-visible {
  outline: 1px solid var(--focus-ring, var(--amber));
  outline-offset: 2px;
}
html.is-touch .mbtn:active {
  transform: none;
  filter: brightness(.9);
  box-shadow: inset 0 2px 8px rgba(0,0,0,.45);
}
html.is-touch .mbtn.small { padding: 11px 16px; font-size: 13px; min-height: 44px; }
html.is-touch .mpage .action-bar .mbtn.back,
html.is-touch .mpage .action-bar .mbtn.go { border-radius: 0; }

/* Both of the above were cuts made to fit two questions on one page. Each
   question has a page of its own now, so on any viewport with real height the
   copy comes back: the roster can afford every soldier's line, and the night
   page can afford the stats you are actually choosing between. Short landscape
   viewports still cut them, further down — there the constraint is height, not
   crowding, and it does not go away. */
@media (min-height: 560px) {
  html.is-touch .p-card .p-blurb { display: block; }
  html.is-touch #persona-grid .p-card { flex: 0 1 152px; }
  html.is-touch .dc-stats { display: flex; }
  html.is-touch #diff-grid .diff-card { flex: 1 1 100%; max-width: none; }
}
/* Four cards want an even split, not a min-width basis: a basis wide enough to
   be readable fits three across a tablet and strands Creative alone on a row
   of its own. One column on a phone, a square 2x2 once there is room. */
@media (min-height: 560px) and (min-width: 620px) {
  html.is-touch #diff-grid .diff-card { flex: 1 1 calc(50% - 6px); max-width: 430px; }
}
/* Landscape phones have almost no vertical room, so the title page compresses. */
@media (orientation: landscape) and (max-height: 500px) {
  .gt-main { font-size: clamp(34px, 7vw, 56px); }
  .gt-file { letter-spacing: .2em; }
  .gt-sub { letter-spacing: .42em; text-indent: .42em; }
  .menu-col { margin-top: 16px; gap: 8px; }
  .subtitle { margin-top: 12px; }
  .menu-grid { margin-top: 14px; gap: 7px; }
  .mrow { gap: 7px; }
  .mtile { min-height: 44px; padding: 9px 12px; }
  .mtile.ghost { min-height: 44px; padding: 8px 12px; }
  .mpage-title { margin: 12px 0 8px; }
  #persona-grid .p-card { flex: 0 1 118px; }
  #callsign-row { margin-top: 10px; }
}

/* Creative is a sandbox rather than a difficulty step, so it reads differently
   from the three that sit on the same scale. */
.diff-card.creative { border-color: rgba(120,150,190,.26); }
.diff-card.creative:hover { border-color: rgba(130,175,225,.55); }
.diff-card.creative.sel { background: rgba(20,48,80,.44); border-color: var(--tone-4d82b8); }
.diff-card.creative.sel .dc-name { color: var(--tone-cfe4fb); }

/* ------------------------------------------------------------------- co-op */
/* The .coop-card / .cc-head / .cc-line / .cc-key / .cc-rooms / .cc-actions
   family styled the old three-panel co-op page. That page became the online
   card grid and the lobby, and none of those class names survive in the markup
   or the modules — they were only costing offline-install bytes. */
.cc-input {
  padding: 11px 13px; width: 100%;
  background: rgba(4,6,8,.6); border: 1px solid rgba(150,150,150,.24); border-radius: 3px;
  color: var(--cream-500); font: 700 20px/1 var(--font-mono);
  letter-spacing: .22em; text-align: center; text-transform: uppercase;
}
.cc-input:focus { border-color: var(--amber-dim); }
.cc-input:focus-visible {
  outline: 3px solid var(--amber-hot);
  outline-offset: 2px;
  border-color: var(--tone-d8bd82);
}
.cc-input::placeholder { color: var(--tone-4b4d52); }

.cc-status {
  max-width: 620px; margin-top: 18px;
  font: 700 10.5px/1.6 var(--font-mono);
  letter-spacing: .1em; color: var(--tone-7c7568);
}
.cc-status.ok  { color: var(--tone-8fbb84); }
.cc-status.bad { color: var(--tone-c4776c); }

.cc-room {
  font: 700 11.5px/1.5 var(--font-mono); font-style: normal;
  letter-spacing: .08em; color: var(--cream-800);
}

.cc-check {
  display: flex; align-items: center; gap: 8px;
  font: 400 11.5px/1.4 var(--font-ui); font-style: normal; letter-spacing: .04em; color: var(--paper-dim, var(--paper-mute));
  cursor: pointer;
  /* Always ≥44px — not only under is-touch (U05). */
  min-height: 44px;
}
.cc-check input { width: 16px; height: 16px; flex: 0 0 auto; accent-color: var(--amber-dim); cursor: pointer; }
html.is-touch .cc-check input { width: 20px; height: 20px; }

.mpage[data-for="coop"] .menu-col {
  width: min(720px, 100%);
  max-width: 720px;
  box-sizing: border-box;
}

/* -------------------------------------------------------------------- pause */
/* Its own button language, distinct from the title menu's bare skewed labels:
   every action is visibly a BUTTON — bordered box, filled on hover — because
   "I did not realise Resume was a button" is real feedback. The primary action
   is red at all times, not only on hover. */
.pause-panel { text-align: center; }
#pause-screen.screen {
  justify-content: stretch;
  align-items: stretch;
  padding: 0;
  background: rgba(7, 9, 10, .88);
  backdrop-filter: blur(8px) saturate(.55);
  -webkit-backdrop-filter: blur(8px) saturate(.55);
}
/* Opened from the title there is no game world behind this panel — only the
   menu page that launched it, whose headings ghosted through the 88% scrim
   and read as a rendering bug. Solid ink; the blur has nothing to blur. */
#pause-screen.screen[data-from-title="1"] {
  background: rgb(4, 5, 6);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
#pause-screen .panel.pause-panel {
  width: 100%;
  max-width: none;
  min-height: 100%;
  margin: 0;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  background:
    linear-gradient(180deg, rgba(18,20,24,.42), rgba(5,6,8,.9));
  padding:
    calc(36px + env(safe-area-inset-top, 0px))
    clamp(20px, 6vw, 80px)
    calc(28px + env(safe-area-inset-bottom, 0px));
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
}
#pause-screen .pause-actions {
  width: min(460px, 100%);
  /* .pause-main shrink-wraps to its widest child (the 560px stats row), so
     without auto margins this 460px column sat visibly left of the PAUSED
     heading. Same family of bug as the scaleX note on the h2 below. */
  margin-inline: auto;
  flex-direction: column;
  align-items: stretch;
  gap: 8px;
}
#pause-screen .pause-actions .pbtn {
  max-width: none;
  width: 100%;
  min-height: 48px;
  letter-spacing: .16em;
  box-shadow: inset 0 1px 0 rgba(255,240,215,.1), 0 8px 22px rgba(0,0,0,.4);
}
/* `.panel.pause-panel h2`, not `.pause-panel h2`: theme.css sets
   `.panel h2{transform:scaleX(.9);transform-origin:left}` at equal specificity
   and loads later, so the plain form lost and PAUSED was condensed toward the
   panel's left edge — centred text that visibly is not centred. */
.panel.pause-panel h2 { transform: none; width: 100%; text-align: center; }
.pause-run-stats {
  display: flex; flex-wrap: wrap; justify-content: center;
  /* 660, not 560: at 560 the six stats wrapped after HEALTH and its trailing
     separator dot dangled at the line end with nothing after it. */
  gap: 8px 6px; max-width: 660px; margin: 14px auto 0;
  font: 700 11px/1.4 var(--font-mono);
  letter-spacing: .1em; text-transform: uppercase; color: var(--paper-mute);
}
.pause-run-stats span { white-space: nowrap; }
.pause-run-stats span:not(:last-child)::after {
  content: "·";
  margin: 0 8px 0 10px;
  color: var(--copper);
  opacity: .7;
}
.pause-run-stats b {
  color: var(--cream-500);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}

.pause-actions {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 10px;
  margin-top: 26px;
}
.pbtn {
  flex: 1 1 auto; min-width: 132px; max-width: 240px;
  min-height: 44px;
  padding: 13px 20px;
  border: 1px solid var(--edge); border-radius: 0;
  background: linear-gradient(180deg, rgba(28,22,16,.94), rgba(10,8,6,.96));
  color: var(--paper);
  font: 800 15px/1 var(--font-display);
  letter-spacing: .12em; text-transform: uppercase;
  text-shadow: 1px 2px 2px var(--ink);
  cursor: pointer;
  transition: background var(--dur-fast, .12s) var(--ease-out, ease),
    border-color var(--dur-fast, .12s), color var(--dur-fast, .12s),
    transform var(--dur-fast, .12s) var(--ease-out, ease);
}
.pbtn:active { transform: translateY(1px); filter: brightness(.92); }
.pbtn:disabled, .pbtn[disabled],
.mbtn:disabled, .mbtn[disabled] {
  opacity: .42;
  color: var(--paper-mute);
  border-color: rgba(190, 170, 135, .12);
  background: rgba(12, 10, 8, .72);
  box-shadow: none;
  cursor: not-allowed;
  filter: none;
  transform: none;
}
.pbtn:disabled:hover, .pbtn[disabled]:hover,
.mbtn:disabled:hover, .mbtn[disabled]:hover,
.pbtn:disabled:focus-visible, .pbtn[disabled]:focus-visible {
  border-color: rgba(190, 170, 135, .12);
  background: rgba(12, 10, 8, .72);
  color: var(--paper-mute);
  box-shadow: none;
}
.pbtn:hover {
  border-color: var(--amber-dim);
  background: rgba(40, 34, 24, .85); color: var(--cream-300);
}
.pbtn:focus-visible {
  border-color: var(--amber-dim);
  background: rgba(40, 34, 24, .85); color: var(--cream-300);
  outline: 1px solid var(--focus-ring, var(--amber));
  outline-offset: 2px;
}
/* Resume/Deploy: red, bordered, unmistakably the main action. */
.pbtn.primary {
  border: 1px solid var(--blood);
  background: linear-gradient(180deg, var(--blood), var(--blood-deep));
  color: var(--cream-200);
  box-shadow: 0 0 14px rgba(93, 16, 10, .28), inset 0 1px rgba(255, 220, 180, .08);
}
.pbtn.primary:hover, .pbtn.primary:focus-visible {
  background: linear-gradient(180deg, var(--blood-hot), var(--blood-deep));
  border-color: var(--danger-hot); color: var(--cream-100);
}

/* Two views, switched by a data attribute on the screen. */
#pause-screen .pause-settings,
#pause-screen .pause-objectives { display: none; }
#pause-screen[data-view="settings"] .pause-settings { display: flex; }
#pause-screen[data-view="objectives"] .pause-objectives { display: block; }
#pause-screen[data-view="settings"] .pause-main,
#pause-screen[data-view="objectives"] .pause-main { display: none; }

/* ---- pause: co-op squad, and the field ledger ---- */
.pause-squad {
  margin: 16px 0 4px;
  padding: 12px 14px;
  background: rgba(6,9,12,.7);
  border: 1px solid rgba(190,170,135,.16);
  border-radius: 3px;
  text-align: left;
}
.pause-squad[hidden] { display: none !important; }
.pause-squad-head {
  display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap;
  margin-bottom: 8px;
  color: var(--paper-mute);
  font: 700 10px/1.4 var(--font-mono);
  letter-spacing: .2em; text-transform: uppercase;
}
#pause-connection.bad { color: var(--tone-d8837a); }
#pause-connection.warn { color: var(--tone-e8b473); }
#pause-connection.good { color: var(--rot-green); }
.pause-squad ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 5px; }
.pause-squad li {
  display: flex; justify-content: space-between; gap: 12px;
  color: var(--cream-600);
  font: 700 13px/1.35 var(--font-ui);
  overflow-wrap: anywhere;
}
.pause-squad li span { color: var(--paper-mute); font: 700 11px/1.4 var(--font-mono); letter-spacing: .1em; }
.pause-squad li.down span { color: var(--tone-d8837a); }

.pause-objectives { text-align: left; max-width: 640px; margin: 6px auto 0; }
.pause-minimap-wrap { display: none; }
@media (max-width: 480px), (max-height: 430px) {
  .pause-minimap-wrap { display: block; margin: 14px 0 4px; }
  #pause-minimap {
    display: block;
    width: 152px; height: 152px;
    margin: 0 auto;
    background: rgba(7, 9, 10, .55);
    border: 1px solid rgba(215, 195, 157, .28);
    border-radius: 50%;
  }
  .pause-minimap-note {
    margin: 8px 0 0;
    color: var(--paper-mute);
    font: 700 10px/1.4 var(--font-mono);
    letter-spacing: .16em;
    text-transform: uppercase;
    text-align: center;
  }
}
.pause-sub {
  margin: 18px 0 8px;
  color: var(--paper-mute);
  font: 700 10px/1 var(--font-mono);
  letter-spacing: .3em; text-transform: uppercase;
}
.pause-sub:first-child { margin-top: 6px; }
.ledger-order {
  padding: 13px 15px;
  background: rgba(8,10,12,.8);
  border-left: 3px solid var(--amber);
}
.ledger-kicker { color: var(--amber); font: 700 10px/1.2 var(--font-mono); letter-spacing: .22em; text-transform: uppercase; }
.ledger-title { margin-top: 5px; color: var(--paper-bright); font: 800 18px/1.2 var(--font-display); letter-spacing: .04em; text-transform: uppercase; }
.ledger-detail { margin-top: 5px; color: var(--cream-900); font: 400 13px/1.5 var(--font-ui); }
.ledger-meta { display: flex; gap: 16px; flex-wrap: wrap; margin-top: 8px; color: var(--amber); font: 700 12px/1.2 var(--font-mono); letter-spacing: .1em; text-transform: uppercase; }
.ledger-legend { display: grid; gap: 8px; margin: 0; }
.ledger-legend > div { display: grid; grid-template-columns: minmax(96px, 150px) 1fr; gap: 6px 14px; align-items: baseline; }
.ledger-legend dt { color: var(--cream-600); font: 700 12px/1.4 var(--font-mono); letter-spacing: .12em; text-transform: uppercase; }
.ledger-legend dd { margin: 0; color: var(--tone-b6ae9c); font: 400 13px/1.5 var(--font-ui); }
@media (max-width: 480px) {
  .ledger-legend > div { grid-template-columns: 1fr; }
}
.pause-settings .slider-row { justify-content: center; }

/* Stack when the panel gets narrow (phones); the flex-wrap handles the rest. */
/* Stack when the panel gets narrow (portrait phones). */
@media (max-width: 560px) {
  .pause-actions { flex-direction: column; align-items: stretch; }
  .pbtn { max-width: none; }
}
/* Landscape phones: height is the binding constraint, not width. A row of
   four 44px buttons fits an 844px width with room to spare and keeps every
   action on screen without scrolling the panel. */
@media (min-width: 561px) and (max-height: 500px) {
  .pause-actions { flex-wrap: nowrap; }
  .pbtn { min-width: 0; min-height: 44px; padding: 11px 10px; font-size: 13px; }
  .pause-actions { margin-top: 16px; }
  /* 46px "PAUSED" on a 390px-tall screen pushes every button off the fold —
     it is a label, not a billboard, so it comes down to the same scale as the
     menu buttons. */
  #pause-screen h2 { font-size: clamp(22px, 4vw, 30px); }
  /* Three 16px-spaced slider rows on the same short screen are half the
     panel — 9px of air is enough to keep them visually separate. */
  #pause-screen[data-view="settings"] .pause-settings { row-gap: 9px; margin-top: 12px; }
  .pause-settings .set-head { margin: 2px 0 0; }
}

/* The one forward action on each step — Next on the soldier page, Deploy on the
   night page: always red, always a visible box, same language as pause's Resume
   and the title menu's Start Game, rather than a bare label that only turns red
   on hover. */
#btn-deploy, .mbtn.go {
  /* Stamped primary plate — rivets from tokens.css ::before */
  transform: none;
  min-width: 300px; padding: 13px 20px;
  border: 1px solid var(--danger) !important; border-radius: var(--radius-0);
  background:
    linear-gradient(180deg, rgba(232,226,212,.1), transparent 42%),
    linear-gradient(180deg, var(--blood), var(--blood-deep));
  color: var(--cream-200);
  letter-spacing: .14em; text-transform: uppercase;
  box-shadow: 0 0 18px rgba(140, 20, 12, .35), inset 0 1px rgba(255, 220, 180, .18);
}
#btn-deploy:hover, #btn-deploy:focus-visible,
.mbtn.go:hover, .mbtn.go:focus-visible {
  transform: none;
  background:
    linear-gradient(180deg, rgba(232,226,212,.12), transparent 42%),
    linear-gradient(180deg, var(--blood-hot), var(--blood-deep));
  border-color: var(--danger-hot) !important; color: var(--cream-100);
}
#btn-deploy:active, .mbtn.go:active {
  transform: scale(var(--press-scale));
}
html.reduce-motion #btn-deploy:active,
html.reduce-motion .mbtn.go:active { transform: none; }
#btn-deploy:focus-visible,
.mbtn.go:focus-visible {
  outline: 1px solid var(--focus-ring, var(--amber));
  outline-offset: 2px;
}

/* ------------------------------------------------------------------ credits */
#title-screen[data-page="credits"],
#title-screen[data-page="legal"] { justify-content: flex-start; }
.mpage[data-for="credits"],
.mpage[data-for="legal"] {
  width: min(920px, 96vw);
  max-height: 100dvh;
  align-items: stretch;
  overflow-x: hidden;
  padding: calc(24px + env(safe-area-inset-top, 0px)) 18px
           calc(132px + env(safe-area-inset-bottom, 0px));
}
.mpage[data-for="credits"] .mpage-title,
.mpage[data-for="legal"] .mpage-title {
  flex: 0 0 auto;
  text-align: center;
}
.credits-body {
  width: 100%;
  max-width: 780px;
  min-width: 0;
  margin: 0 auto;
  padding: clamp(22px, 4vw, 44px);
  overflow-wrap: anywhere;
  text-align: left;
  user-select: text;
  -webkit-user-select: text;
  background:
    linear-gradient(168deg, rgba(24,27,31,.92), rgba(7,9,11,.97)),
    repeating-linear-gradient(0deg, transparent 0 3px, rgba(255,255,255,.018) 3px 4px);
  border: 1px solid rgba(190,170,135,.22);
  border-radius: 4px;
  box-shadow: 0 22px 60px rgba(0,0,0,.62), inset 0 1px rgba(255,240,215,.06);
}
.credits-body p,
.credits-body li { font: 400 13px/1.78 var(--font-ui); color: var(--tone-aaa395); }
.credits-body p { margin-bottom: 15px; }
.credits-body b { color: var(--cream-600); }
.credits-body a { color: var(--tone-b99a64); text-decoration: underline; pointer-events: auto; }
.credits-body a:hover { color: var(--cream-500); }
.credits-body a:focus-visible {
  outline: 3px solid var(--tone-e6c17f);
  outline-offset: 3px;
  border-radius: 2px;
  color: var(--tone-fff1cf);
}
.credits-body code {
  color: var(--tone-d8c8a8);
  font: .92em/1.4 var(--font-mono);
}
.legal-lead {
  margin-bottom: 28px !important;
  padding: 0 0 24px;
  border-bottom: 1px solid rgba(190,170,135,.18);
  color: var(--tone-c4bba8) !important;
  font-size: 14px !important;
}
/* A contents list inside the credits card, not a second card inside it. */
.legal-toc { margin: 0 0 4px; padding: 0 0 24px; border-bottom: 1px solid rgba(190,170,135,.18); }
.legal-toc h3 {
  margin: 0 0 12px;
  color: var(--cream-600);
  font: 700 12px/1.35 var(--font-mono);
  letter-spacing: .16em;
  text-transform: uppercase;
}
.legal-toc ol { columns: 2 220px; column-gap: 40px; margin: 0; padding-left: 20px; }
.legal-toc li { break-inside: avoid; padding-left: 3px; }
.legal-toc a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}
.legal-section {
  scroll-margin-top: calc(20px + env(safe-area-inset-top, 0px));
}
/* The credits TOC jumps to h4 anchors, not sections — same clearance. */
.legal-section > h4[id] {
  scroll-margin-top: calc(20px + env(safe-area-inset-top, 0px));
}
.legal-section > h3 {
  margin: 40px 0 13px;
  padding-top: 22px;
  border-top: 1px solid rgba(190,170,135,.14);
  color: var(--tone-c6a66d);
  font: 700 13px/1.45 var(--font-mono);
  letter-spacing: .1em;
  text-transform: uppercase;
}
.legal-section > h4 {
  margin: 24px 0 8px;
  color: var(--tone-d4cab5);
  font: 700 12px/1.5 var(--font-mono);
  letter-spacing: .06em;
}
.credits-priority { margin-top: 4px; }
.credits-priority > h3 {
  margin-top: 22px;
  border-top: 0;
  color: var(--amber-hot);
}
.cr-note { font-style: normal; letter-spacing: .04em; color: var(--paper-faint) !important; font-size: 11.5px !important; opacity: .86; }
.back-to-toc { font-family:var(--font-mono); }

/* Back is a persistent escape hatch on a long document. It used to be pinned
   to the viewport here; menu-cinematic.css sticks it to the bottom of the
   card instead, and gave these two buttons the same 8px flat treatment as
   every other .mbtn rather than a 3px gradient of their own. */

@media (max-width: 560px) {
  .credits-body p,
  .credits-body li { font-size: 12.5px; line-height: 1.72; }
  .legal-lead { font-size: 13px !important; }
  .legal-toc { padding: 0 0 20px; }
  .legal-toc ol { columns: 1; }
  .legal-section > h3 { letter-spacing: .07em; }
}

@media (max-height: 500px) and (orientation: landscape) {
  .mpage[data-for="credits"],
  html.is-touch .mpage[data-for="credits"] {
    padding-top: calc(10px + env(safe-area-inset-top, 0px));
    padding-left: max(10px, env(safe-area-inset-left, 0px));
    padding-right: max(10px, env(safe-area-inset-right, 0px));
  }
  .mpage[data-for="credits"] .mpage-title { margin-bottom: 8px; }
}

@media (prefers-reduced-motion: reduce) {
  .mpage[data-for="credits"],
  .mpage[data-for="credits"] *,
  .mpage[data-for="credits"] *::before,
  .mpage[data-for="credits"] *::after {
    scroll-behavior: auto !important;
    transition-duration: .01ms !important;
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
  }
}

/* ---------------------------------------------------------------------------
   The primary action must never be below the fold.

   On a landscape phone the loadout page is ~1233px tall (five soldier cards, a
   callsign row, four difficulty cards) inside a 390px viewport, which put Deploy
   at y=1156. The page scrolls, but a button 1150px down is not discoverable —
   this is why the game read as "won't let me start".

   Viewport-fixed native dock. Sticky sat at the bottom of the *content*, so on
   a tall screen the bar floated in the lower third with a black void under it.
   Fixed pins Back | Next / Deploy to the browser viewport at every size.
   Pages drop their entrance transform so they cannot become the containing
   block (an identity transform still would).
   --------------------------------------------------------------------------- */
.mpage[data-for="loadout"],
.mpage[data-for="treatments"],
.mpage[data-for="night"] {
  /* No entrance transform/animation: an identity or mid-animation transform
     makes this page the containing block for the fixed dock, so Back|Next
     starts inline and jumps to the viewport on first interaction — and the
     first NEXT tap misses. Fixed from first paint, no jump. */
  transform: none !important;
  animation: none !important;
  justify-content: flex-start;
  padding-bottom: calc(96px + env(safe-area-inset-bottom, 0px));
}
.mpage[data-for="loadout"] .menu-col.action-bar,
.mpage[data-for="treatments"] .menu-col.action-bar,
.mpage[data-for="night"] .menu-col.action-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  max-width: none;
  margin: 0;
  z-index: 8;
  flex-direction: row;
  flex-wrap: nowrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  box-sizing: border-box;
  padding: 12px max(18px, env(safe-area-inset-right, 0px))
           max(14px, env(safe-area-inset-bottom, 0px))
           max(18px, env(safe-area-inset-left, 0px));
  background: linear-gradient(180deg, rgba(3,4,6,0) 0%, rgba(3,4,6,.92) 32%, var(--steel-900) 100%);
  border-top: 1px solid rgba(190,160,110,.22);
  box-shadow: 0 -18px 40px rgba(0,0,0,.45);
}
.mpage[data-for="loadout"] .menu-col.action-bar .mbtn,
.mpage[data-for="treatments"] .menu-col.action-bar .mbtn,
.mpage[data-for="night"] .menu-col.action-bar .mbtn {
  min-width: 0;
  min-height: 48px;
}
.mpage[data-for="loadout"] .action-bar .mbtn.back,
.mpage[data-for="treatments"] .action-bar .mbtn.back,
.mpage[data-for="night"] .action-bar .mbtn.back {
  flex: 0 0 auto;
  min-width: 132px;
  width: auto;
  align-self: center;
}
.mpage[data-for="loadout"] .action-bar .mbtn.go,
.mpage[data-for="treatments"] .action-bar .mbtn.go,
.mpage[data-for="night"] .action-bar .mbtn.go,
.mpage[data-for="night"] .action-bar #btn-deploy {
  flex: 0 1 320px;
  min-width: 168px;
  max-width: 420px;
  margin-left: auto;
  align-self: center;
}
.mpage[data-for="coop"] .menu-col,
.mpage[data-for="lobby"] .menu-col {
  position: sticky;
  inset-block-end: 0;
  align-self: stretch;
  flex: 0 0 auto;
  width: 100%;
  margin: auto 0 0;
  padding: 12px max(4px, env(safe-area-inset-right)) max(12px, env(safe-area-inset-bottom)) max(4px, env(safe-area-inset-left));
  background: linear-gradient(180deg, rgba(3,4,6,0) 0%, rgba(3,4,6,.86) 26%, rgba(3,4,6,.985) 62%, var(--steel-900) 100%);
  border-top: 1px solid rgba(190,160,110,.16);
  z-index: 4;
}
/* Site / Ready / Coop: the same Back | primary reading order as the wizard
   dock — Back small on the left, the one red action wide on the right. These
   pages are short cards (no below-the-fold risk), so the row lives in-card
   instead of joining the fixed dock, but a player should never see Back ABOVE
   the button that moves them forward on one step and beside it on the next. */
/* 360px floor: Back(132) + gap + primary(168) + card padding does not fit a
   320px viewport — the matrix flagged Join unreachable there. Below the
   floor these bars keep the stacked column. */
@media (min-width: 360px) {
  .mpage[data-for="site"] .menu-col.action-bar,
  .mpage[data-for="ready"] .menu-col.action-bar,
  .mpage[data-for="coop"] .menu-col.action-bar {
    flex-direction: row;
    flex-wrap: nowrap;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
  }
  .mpage[data-for="site"] .action-bar .mbtn.back,
  .mpage[data-for="ready"] .action-bar .mbtn.back,
  .mpage[data-for="coop"] .action-bar .mbtn.back {
    flex: 0 0 auto;
    min-width: 132px;
    width: auto;
  }
  .mpage[data-for="site"] .action-bar .mbtn.go,
  .mpage[data-for="ready"] .action-bar .mbtn.go,
  .mpage[data-for="coop"] .action-bar .mbtn.go {
    flex: 1 1 auto;
    min-width: 168px;
    max-width: 420px;
    margin-left: auto;
  }
}
/* Lobby carries THREE actions (Leave / Ready / Start), which overflow a
   phone as a row — the layout matrix flagged Ready and Start unreachable at
   360-430px. Row only where three fit; phones keep the stack. */
@media (min-width: 700px) {
  .mpage[data-for="lobby"] .menu-col.action-bar {
    flex-direction: row;
    flex-wrap: nowrap;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
  }
  .mpage[data-for="lobby"] .action-bar .mbtn.back {
    flex: 0 0 auto;
    min-width: 132px;
    width: auto;
  }
  .mpage[data-for="lobby"] .action-bar .mbtn.go {
    flex: 1 1 auto;
    min-width: 168px;
    max-width: 420px;
    margin-left: auto;
  }
}

.mpage[data-for="treatments"] #cosmetic-title { display: none; }
/* The centred-island styling for #predeploy-accessibility used to live here,
   along with sizing for #predeploy-deploy-spacer — an element the markup no
   longer contains. menu-cinematic.css now owns that block outright at a higher
   specificity, so every rule here was dead weight in the offline install
   payload. Landscape clearance for it is asserted by check_controls.py. */
@media (orientation: landscape) and (max-height: 430px) {
  .mpage[data-for="night"] .menu-col.action-bar { z-index: 8; }
  .mpage[data-for="night"],
  html.is-touch .mpage[data-for="night"] {
    padding-bottom: calc(132px + env(safe-area-inset-bottom, 0px));
  }
}
@media (orientation: landscape) and (max-height: 430px) {
  /* Drop retained entrance transforms so Deploy is viewport-fixed again and
     can clear the accessibility block after scroll. */
  .mpage[data-for="night"],
  .mpage[data-for="loadout"],
  .mpage[data-for="coop"] {
    transform: none !important;
  }
}
#after-action-dossier {
  display: flex;
  flex-direction: column;
  gap: 7px;
  margin: 14px auto 0;
  max-width: 420px;
  padding: 14px 16px;
  color: var(--cream-800);
  background: rgba(8,10,10,.82);
  border-left: 3px solid var(--tone-9f7441);
  font: 700 12px/1.65 var(--font-mono);
  text-align: left;
  text-wrap: pretty;
  overflow-wrap: anywhere;
}
#after-action-dossier b { color: var(--tone-e8bd78); letter-spacing: .12em; }
#after-action-dossier .dossier-official { color: var(--tone-9a9588); margin-top: 6px; }
#after-action-dossier .dossier-recovered { color: var(--tone-d7c39a); }
#after-action-dossier .dossier-meta,
#after-action-dossier .dossier-pb { color: var(--tone-b9b0a0); font-weight: 600; }
#after-action-dossier .dossier-next { color: var(--amber-hot); font-weight: 700; margin-top: 6px; letter-spacing: .08em; }
/* Real near-record outcomes and unfinished objectives: the two lines that
   turn "Signal Lost" into a reason to redeploy. Same dossier palette. */
#after-action-dossier .dossier-near { color: var(--amber-hot); font-weight: 700; margin-top: 6px; }
#after-action-dossier .dossier-unfinished { color: var(--tone-d7c39a); font-weight: 600; }
#after-action-dossier .dossier-archive { color: var(--tone-9a9588); font-weight: 600; }

/* Requisition Archive completion header on the Cache Index screen. */
.cache-index-progress {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 0 0 14px;
  font: 700 11px/1.4 var(--font-mono);
  color: var(--tone-d7c39a);
  letter-spacing: .06em;
}
.cache-index-progress .cache-progress-track {
  display: block;
  height: 5px;
  background: rgba(255,255,255,.08);
  border: 1px solid rgba(255,255,255,.12);
}
.cache-index-progress .cache-progress-track i {
  display: block;
  height: 100%;
  background: var(--tone-9f7441);
}
/* Room so the last card is not stuck behind the fixed bar. The bar is exactly
   one row tall at every width by construction (see .action-bar below), so this
   is a derived number and not a guess: 14 top + 48 button + 14 bottom + 1
   border = 77, plus clearance, plus whatever the home indicator takes.

/* The bar is in the flow now, so nothing has to be reserved for it. What is
   left is ordinary breathing room under the last card. */
.mpage[data-for="coop"],
.mpage[data-for="lobby"] { padding-bottom: 0; }

/* A short viewport also needs the cards themselves to be smaller, or scrolling
   past five of them to reach the difficulty choice is a chore. */
@media (max-height: 460px) {
  #persona-grid .p-card { flex: 0 1 122px; }
  #persona-grid .p-card .p-blurb,
  #persona-grid .p-card .p-perk { display: none; }
  #persona-grid .p-card .p-body { padding: 6px 8px 8px; }
  .mpage-title { margin: 10px 0 7px; }
  #diff-grid .diff-card { padding: 9px 11px; }
  .dc-line { display: none; }
}

/* ---------------------------------------------------------------------------
   Minimum tap targets, applied at the base rather than only under .is-touch.

   A sweep at 844x390 found ten controls under the 44px minimum — every menu
   button (37px and 30px), the callsign reroll (24px), the join/host buttons and
   the controls tabs. The is-touch overrides did cover some of these, but they
   only apply when platform detection says touch-first, so a small desktop
   window, a touchscreen laptop, or the game in an iOS webview that reports
   oddly all got the cramped version. Sizing them properly everywhere costs
   nothing on a mouse and removes a whole class of "I tapped it and nothing
   happened".
   --------------------------------------------------------------------------- */
.mbtn { min-height: 48px; }
.mbtn.small { min-height: 44px; }
.pbtn { min-height: 44px; }
.diff-btn { min-height: 44px; }
.cc-check { min-height: 44px; }
/* range thumbs are drag targets; 34px of track is the comfortable floor */
.slider-row input { height: 34px; }
#callsign-reroll { width: 44px; height: 44px; font-size: 18px; }
.ctl-tab { min-height: 44px; padding: 12px 16px; }
.diff-card { min-height: 44px; }
.p-card { min-height: 44px; }
#coop-input { min-height: 48px; }
#btn-copy-key, #btn-host, #btn-join { min-height: 44px; }
#tc-pause, #tc-more { min-width: 44px; min-height: 44px; }

/* screens.css switches short viewports to `justify-content:flex-start`, so a
   panel taller than the screen can be scrolled to from its top rather than
   being centred — centred content that overflows a flex container clips
   upward, and the clipped-off part cannot be scrolled back to. theme.css then
   re-set `.screen{justify-content:center}` at equal specificity and, loading
   later, silently won: on a 390px-tall landscape phone the top of the pause
   panel — Resume, in the main view — was unreachable. Restated here with the
   specificity to hold. #title-screen keeps its own centring (id beats this). */
@media (max-height: 620px) {
  html .screen { justify-content: flex-start; }
}

/* ===========================================================================
   HOME PAGE — the 3 + 2 block
   ===========================================================================

   Three ways into a game on the top row, the two reference pages on a shorter
   row beneath. The five-item column this replaced made Credits and Start Game
   the same weight and the same shape, so the page had to be read rather than
   recognised.

   Grid, not flex-wrap: the two rows must stay 3-up and 2-up at every width
   they are allowed at all, and a wrapping flex row would reflow them into
   3+1+1 at awkward sizes on its own schedule.
   =========================================================================== */

.menu-grid {
  display: flex; flex-direction: column; align-items: center;
  gap: 12px; width: 100%;
  margin-top: clamp(26px, 4.5vh, 46px);
}
.mrow { display: grid; gap: 12px; width: 100%; }
/* The 2-row is deliberately narrower than the 3-row and centred under it —
   equal width would read as a broken 3-column grid missing a cell. */
/* Controls lives in the footer on desktop so the 3-up grid stays optically
   centred. Touch keeps the Minecraft-style stacked Controls tile. */
/* The returning player's quiet row: same soldier and night, one press.
   Full tile width keeps it read as part of the block, not a stray chip. */
.mrow-1 { grid-template-columns: minmax(0, 1fr); max-width: 792px; }
.mtile.slim { min-height: 44px; padding: 10px 18px; font-size: 13.5px; }
.mtile.slim .mt-note { margin-top: 3px; min-height: 0; }

/* Each way into the game says what it does under its own name. "Play Online"
   put a player into a live public round with strangers; the label could not
   have told them that, and the note under the name now does. */
.mt-name { display: block; }
.mt-note {
  display: block;
  margin-top: 5px;
  min-height: 1.35em;
  color: var(--paper-mute);
  font: 400 11px/1.35 var(--font-ui); font-style: normal;
  letter-spacing: .04em; text-transform: none;
  opacity: .82;
}
.mtile:hover .mt-note, .mtile:focus-visible .mt-note { color: var(--tone-d8cdb6); opacity: 1; }
.mtile.primary .mt-note { color: var(--tone-e2bfae); opacity: .9; }

.home-online-price {
  max-width: 42rem;
  margin: 14px auto 6px;
  padding: 0 12px;
  color: #e6dcc4;
  font: 400 13px/1.45 var(--font-ui);
  text-wrap: pretty;
}
.home-online-more {
  max-width: 36rem;
  margin: 0 auto 10px;
  padding: 0 12px;
  color: #c4bba8;
  font: 400 12px/1.45 var(--font-ui);
  /* Centred like every other line in this card — the collapsed "What's
     this?" chip sat left-of-centre and read as an orphan. */
  text-align: center;
}
.home-online-more summary {
  cursor: pointer;
  color: #c08a48;
  font: 600 11px/1.4 var(--font-mono);
  letter-spacing: .06em;
  text-transform: uppercase;
  list-style: none;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}
.home-online-more summary::-webkit-details-marker { display: none; }
.home-online-more[open] summary { margin-bottom: 6px; }
.home-online-more p { margin: 0; text-wrap: pretty; }
.home-trial-status {
  margin: 0 auto 8px;
  max-width: 36rem;
  color: #c08a48;
  font: 600 12px/1.4 var(--font-mono);
  letter-spacing: .04em;
}
.home-trial-status[data-state="ok"] { color: #c4bba8; }
.home-trial-status[data-state="ending"] { color: #c08a48; }
.home-trial-status[data-state="ended"] { color: #bd2417; }
.home-subscribe {
  min-height: 44px;
  margin: 0 auto 4px;
  padding: 10px 16px;
  border: 1px solid rgba(189, 36, 23, .55);
  background: rgba(12, 10, 8, .72);
  color: #e6dcc4;
  font: 600 12px/1 var(--font-display);
  letter-spacing: .14em;
  text-transform: uppercase;
  cursor: pointer;
}
.home-subscribe:hover,
.home-subscribe:focus-visible {
  color: #fff6e8;
  border-color: #bd2417;
  outline: 2px solid #e6c17f;
  outline-offset: 2px;
}

.mtile {
  position: relative; overflow: hidden;
  cursor: pointer; pointer-events: auto;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  min-height: 86px;
  padding: 16px 18px 16px calc(18px + .14em);
  font-family:var(--font-display);
  font-size: clamp(15px, 1.35vw, 18px); font-weight: 800;
  letter-spacing: .18em; text-transform: uppercase; text-align: center;
  line-height: 1.12;
  color: var(--paper);
  background:
    repeating-linear-gradient(0deg, transparent 0 2px, rgba(0,0,0,.04) 2px 3px),
    linear-gradient(180deg, rgba(255,240,215,.06), transparent 14%),
    linear-gradient(180deg, rgba(28,22,16,.96), rgba(10,8,6,.98));
  border: 1px solid var(--edge); border-radius: 2px;
  box-shadow:
    inset 0 1px 0 rgba(255,240,215,.06),
    inset 0 -2px 0 rgba(0,0,0,.45),
    0 14px 34px rgba(0,0,0,.58);
  transition: color var(--dur-fast, .16s) var(--ease-out, ease),
    border-color var(--dur-fast, .16s), background var(--dur-fast, .16s),
    transform var(--dur-fast, .16s) var(--ease-out, ease),
    box-shadow var(--dur-fast, .16s);
}
/* display:flex above beats the UA [hidden] { display:none }. Without this,
   Deploy last night stays painted on a first visit and the click no-ops. */
.mtile[hidden] { display: none !important; }
.mrow-1:has(#btn-last-night[hidden]) { display: none; }
/* The old 2px tick is gone; the whole edge lights up now, so the hover is
   unmistakable on a phone where there is no cursor. */
.mtile::before {
  content:""; position:absolute; inset:0; pointer-events:none;
  border: 1px solid transparent; border-radius: inherit;
  transition: border-color var(--dur-fast, .16s);
}
.mtile:hover {
  color: var(--tone-f4ecd9);
  border-color: rgba(190,170,135,.55);
  background:
    repeating-linear-gradient(0deg, transparent 0 2px, rgba(0,0,0,.04) 2px 3px),
    linear-gradient(180deg, rgba(255,240,215,.06), transparent 14%),
    linear-gradient(180deg, rgba(40,32,24,.96), rgba(14,11,8,.98));
  box-shadow:
    inset 0 1px 0 rgba(255,240,215,.08),
    0 18px 40px rgba(0,0,0,.62);
  transform: translateY(-3px);
}
.mtile:focus-visible {
  color: var(--tone-f4ecd9);
  border-color: rgba(190,170,135,.55);
  background:
    repeating-linear-gradient(0deg, transparent 0 2px, rgba(0,0,0,.04) 2px 3px),
    linear-gradient(180deg, rgba(255,240,215,.06), transparent 14%),
    linear-gradient(180deg, rgba(40,32,24,.96), rgba(14,11,8,.98));
  box-shadow:
    inset 0 1px 0 rgba(255,240,215,.08),
    0 18px 40px rgba(0,0,0,.62);
  transform: translateY(-3px);
  outline: 1px solid var(--focus-ring, var(--amber));
  outline-offset: 3px;
}
.mtile:active { transform: translateY(0); filter: brightness(.93); }

/* The one action on the page is the one red button. Everything else stays
   paper-on-soot until the player points at it. */
.mtile.primary {
  color: var(--cream-100); border-color: var(--blood);
  background:
    linear-gradient(180deg, rgba(255,240,215,.06), transparent 14%),
    linear-gradient(180deg, var(--blood), var(--blood-deep));
  box-shadow:
    inset 0 1px 0 rgba(255,220,180,.1),
    inset 0 -2px 0 rgba(0,0,0,.35),
    0 0 18px rgba(93,16,10,.32),
    0 16px 36px rgba(0,0,0,.55);
}
.mtile.primary:hover, .mtile.primary:focus-visible {
  background:
    linear-gradient(180deg, rgba(255,240,215,.08), transparent 14%),
    linear-gradient(180deg, var(--blood-hot), var(--blood-deep));
  border-color: var(--danger-hot); color: var(--tone-fff8ee);
}

/* Controls and Credits are reference, not action: quieter, shorter, smaller. */
.mtile.ghost {
  min-height: 44px;
  padding: 11px 14px 11px calc(14px + .2em);
  font-size: clamp(11px, 1.05vw, 13px); letter-spacing: .2em;
  color: var(--paper-dim);
  background: linear-gradient(180deg, rgba(22,18,14,.78), rgba(8,6,5,.9));
  border-color: var(--edge);
  box-shadow: none;
}
.mtile.ghost:hover, .mtile.ghost:focus-visible {
  color: var(--tone-e9e0cb); border-color: rgba(190,170,135,.4);
}

/* Under ~700px the three action tiles cannot hold their labels on one line
   without shrinking the type past legibility, so they stack. The reference
   row stays 2-up — it is short enough to survive, and keeping it paired holds
   the shape of the block. */
@media (max-width: 700px) {
  .mrow-3 { grid-template-columns: minmax(0, 1fr); max-width: 360px; }
  .mrow-2 { grid-template-columns: minmax(0, 1fr); max-width: 360px; }
  .mrow-1 { max-width: 360px; }
  .mtile { min-height: 62px; font-size: 15px; }
  .mt-note { font-size: 10.5px; }
}

/* The centred title, subtitle and page headings all carry heavy tracking, and
   tracking is emitted after the final glyph as well — every one of them sits
   half a unit left of centre until it is told not to. */
.mpage .subtitle { text-indent: .185em; }
.mpage-title { text-indent: .21em; }

/* --------------------------------------------------------- corner readouts */
/* Best run bottom-left, studio credit bottom-right, both pinned to the screen
   and both shown only on the home page. */
#title-screen .corner-stat { display: none; }
#title-screen[data-page="home"] .corner-stat { display: block; }

#title-screen .best-line.corner-stat,
#title-screen #studio-credit.corner-stat {
  position: fixed; z-index: 3; margin: 0;
  bottom: max(8px, env(safe-area-inset-bottom));
  font: 700 10px/1.7 var(--font-mono);
  letter-spacing: .28em; text-transform: uppercase;
  color: var(--paper-dim, var(--paper-mute)); pointer-events: none;
}
#title-screen .best-line.corner-stat {
  left: max(10px, env(safe-area-inset-left)); right: auto;
  text-align: left;
}
#title-screen #studio-credit.corner-stat {
  right: max(10px, env(safe-area-inset-right)); left: auto;
  text-align: right;
}
#title-screen .best-line.corner-stat b { color: var(--tone-a89d88); font-size: 10px; }
.best-line .cs-dot { margin: 0 .7em; font-style: normal; opacity: .5; }

/* Narrow screens: the two readouts reach for the same middle. They used to be
   squeezed to 8px and split awkwardly across two corners; 8px of tracked-out
   monospace is not a readout, it is texture. Below 640px they stop competing
   for the corners and become one centred, legible footer line. */
@media (max-width: 640px) {
  #title-screen .best-line.corner-stat,
  #title-screen #studio-credit.corner-stat {
    position: static;
    display: none;
    max-width: min(360px, 92vw);
    margin: 0 auto;
    font-size: 11px; letter-spacing: .12em; line-height: 1.7;
    text-align: center;
  }
  #title-screen[data-page="home"] .best-line.corner-stat,
  #title-screen[data-page="home"] #studio-credit.corner-stat {
    display: block;
  }
  #title-screen[data-page="home"] .best-line.corner-stat { margin-top: 22px; }
  #title-screen[data-page="home"] #studio-credit.corner-stat { margin-bottom: 6px; }
  #title-screen .best-line.corner-stat b { font-size: 12px; }
}

/* ------------------------------------------------------- pause: settings */
/* Three independently-centred flex rows meant no two sliders began at the same
   x, and the graphics row still carried `margin-left:19px` from the old
   left-aligned layout, so it sat off-centre under them. One grid, one column
   set, one centred stack. */
/* One grid for the whole block, not one per row. A grid per row cannot align
   anything: each row sizes its own label column, so Volume, Music and
   Brightness each started their track at a different x. The rows are
   display:contents so their label/track/value become items of the SHARED
   grid — one label column, sized to the widest of the three, and three tracks
   that line up because they are literally the same column. */
/* The shared grid moved down one level when Settings gained tabs: the grid now
   belongs to the visible PANEL, and .pause-settings is just the frame that
   holds the tab strip, the panel and the Back button. */
#pause-screen[data-view="settings"] .panel.pause-panel {
  justify-content: flex-start;
  height: 100%;
  max-height: 100%;
  overflow: hidden;
  padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px));
}
#pause-screen[data-view="settings"] .panel.pause-panel > h2 {
  flex: 0 0 auto;
  margin-bottom: 0;
}
#pause-screen[data-view="settings"] .pause-settings {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  flex: 1 1 auto;
  min-height: 0;
  width: min(880px, 92vw);
  margin: 12px auto 0;
}
.pause-settings .set-tabs {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 4px;
  flex: 0 0 auto;
  width: 100%; margin: 0 0 10px;
  padding-bottom: 10px; border-bottom: 1px solid rgba(190,160,110,.16);
}
.pause-settings .set-tab {
  flex: 1 1 auto; min-height: 44px; padding: 10px 12px;
  border: 1px solid rgba(150,150,150,.2); border-radius: 3px;
  background: rgba(10,13,16,.7); color: var(--paper-mute);
  font: 700 10px/1 var(--font-mono);
  letter-spacing: .1em; text-transform: uppercase;
  cursor: pointer; pointer-events: auto;
}
.pause-settings .set-tab:hover { color: var(--cream-600); border-color: var(--steel-400); }
.pause-settings .set-tab.sel {
  color: var(--paper-bright); background: rgba(120,25,18,.42); border-color: var(--denied);
}
.pause-settings .set-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
  padding: 4px 8px 28px;
  mask-image: linear-gradient(180deg, transparent 0, #000 12px, #000 calc(100% - 18px), transparent 100%);
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 12px, #000 calc(100% - 18px), transparent 100%);
  scrollbar-width: thin;
  scrollbar-color: rgba(216,208,186,.35) transparent;
}
.pause-settings .set-body::-webkit-scrollbar { width: 6px; }
.pause-settings .set-body::-webkit-scrollbar-track { background: transparent; }
.pause-settings .set-body::-webkit-scrollbar-thumb {
  background: rgba(216,208,186,.35); border-radius: 99px;
}
.pause-settings .set-panel {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 14px;
  width: 100%;
  max-width: 720px;
  margin: 0 auto;
}
.pause-settings .set-panel[hidden] { display: none; }
.pause-settings .set-note {
  margin: 0; max-width: none;
  color: var(--paper-mute); font: 400 11.5px/1.5 var(--font-ui); font-style: normal;
  letter-spacing: .04em; text-align: center; opacity: .86;
}
.pause-settings .set-note b { color: var(--cream-600); font-style: normal; }
.pause-settings #set-wedge { margin: 0; }
.pause-settings #touch-settings {
  display: flex;
  flex-direction: column;
  gap: 14px;
  width: 100%;
}
.pause-settings #touch-settings[hidden] { display: none; }
.pause-settings .hand-row { display: flex; justify-content: center; gap: 8px; margin: 0; }
.pause-settings .hand-row .diff-btn { flex: 1 1 0; }
.pause-settings .slider-row {
  display: grid;
  grid-template-columns: minmax(7.5em, 9.5em) minmax(260px, 1fr) 4.6em;
  align-items: center;
  column-gap: 12px;
  width: 100%;
  min-height: 44px;
  padding: 4px 6px;
  box-sizing: border-box;
  cursor: pointer;
}
.pause-settings .slider-row:focus-within {
  outline: 1px solid var(--focus-ring, var(--amber));
  outline-offset: 2px;
}
.pause-settings .slider-row label {
  text-align: left;
  font: 700 11px/1.2 var(--font-mono);
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--paper-mute);
}
.pause-settings .slider-control {
  display: grid;
  grid-template-columns: 2.4em minmax(0, 1fr) 2.4em;
  align-items: center;
  gap: 8px;
  min-width: 260px;
}
.pause-settings .slider-min,
.pause-settings .slider-max {
  font: 600 9px/1 var(--font-mono);
  letter-spacing: .06em;
  color: var(--paper-faint);
  font-variant-numeric: tabular-nums;
}
.pause-settings .slider-min { text-align: right; }
.pause-settings .slider-max { text-align: left; }
.pause-settings .slider-row input { width: 100%; min-width: 0; }
.pause-settings .slider-row .val {
  min-width: 0; text-align: right;
  font: 700 12px/1 var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--paper);
}

/* A thumb that is actually a thumb, not the 6px dot WebKit draws on a
   34px-tall input. Same accent for every slider so volume / music /
   brightness read as a matched set. */
.pause-settings .slider-row input[type="range"] {
  -webkit-appearance: none; appearance: none;
  height: 34px; background: transparent;
  --fill: 50%;
}
.pause-settings .slider-row input[type="range"]::-webkit-slider-runnable-track {
  height: 4px; border-radius: 999px;
  background: linear-gradient(90deg, var(--paper) var(--fill), rgba(216,208,186,.22) var(--fill));
}
.pause-settings .slider-row input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 22px; height: 22px; border-radius: 50%;
  margin-top: -9px;
  background: radial-gradient(circle at 36% 30%, var(--tone-f2ece0), var(--tone-9b9280));
  border: 1px solid var(--tone-3b362e);
  box-shadow: 0 2px 5px rgba(0,0,0,.7);
}
.pause-settings .slider-row input[type="range"]::-moz-range-track {
  height: 4px; border-radius: 999px;
  background: rgba(216,208,186,.22);
}
.pause-settings .slider-row input[type="range"]::-moz-range-progress {
  height: 4px; border-radius: 999px;
  background: var(--paper);
}
.pause-settings .slider-row input[type="range"]::-moz-range-thumb {
  width: 22px; height: 22px; border-radius: 50%;
  background: radial-gradient(circle at 36% 30%, var(--tone-f2ece0), var(--tone-9b9280));
  border: 1px solid var(--tone-3b362e);
  box-shadow: 0 2px 5px rgba(0,0,0,.7);
}

/* The heading and the two button rows span the full width of the grid. */
.pause-settings .set-head,
.pause-settings .gfx-row,
.pause-settings .gear-row,
.pause-settings .adaptive-row,
.pause-settings .scare-row,
.pause-settings .cb-row,
.pause-settings .fov-preview,
.pause-settings .set-back { width: 100%; }
.pause-settings .scare-row,
.pause-settings .cb-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; margin: 0; }
.pause-settings .scare-row .diff-btn,
.pause-settings .cb-row .diff-btn { flex: 1 1 0; min-width: 0; padding-inline: 8px; }
.pause-settings .set-head {
  margin: 6px 0 0; text-align: center;
  font: 700 10px/1 var(--font-mono);
  letter-spacing: .3em; text-transform: uppercase; color: var(--paper-faint);
  text-indent: .3em;
}
.pause-settings .gfx-row {
  display: flex; justify-content: center; gap: 8px; margin: 0;
}
.pause-settings .gfx-row .diff-btn { flex: 1 1 0; }
.pause-settings .gear-row { display: flex; margin: 0; }
.pause-settings .gear-row .diff-btn { width: 100%; min-height: 44px; }
.pause-settings .gear-row .diff-btn[aria-pressed="true"] {
  color: var(--tone-f0e5c9); border-color: var(--tone-a78b55); background: rgba(104,81,32,.35);
}
.pause-settings .adaptive-row {
  display: flex; align-items: flex-start; gap: 10px; max-width: none;
  color: var(--tone-bdb5a5); font: 600 10px/1.35 var(--font-mono);
  letter-spacing: .04em; cursor: pointer;
}
.pause-settings .adaptive-row input:not(.zr-check__input) {
  width: 22px; height: 22px; flex: 0 0 22px; accent-color: var(--tone-b28b4d);
}
.pause-settings .adaptive-row.zr-check {
  font: 600 10px/1.35 var(--font-mono);
  color: var(--tone-bdb5a5);
}
.pause-settings .set-back {
  flex: 0 0 auto;
  margin: 8px 0 0;
  width: 100%;
}
.fov-preview {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 10px 0 4px;
}
.fov-preview__cone {
  display: block; width: min(280px, 70%); height: 64px;
  background: linear-gradient(180deg, rgba(216,208,186,.28), rgba(216,208,186,.06));
  clip-path: polygon(50% 0, calc(50% + var(--fov-spread, 28%)) 100%, calc(50% - var(--fov-spread, 28%)) 100%);
  border-bottom: 1px solid rgba(216,208,186,.35);
}
.fov-preview__label {
  font: 700 9px/1 var(--font-mono);
  letter-spacing: .18em; text-transform: uppercase; color: var(--paper-faint);
}
.pause-ledger .ledger-row {
  display: flex; align-items: flex-start; gap: 8px;
  margin: 6px 0;
  font: 700 12px/1.35 var(--font-mono);
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--paper-mute);
}
.pause-ledger > b {
  display: block;
  margin: 4px 0 8px;
  font: 700 10px/1 var(--font-mono);
  letter-spacing: .22em; text-transform: uppercase; color: var(--paper-faint);
}
.pause-ledger .ledger-transcript {
  font: 400 12px/1.45 var(--font-ui);
  letter-spacing: .02em; color: var(--paper-mute); opacity: .86;
}

/* -------------------------------------------------- loadout: action bar */
/* The geometry of this bar lives in ONE place — the page shell at the end of
   this file. It used to be spread over a base rule, two width overrides, a
   min-width, a media query and three competing declarations in theme.css and
   screens.css, and the result could not be predicted by reading any of them:
   at 320px the primary button was laid out 90px wider than the grid track it
   was in. What is left here is appearance only. */
.mpage .action-bar .mbtn.back {
  border: 1px solid rgba(190,170,135,.3); border-radius: 3px;
  background: rgba(8,10,11,.72); color: var(--tone-a49d8d);
  font-size: 14px; letter-spacing: .16em; transform: none;
}
.mpage .action-bar .mbtn.back::before { display: none; }
.mpage .action-bar .mbtn.back:hover,
.mpage .action-bar .mbtn.back:focus-visible {
  transform: none; background: rgba(40,34,24,.85);
  border-color: var(--amber-dim); color: var(--cream-300);
}
.mpage .action-bar .mbtn.back:focus-visible {
  outline: 1px solid var(--focus-ring, var(--amber));
  outline-offset: 2px;
}
@media (max-width: 480px) {
  /* Trim the padding rather than the row: Back keeps a thumb-sized target and
     the primary action takes the remainder. */
  .mpage .action-bar .mbtn.back { min-width: 92px; padding: 13px 14px; }
  .mpage .action-bar .mbtn.go { flex: 1 1 auto; }
}

/* The difficulty cards stretch to the tallest of them (Creative carries four
   stat lines and a note), which left the other three with their stats floating
   in the middle of an empty box. Push the stats to the floor so the four cards
   read as a set of aligned blocks. */

/* Short viewports: shrink the cards so the difficulty row is a short scroll,
   not a long one, now that the action bar is pinned. */
@media (max-height: 430px) {
  #persona-grid .p-card { flex: 0 1 108px; }
  #persona-grid .p-card .p-name { font-size: 11px; }
  /* Keep titles ≥12px — 10px failed the mobile readability audit. */
  .mpage-title { margin: 8px 0 6px; font-size: 12px; letter-spacing: .24em; }
  .mpage-title::before, .mpage-title::after { width: clamp(12px, 4vw, 40px); margin: 0 10px; }
  #diff-grid .diff-card { padding: 8px 10px; }
  .dc-stats { display: none; }
  #callsign-row { margin-top: 8px; }
}

/* ==========================================================================
   LOADOUT + NIGHT — adaptive presentation pass

   The old layout had responsive breakpoints, but its desktop maxima were so
   conservative that the entire decision lived in the middle half of a wide
   display. These pages now use the available canvas, then deliberately change
   composition on a tablet and phone instead of making the desktop row tiny.
   ========================================================================== */

.mpage[data-for="loadout"],
.mpage[data-for="treatments"],
.mpage[data-for="night"] {
  width: min(1320px, 96vw);
  justify-content: flex-start;
  padding-top: calc(18px + env(safe-area-inset-top, 0px));
}

.mpage-title {
  margin: 4px 0 18px;
  color: var(--tone-c2b9a4);
  font-size: clamp(12px, .9vw, 15px);
  letter-spacing: .36em;
  text-shadow: 0 2px 10px var(--ink);
}
.mpage-title::before,
.mpage-title::after {
  width: clamp(40px, 9vw, 140px);
  background: linear-gradient(90deg, transparent, rgba(205,181,139,.68), transparent);
}

/* Soft stage behind the decision so the cards don't float on empty black. */
.mpage[data-for="loadout"] #persona-grid,
.mpage[data-for="night"] #diff-grid {
  position: relative;
  padding: clamp(14px, 1.4vw, 22px);
  border: 1px solid rgba(190,170,135,.14);
  border-radius: 6px;
  background:
    linear-gradient(180deg, rgba(18,20,24,.58), rgba(8,10,13,.72)),
    radial-gradient(ellipse at 50% 0, rgba(190,150,90,.08), transparent 62%);
  box-shadow: inset 0 1px rgba(255,240,215,.05), 0 18px 50px rgba(0,0,0,.35);
}

#persona-grid {
  max-width: 1240px;
  gap: clamp(12px, 1.2vw, 18px);
}
#persona-grid .p-card {
  flex: 1 1 200px;
  min-width: 0;
  max-width: 240px;
}
.p-card {
  border-color: rgba(205,181,139,.3);
  box-shadow: 0 16px 38px rgba(0,0,0,.62), inset 0 1px rgba(255,241,214,.06);
}
.p-card:hover {
  transform: translateY(-5px);
  border-color: rgba(218,192,143,.7);
  box-shadow: 0 22px 48px rgba(0,0,0,.72), 0 0 24px rgba(190,145,78,.12);
}
.p-card:focus-visible {
  transform: translateY(-5px);
  border-color: rgba(218,192,143,.7);
  box-shadow: 0 22px 48px rgba(0,0,0,.72), 0 0 24px rgba(190,145,78,.12);
  outline: 1px solid var(--focus-ring, var(--amber));
  outline-offset: 2px;
}
.p-card.sel {
  border-color: var(--danger);
  box-shadow: 0 0 0 1px rgba(192,68,54,.55), 0 18px 44px rgba(0,0,0,.76),
              0 0 34px rgba(160,34,24,.25);
}
.p-card .p-shot { aspect-ratio: 4 / 5; }
.p-card .p-body { padding: 14px 15px 16px; }
.p-card .p-name { font-size: clamp(13px, 1vw, 16px); }

#diff-grid {
  max-width: 1160px;
  gap: clamp(12px, 1.2vw, 18px);
}
#diff-grid .diff-card {
  flex: 1 1 230px;
  max-width: none;
  min-height: 236px;
}
.diff-card {
  padding: clamp(18px, 1.7vw, 24px);
  border-color: rgba(205,181,139,.3);
  box-shadow: 0 16px 38px rgba(0,0,0,.58);
}
.diff-card:hover {
  transform: translateY(-4px);
  border-color: rgba(218,192,143,.64);
}
.diff-card.sel {
  background:
    radial-gradient(circle at 50% 0, rgba(176,54,40,.19), transparent 58%),
    linear-gradient(168deg, rgba(68,26,23,.96), rgba(14,10,11,.99));
  box-shadow: 0 0 0 1px rgba(176,69,58,.42), 0 18px 42px rgba(0,0,0,.7),
              0 0 28px rgba(160,34,24,.2);
}
.dc-name { font-size: clamp(15px, 1.08vw, 18px); }
.dc-line {
  font-size: clamp(12px, .8vw, 13.5px);
  line-height: 1.62;
}

#callsign-row {
  width: min(520px, 100%);
  min-height: 48px;
  margin-top: 16px;
  padding: 0 8px 0 16px;
  border: 1px solid rgba(190,170,135,.18);
  border-radius: 4px;
  background: rgba(6,8,10,.72);
  box-shadow: inset 0 1px rgba(255,240,215,.05);
}

/* Action bar is viewport-fixed and full-width — do not shrink it into a
   floating island under empty black. */
.mpage[data-for="loadout"] .action-bar,
.mpage[data-for="treatments"] .action-bar,
.mpage[data-for="night"] .action-bar {
  width: 100%;
  margin-left: 0;
  margin-right: 0;
}

/* Tablets: deliberate multi-column composition. */
@media (min-width: 521px) and (max-width: 900px) and (min-height: 501px) {
  #persona-grid { max-width: 720px; }
  #persona-grid .p-card {
    flex: 1 1 calc(33.333% - 12px);
    max-width: 220px;
  }
  #diff-grid { max-width: 740px; }
  #diff-grid .diff-card {
    flex: 1 1 calc(50% - 8px);
    min-height: 196px;
  }
}

/* Portrait phones: horizontal soldier dossiers + stacked nights. */
@media (max-width: 520px) and (min-height: 501px) {
  .mpage[data-for="loadout"],
  .mpage[data-for="night"] {
    width: 100%;
    padding-left: 12px;
    padding-right: 12px;
  }
  .mpage-title {
    margin: 4px 0 12px;
    letter-spacing: .28em;
  }
  .mpage-title::before,
  .mpage-title::after {
    width: clamp(16px, 7vw, 34px);
    margin: 0 10px;
  }
  .mpage[data-for="loadout"] #persona-grid,
  .mpage[data-for="night"] #diff-grid {
    padding: 10px;
  }
  #persona-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    /* The <=920px tier turned the grid into a horizontal carousel. Without
       resetting the flow here, cards kept flowing into implicit 132px columns
       and the first card's 1fr track collapsed to 0 inside the scroller. */
    grid-auto-flow: row;
    grid-auto-columns: auto;
    overflow-x: visible;
    scroll-snap-type: none;
    gap: 9px;
    max-width: 420px;
  }
  #persona-grid .p-card,
  html.is-touch #persona-grid .p-card {
    display: grid;
    grid-template-columns: 108px minmax(0, 1fr);
    flex: none;
    width: 100%;
    max-width: none;
    min-height: 124px;
  }
  .p-card .p-shot {
    aspect-ratio: auto;
    min-height: 124px;
    height: 100%;
  }
  .p-card .p-body {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 11px 12px;
  }
  html.is-touch .p-card .p-blurb {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: 11px;
    line-height: 1.35;
  }
  .p-card .p-perk { margin-top: 8px; }
  .p-card.sel::after { top: 8px; right: 8px; }
  #diff-grid {
    max-width: 420px;
    gap: 9px;
  }
  #diff-grid .diff-card,
  html.is-touch #diff-grid .diff-card {
    min-height: 142px;
    padding: 15px 16px;
  }
  .dc-line,
  .dc-stats { display: flex; }
  .dc-line {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  #callsign-row {
    width: min(420px, 100%);
    margin-top: 12px;
  }
  .mpage[data-for="loadout"] .action-bar,
  .mpage[data-for="treatments"] .action-bar,
  .mpage[data-for="night"] .action-bar {
    width: 100%;
  }
}

/* Short landscape phones: one scan-line, but keep enough copy to choose. */
@media (orientation: landscape) and (max-height: 500px) {
  .mpage[data-for="loadout"],
  .mpage[data-for="night"] {
    width: min(1180px, 96vw);
    padding-top: calc(8px + env(safe-area-inset-top, 0px));
  }
  .mpage[data-for="loadout"] #persona-grid,
  .mpage[data-for="night"] #diff-grid {
    padding: 8px;
  }
  #persona-grid {
    display: flex;
    flex-wrap: nowrap;
    flex: 0 0 auto;
    max-width: 980px;
    gap: 8px;
    overflow-x: auto;
  }
  #persona-grid .p-card,
  html.is-touch #persona-grid .p-card {
    flex: 1 1 0;
    width: auto;
    min-width: 120px;
    max-width: 180px;
    min-height: 118px;
    display: flex;
    flex-direction: column;
  }
  .p-card .p-shot { aspect-ratio: 5 / 4; min-height: 72px; flex: 1 1 auto; }
  .p-card .p-body { padding: 7px 8px 8px; flex: 0 0 auto; }
  .p-card .p-tag {
    letter-spacing: .1em;
    max-width: none;
    overflow: visible;
    text-overflow: clip;
    white-space: normal;
    overflow-wrap: break-word;
  }
  .p-card .p-blurb,
  .p-card .p-perk { display: none !important; }
  #diff-grid {
    flex-wrap: nowrap;
    max-width: 980px;
    gap: 8px;
  }
  #diff-grid .diff-card,
  html.is-touch #diff-grid .diff-card {
    flex: 1 1 0;
    min-width: 0;
    min-height: 132px;
    padding: 10px 11px;
  }
  .dc-name { font-size: 13px; }
  /* Keep one readable line + the key numbers. The older short-height rules
     blanked these and left four empty boxes. */
  .dc-line {
    display: -webkit-box !important;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: 10.5px;
    line-height: 1.35;
  }
  .dc-stats {
    display: flex !important;
    gap: 2px 8px;
  }
  .dc-stats i {
    font-size: 8.5px;
  }
  .dc-note {
    display: -webkit-box;
    -webkit-line-clamp: 1;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  #callsign-row {
    width: min(520px, 70vw);
    min-height: 44px;
    margin-top: 8px;
  }
  .mpage[data-for="loadout"] .action-bar,
  .mpage[data-for="treatments"] .action-bar,
  .mpage[data-for="night"] .action-bar {
    width: 100%;
  }
}


/* ------------------------------------------------- callsign, made legible */
/* The reroll was a bare ↻ glyph with an accessible name and nothing visible
   saying what it did. Sighted players deserve the same information. */
#callsign-row .cs-label {
  color: var(--paper-mute);
  font: 700 11px/1 var(--font-mono);
  letter-spacing: .22em; text-transform: uppercase;
}
#callsign { font-size: 14px !important; color: var(--cream-600) !important; }
#callsign-reroll {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  width: auto !important; min-width: 44px; padding: 0 14px;
  font: 700 11px/1 var(--font-mono) !important;
  letter-spacing: .14em; text-transform: uppercase;
}
#callsign-reroll .rr-glyph { font-size: 15px; line-height: 1; }
@media (max-width: 480px) {
  #callsign-row { flex-wrap: wrap; }
}

/* --------------------------------------------------- difficulty, labelled */
/* "Choose the Night" is the game talking. A plain word underneath is the
   interface telling you what the choice actually is. */
.mpage-sublabel {
  margin: -8px 0 14px;
  color: var(--paper-mute);
  font: 400 12.5px/1.5 var(--font-ui); font-style: normal; letter-spacing: .04em;
  text-align: center;
}
#diff-grid .diff-card { padding-block: 12px; }

/* Privacy / legal lives in the footer text links. Gear opens Settings. */
.chrome-settings,
.chrome-legal {
  position: fixed;
  top: max(12px, env(safe-area-inset-top, 0px));
  right: max(12px, env(safe-area-inset-right, 0px));
  z-index: 5;
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--cream-800);
  background: rgba(8,10,13,.72);
  border: 1px solid rgba(190,170,135,.28);
  border-radius: 4px;
  cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255,240,215,.1), 0 8px 18px rgba(0,0,0,.4);
}
.chrome-settings svg,
.chrome-legal svg { width: 20px; height: 20px; }
.chrome-settings:hover,
.chrome-settings:focus-visible,
.chrome-legal:hover,
.chrome-legal:focus-visible {
  color: var(--cream-100);
  border-color: rgba(232,196,150,.7);
  outline: 1px solid var(--focus-ring, var(--amber));
  outline-offset: 2px;
}
.mpage[data-for="legal"] .mpage-title {
  text-indent: 0;
  text-align: center;
}

.p-card .p-portrait {
  object-position: center 18%;
}

#cosmetic-loadout {
  margin-bottom: 12px;
}

@media (max-width: 380px) {
  .mpage[data-for="loadout"] .menu-col.action-bar,
  .mpage[data-for="treatments"] .menu-col.action-bar,
  .mpage[data-for="night"] .menu-col.action-bar {
    padding-left: max(10px, env(safe-area-inset-left, 0px));
    padding-right: max(10px, env(safe-area-inset-right, 0px));
    gap: 8px;
  }
  .mpage[data-for="loadout"] .action-bar .mbtn.back,
  .mpage[data-for="treatments"] .action-bar .mbtn.back,
  .mpage[data-for="night"] .action-bar .mbtn.back {
    min-width: 88px;
    padding-left: 12px;
    padding-right: 12px;
  }
  .mpage[data-for="loadout"] .action-bar .mbtn.go,
  .mpage[data-for="treatments"] .action-bar .mbtn.go,
  .mpage[data-for="night"] .action-bar .mbtn.go,
  .mpage[data-for="night"] .action-bar #btn-deploy {
    min-width: 0;
    flex: 1 1 auto;
    max-width: none;
  }
}

/* ===========================================================================
   Premium feel pass (0.16.6) — motion, selection chrome, empty/locked states.
   Keeps the paper-and-ink language; does not invent a second visual system.
   =========================================================================== */

/* Home: brand + tiles stagger in. Primary SOLO already owns the red; the
   secondary tiles keep paper chrome so the page reads as one CTA + options. */
@keyframes homeBrandIn {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}
@keyframes homeTileIn {
  /* Translate only — never scale. Layout matrix measures hit targets during
     entrance, and scale(.985) dropped ghost tiles to 43px (under the 44px floor). */
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}
#title-screen[data-page="home"] .mpage[data-for="home"] .game-title {
  animation: homeBrandIn .48s var(--ease-out, cubic-bezier(.2,.8,.2,1)) both;
}
#title-screen[data-page="home"] .mpage[data-for="home"] .menu-grid .mrow-ask .mtile:nth-child(1) {
  animation: homeTileIn .42s var(--ease-out, cubic-bezier(.2,.8,.2,1)) .14s both;
}
#title-screen[data-page="home"] .mpage[data-for="home"] .menu-grid .mrow-ask .mtile:nth-child(2) {
  animation: homeTileIn .42s var(--ease-out, cubic-bezier(.2,.8,.2,1)) .2s both;
}
#title-screen[data-page="home"] .chrome-settings,
#title-screen[data-page="home"] .chrome-legal {
  animation: homeBrandIn .4s var(--ease-out, cubic-bezier(.2,.8,.2,1)) .2s both;
}
/* Soft pulse on the primary CTA once — reads as “this is Start” without
   competing with hover. */
@keyframes primaryBreath {
  0%, 100% { box-shadow:
    inset 0 1px 0 rgba(255,220,180,.1),
    inset 0 -2px 0 rgba(0,0,0,.35),
    0 0 18px rgba(93,16,10,.32),
    0 16px 36px rgba(0,0,0,.55); }
  50% { box-shadow:
    inset 0 1px 0 rgba(255,220,180,.14),
    inset 0 -2px 0 rgba(0,0,0,.35),
    0 0 24px rgba(93,16,10,.42),
    0 16px 36px rgba(0,0,0,.55); }
}
#title-screen[data-page="home"] .mtile.primary {
  animation:
    homeTileIn .42s var(--ease-out, cubic-bezier(.2,.8,.2,1)) .14s both,
    primaryBreath 2.8s ease-in-out 1s 2;
}

/* Version stamp: a small filed plate instead of bare tracked type. */
#build-tag {
  display: inline-block;
  margin-left: .55em;
  padding: 2px 8px 3px;
  border: 1px solid rgba(190,170,135,.32);
  border-radius: 2px;
  background: rgba(0,0,0,.42);
  color: var(--tone-b7ac96);
  opacity: .88;
  letter-spacing: .16em;
  vertical-align: 1px;
  box-shadow: inset 0 1px 0 rgba(255,240,215,.08);
}

/* Loadout portraits: vignette frame + full unit stencil (no truncation). */
.p-card .p-tag {
  display: block;
  position: absolute; left: 8px; right: 8px; bottom: 7px; z-index: 3;
  font: 700 8px/1.25 var(--font-mono);
  letter-spacing: .14em; text-transform: uppercase;
  color: rgba(214,204,182,.72); text-shadow: 0 1px 2px var(--ink);
  /* Break at the FtRot/ slash (a zero-width space in the markup), never
     mid-word — "CONTRACTO R" read as a typo on compact cards. */
  white-space: normal; overflow-wrap: break-word; word-break: normal;
  max-width: none; text-overflow: clip; pointer-events: none;
}
.p-card .p-shot::before {
  content: "";
  position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background:
    radial-gradient(ellipse 78% 62% at 50% 36%, transparent 42%, rgba(0,0,0,.42) 100%),
    linear-gradient(180deg, rgba(0,0,0,.18), transparent 22%, transparent 68%, rgba(0,0,0,.5));
  box-shadow: inset 0 0 0 1px rgba(255,240,215,.06);
}
.p-card.sel {
  border-color: var(--danger-hot);
  box-shadow:
    0 0 0 1px rgba(210,85,69,.55),
    0 0 36px rgba(160,36,24,.34),
    0 18px 40px rgba(0,0,0,.75);
}
.p-card.sel .p-shot::before {
  background:
    radial-gradient(ellipse 78% 62% at 50% 36%, rgba(196,80,55,.12), transparent 55%),
    radial-gradient(ellipse 78% 62% at 50% 36%, transparent 42%, rgba(0,0,0,.38) 100%),
    linear-gradient(180deg, rgba(40,12,10,.2), transparent 24%, transparent 68%, rgba(0,0,0,.48));
  box-shadow:
    inset 0 0 0 1px rgba(255,180,150,.14),
    inset 0 0 28px rgba(150,30,20,.18);
}

/* Treatments: locked cards read as sealed dossiers, selected as live gear. */
.cosmetic-card {
  transition: border-color .16s, box-shadow .16s, background .16s, transform .16s, filter .16s;
  box-shadow: 0 10px 22px rgba(0,0,0,.4);
}
.cosmetic-card:hover:not(.locked) {
  transform: translateY(-2px);
  box-shadow: 0 14px 28px rgba(0,0,0,.5);
}
.cosmetic-card.sel {
  border-color: var(--danger-hot);
  background: linear-gradient(168deg, rgba(52,22,18,.94), rgba(12,8,9,.98));
  box-shadow:
    0 0 0 1px rgba(210,85,69,.4),
    0 0 24px rgba(150,34,25,.22),
    0 12px 26px rgba(0,0,0,.55);
}
.cosmetic-card.sel .cosmetic-name { color: var(--tone-ffe2d8); }
.cosmetic-card.locked {
  color: var(--tone-6e6b64);
  cursor: not-allowed;
  filter: grayscale(.4) brightness(.88);
  border-style: dashed;
  /* .34 / .82, up from .2 / .72: at the old alphas the dashed border and the
     panel dissolved into the page and locked treatments read as bare text
     floating beside the one real card, not as sealed dossiers. */
  border-color: rgba(190,170,135,.34);
  background: rgba(9,12,14,.82);
  box-shadow: none;
}
.cosmetic-card.locked .cosmetic-name { color: var(--tone-8a867c); }
.cosmetic-card.locked .cosmetic-description { color: var(--tone-6f6c64); }
.cosmetic-card.locked .cosmetic-swatch {
  position: relative;
  opacity: .7;
}
.cosmetic-card.locked .cosmetic-swatch::after {
  content: "";
  position: absolute; inset: 6px;
  border: 1.5px solid rgba(210,200,180,.45);
  border-radius: 50%;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.35);
  background:
    linear-gradient(135deg, transparent 44%, rgba(210,200,180,.55) 46% 54%, transparent 56%);
}
.cosmetic-meter {
  height: 4px;
  border-radius: 1px;
  background: rgba(255,255,255,.1);
}
.cosmetic-meter i {
  border-radius: 1px;
  background: linear-gradient(90deg, var(--tone-8d2418), var(--tone-c44538));
}

/* Night difficulty: selected reads like a stamped order. */
.diff-card.sel {
  border-color: var(--danger-hot);
  background: linear-gradient(168deg, rgba(96,26,18,.55), rgba(18,10,10,.96));
  box-shadow: 0 0 0 1px rgba(210,85,69,.35), 0 0 22px rgba(140,30,20,.2);
  transform: translateY(-2px);
}
.diff-card.sel .dc-name { color: var(--tone-ffe2d8); }

/* Fixed docks: frosted paper rail instead of a hard black bar. */
.mpage[data-for="loadout"] .menu-col.action-bar,
.mpage[data-for="treatments"] .menu-col.action-bar,
.mpage[data-for="night"] .menu-col.action-bar {
  background:
    linear-gradient(180deg, rgba(3,4,6,0) 0%, rgba(8,10,14,.72) 28%, rgba(4,5,7,.96) 100%);
  border-top-color: rgba(210,190,150,.28);
  backdrop-filter: blur(10px) saturate(.7);
  -webkit-backdrop-filter: blur(10px) saturate(.7);
}

/* Pause: dim + blur the live world behind the full-bleed panel. */
#pause-screen.screen {
  background: rgba(7, 9, 10, .88);
  backdrop-filter: blur(8px) saturate(.55);
  -webkit-backdrop-filter: blur(8px) saturate(.55);
}
/* Settings gear chrome (title + pause). */
.chrome-settings,
.chrome-legal {
  background: rgba(10,12,16,.78);
  border-color: rgba(210,190,150,.34);
  transition: color .15s, border-color .15s, background .15s, transform .15s;
}
.chrome-settings:hover,
.chrome-settings:focus-visible,
.chrome-legal:hover,
.chrome-legal:focus-visible {
  transform: translateY(-1px);
  background: rgba(18,16,14,.88);
}

/* Home footer: Credits + Legal as text links (not menu tiles). */
#title-screen .home-footer-links.corner-stat {
  position: fixed; z-index: 4; margin: 0;
  left: 50%; bottom: max(8px, env(safe-area-inset-bottom));
  transform: translateX(-50%);
  display: none;
  gap: 0;
  font: 700 10px/1.7 var(--font-mono);
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--paper-dim);
  pointer-events: auto;
  white-space: nowrap;
}
#title-screen[data-page="home"] .home-footer-links.corner-stat {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
#title-screen .home-footer-links .text-link,
#title-screen .ready-adjust .text-link {
  appearance: none; background: none; border: 0;
  min-height: 44px; min-width: 44px; padding: 0 8px;
  display: inline-flex; align-items: center; justify-content: center;
  color: inherit; font: inherit; letter-spacing: inherit;
  text-transform: inherit; cursor: pointer;
  text-decoration: underline; text-underline-offset: 3px;
  text-decoration-color: rgba(190,170,135,.35);
}
#title-screen .home-footer-links .text-link:hover,
#title-screen .home-footer-links .text-link:focus-visible,
#title-screen .ready-adjust .text-link:hover,
#title-screen .ready-adjust .text-link:focus-visible {
  color: var(--paper);
  text-decoration-color: rgba(210,190,150,.75);
  outline: none;
}
#title-screen .home-footer-links .cs-dot {
  margin: 0 .55em; opacity: .45; font-style: normal;
}
@media (max-width: 640px) {
  #title-screen .home-footer-links.corner-stat {
    position: static;
    transform: none;
    margin: 6px auto 0;
    font-size: 11px; letter-spacing: .12em;
  }
}

@media (prefers-reduced-motion: reduce) {
  #title-screen[data-page="home"] .mpage[data-for="home"] .game-title,
  #title-screen[data-page="home"] .mpage[data-for="home"] .subtitle,
  #title-screen[data-page="home"] .mpage[data-for="home"] .menu-grid .mtile,
  #title-screen[data-page="home"] .mtile.primary,
  #title-screen[data-page="home"] .chrome-settings,
  #title-screen[data-page="home"] .chrome-legal {
    animation: none !important;
  }
  .cosmetic-card:hover:not(.locked),
  .diff-card.sel,
  #pause-screen .pause-actions .pbtn:hover,
  #pause-screen .pause-actions .pbtn:focus-visible,
  .chrome-settings:hover,
  .chrome-settings:focus-visible,
  .chrome-legal:hover,
  .chrome-legal:focus-visible {
    transform: none;
  }
  #pause-screen.screen,
  .mpage[data-for="loadout"] .menu-col.action-bar,
  .mpage[data-for="treatments"] .menu-col.action-bar,
  .mpage[data-for="night"] .menu-col.action-bar {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
  #pause-screen.screen {
    background: rgba(2,3,5,.94);
  }
}
html.reduce-motion #pause-screen.screen,
html.reduce-motion .mpage[data-for="loadout"] .menu-col.action-bar,
html.reduce-motion .mpage[data-for="treatments"] .menu-col.action-bar,
html.reduce-motion .mpage[data-for="night"] .menu-col.action-bar {
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
html.reduce-motion #pause-screen.screen {
  background: rgba(2,3,5,.94);
}

#pause-screen .pause-actions .pbtn {
  border-radius: 2px;
  transition: background var(--dur-fast, .12s) var(--ease-out, ease),
    border-color var(--dur-fast, .12s), color var(--dur-fast, .12s),
    transform var(--dur-fast, .12s) var(--ease-out, ease),
    box-shadow var(--dur-fast, .12s);
}
#pause-screen .pause-actions .pbtn:hover,
#pause-screen .pause-actions .pbtn:focus-visible {
  transform: translateY(-1px);
  box-shadow: inset 0 1px 0 rgba(255,240,215,.14), 0 12px 26px rgba(0,0,0,.45);
}
#pause-screen .pause-actions .pbtn.primary:hover,
#pause-screen .pause-actions .pbtn.primary:focus-visible {
  box-shadow:
    0 0 18px rgba(93,16,10,.35),
    inset 0 1px rgba(255,220,180,.1),
    0 12px 26px rgba(0,0,0,.45);
}

/* Title background: cover every aspect, no letterbox. */
#title-bg {
  position: absolute; inset: 0; overflow: hidden;
  background: url('../assets/img/menu_bg.jpg') center / cover no-repeat;
}
#title-bg img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center;
  pointer-events: none;
}

/* Quick Match: one primary, heading that does not eat the dialog. */
#quickmatch .qm-panel {
  width: min(480px, 92vw);
  text-align: center;
}
#quickmatch .ask-kicker {
  margin: 0 0 6px;
  font: 700 11px/1 var(--font-mono);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: #c08a48;
  opacity: 1;
}
#quickmatch h2 {
  transform: none;
  width: 100%;
  font: 800 clamp(22px, 4vw, 32px)/1.15 var(--font-display);
  letter-spacing: .08em;
  text-transform: uppercase;
  white-space: nowrap;
}
@media (max-width: 420px) {
  #quickmatch h2 { white-space: normal; font-size: 22px; }
}
#quickmatch p,
#quickmatch .fr-lead,
#quickmatch .fr-note {
  font: 400 13px/1.5 var(--font-ui);
  font-style: normal;
  letter-spacing: .04em;
  text-align: center;
  color: var(--paper-mute);
  opacity: .88;
}
#quickmatch .menu-col { align-items: stretch; width: min(360px, 100%); margin-inline: auto; }
#quickmatch .mbtn { width: 100%; min-width: 0; }
#quickmatch #qm-cancel {
  appearance: none; background: none; border: 0; box-shadow: none;
  min-height: 44px; padding: 10px;
  color: var(--paper-dim);
  font: 700 12px/1 var(--font-mono);
  letter-spacing: .16em; text-transform: uppercase;
  text-decoration: underline; text-underline-offset: 3px;
  cursor: pointer;
}
#quickmatch #qm-cancel:hover,
#quickmatch #qm-cancel:focus-visible {
  color: var(--paper);
  outline: 1px solid var(--focus-ring, var(--amber));
  outline-offset: 2px;
}

@media (max-width: 720px) {
  .pause-settings .slider-row {
    grid-template-columns: 1fr;
    row-gap: 6px;
  }
  .pause-settings .slider-row .val { text-align: left; }
  .pause-settings .slider-control { min-width: 0; width: 100%; }
}

/* UI text scale — menus and subtitles, not HUD layout. */
#title-screen .mpage,
#pause-screen .pause-panel,
#quickmatch .qm-panel,
#confirm-screen .confirm-panel,
#gameover-screen .panel {
  font-size: calc(13px * var(--ui-scale, 1));
}
#title-screen .mtile {
  font-size: calc(clamp(15px, 1.35vw, 18px) * var(--ui-scale, 1));
}
#signal-subtitle {
  font-size: calc(16px * var(--hud-sub-scale, 1) * var(--ui-scale, 1));
}

/* Conversational deploy — one paper card, one question. Not a chatbot. */
.ask-card {
  width: min(540px, 94vw);
  margin: 10px auto 0;
  padding: 20px 18px 16px;
  text-align: center;
  background:
    linear-gradient(180deg, rgba(255,240,215,.05), transparent 18%),
    linear-gradient(180deg, rgba(22,18,14,.94), rgba(8,7,6,.97));
  border: 1px solid rgba(190,170,135,.3);
  border-radius: 2px;
  box-shadow:
    inset 0 1px 0 rgba(255,240,215,.08),
    0 18px 40px rgba(0,0,0,.55);
}
.ask-kicker {
  margin: 0 0 8px;
  font: 700 10px/1 var(--font-mono);
  letter-spacing: .22em;
  text-transform: uppercase;
  color: #c08a48;
}
.ask-q {
  margin: 0 0 14px;
  font: 700 clamp(22px, 3.6vw, 32px)/1.15 var(--font-display);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--cream-100, #e6dcc4);
}
.ask-q.mpage-title {
  margin: 0 0 14px;
  letter-spacing: .06em;
  color: var(--cream-100, #e6dcc4);
  font: 700 clamp(22px, 3.6vw, 32px)/1.15 var(--font-display);
}
.ask-q.mpage-title::before,
.ask-q.mpage-title::after { display: none; }
.ask-answers { margin-top: 0; }
/* Beat the old home-compression hide so Solo/Online price lines stay on phones. */
#title-screen[data-page="home"] .ask-answers .mrow-ask .mt-note {
  display: block !important;
}
@media (max-height: 500px) {
  #title-screen[data-page="home"] .ask-answers .mrow-ask .mt-note {
    display: none !important;
  }
}
.mrow-ask {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  width: 100%;
  max-width: 640px;
}
.mrow-ask-3 {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  width: 100%;
}
.ask-more {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  margin-top: 8px;
  padding: 8px 16px;
  appearance: none;
  background: none;
  border: 0;
  color: var(--paper-mute, #b7ac96);
  font: 700 11px/1 var(--font-mono);
  letter-spacing: .2em;
  text-transform: uppercase;
  cursor: pointer;
}
.ask-more:hover,
.ask-more:focus-visible {
  color: var(--cream-100, #fff6e8);
  outline: 1px solid var(--focus-ring, var(--amber));
  outline-offset: 2px;
}
.ready-recap {
  margin: 0 0 16px;
  min-height: 1.45em;
  color: #e6dcc4;
  font: 400 15px/1.45 var(--font-ui);
  text-wrap: pretty;
}
.ready-recap:empty { min-height: 0; }
.ask-empty {
  margin: 8px 0 0;
  color: #c4bba8;
  font: 400 14px/1.45 var(--font-ui);
  text-wrap: pretty;
}
.ask-empty[hidden] { display: none !important; }
.cc-status:empty { display: none; }
.mpage[data-for="coop"]:has(.cc-error:not(:empty)) .cc-help { display: none; }
.mpage[data-for="online"][data-online-state="ended"] .home-subscribe,
.mpage[data-for="online"][data-online-state="ending"] .home-subscribe {
  border-color: #bd2417;
  background: rgba(189, 36, 23, .18);
}
.mpage[data-for="online"][data-online-state="ok"] .home-trial-status {
  color: #c4bba8;
}
.ready-adjust {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 10px;
}
.more-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
}
.more-list .mtile { min-height: 48px; }
#title-screen[data-page="home"] .chrome-settings,
#title-screen[data-page="night"] .chrome-settings,
#title-screen[data-page="site"] .chrome-settings,
#title-screen[data-page="ready"] .chrome-settings,
#title-screen[data-page="online"] .chrome-settings,
#title-screen[data-page="coop"] .chrome-settings,
#title-screen[data-page="lobby"] .chrome-settings { display: none; }
#site-strip.site-strip {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  width: min(640px, 100%);
  margin: 4px auto 0;
}
#site-strip .site-card {
  flex: 1 1 200px;
  max-width: 280px;
  min-height: 72px;
}
#site-strip .site-file { display: none; }
#site-strip .site-intel {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
#site-strip .site-card.is-locked,
#site-strip .site-card.is-stub,
#lobby-site .site-card.is-locked,
#lobby-site .site-card.is-stub { display: none; }
.mpage[data-for="night"] {
  padding-bottom: calc(var(--space-4, 28px) + env(safe-area-inset-bottom, 0px));
}
.mpage[data-for="night"] .menu-col.action-bar,
.mpage[data-for="site"] .menu-col.action-bar,
.mpage[data-for="ready"] .menu-col.action-bar,
.mpage[data-for="online"] .menu-col.action-bar,
.mpage[data-for="more"] .menu-col.action-bar,
.mpage[data-for="coop"] .menu-col.action-bar {
  position: relative;
  left: auto;
  right: auto;
  bottom: auto;
  width: 100%;
  margin-top: 14px;
  padding: 0;
  background: none;
  border: 0;
  box-shadow: none;
}
.mpage[data-for="night"] #diff-grid {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
  max-width: none;
  padding: 0;
  border: 0;
  background: none;
  box-shadow: none;
}
.mpage[data-for="night"] #diff-grid .diff-card,
.mpage[data-for="night"] .diff-card {
  flex: none;
  width: 100%;
  max-width: none;
  min-height: 56px;
  text-align: left;
  padding: 12px 14px;
}
.mpage[data-for="online"] .home-subscribe[hidden] { display: none !important; }
#btn-host[hidden] { display: none !important; }
@media (max-width: 560px) {
  .mrow-ask,
  .mrow-ask-3 { grid-template-columns: 1fr; }
}

/* A tile with nothing to say shows only its name. */
.mt-note:empty { display: none; }
