:root {
  font-family: "Avenir Next", "Trebuchet MS", system-ui, sans-serif;
  color: #17313a;
  background: #0d252d;
  font-synthesis: none;
}

* { box-sizing: border-box; }

html, body, #game-shell { width: 100%; height: 100%; margin: 0; overflow: hidden; }

#game-shell {
  position: relative;
  background: radial-gradient(circle at 50% 25%, #316876, #102f38 72%);
}

#game-canvas {
  display: block;
  width: 100%;
  height: 100%;
  outline: none;
  touch-action: none;
}

.hidden { display: none !important; }

.game-entry {
  position: absolute;
  inset: 0;
  z-index: 80;
  display: grid;
  place-items: center;
  overflow: hidden;
  background:
    radial-gradient(circle at 50% 44%, rgba(74,174,176,.2), transparent 34%),
    linear-gradient(145deg, rgba(8,29,36,.88), rgba(18,55,65,.94));
  color: #fff6e5;
  opacity: 1;
  transition: opacity .42s ease, transform .55s cubic-bezier(.2,.8,.2,1);
}
.game-entry::before {
  content: "";
  position: absolute;
  inset: -12%;
  background: repeating-linear-gradient(125deg, transparent 0 88px, rgba(255,255,255,.025) 88px 90px);
  transform: rotate(-2deg);
  pointer-events: none;
  animation: entry-backdrop 2.2s cubic-bezier(.16,.84,.3,1) .3s both;
}
/* the backdrop drifts in slightly wider than it settles, so the whole screen
   reads as arriving rather than being there already */
@keyframes entry-backdrop {
  0% { transform: rotate(-2deg) scale(1.16); opacity: 0; }
  100% { transform: rotate(-2deg) scale(1); opacity: 1; }
}
.game-entry.exiting { opacity: 0; transform: scale(1.035); pointer-events: none; }
.entry-hero {
  position: relative;
  display: grid;
  justify-items: center;
  width: min(720px, calc(100% - 42px));
  text-align: center;
  transition: opacity .34s ease, transform .44s cubic-bezier(.2,.8,.2,1);
}
.entry-logo-lockup {
  display: grid;
  justify-items: center;
  gap: 8px;
  padding: 28px clamp(26px, 4.5vw, 52px) 24px;
  max-width: 92vw;
  border: 4px solid rgba(255,255,255,.88);
  border-radius: 26px;
  background: #173e4a;
  box-shadow: 0 12px 0 #0b252d, 0 30px 70px rgba(0,0,0,.28);
  transform: rotate(-1deg);
  animation: entry-lockup 1.5s cubic-bezier(.18,.9,.28,1.06) .55s both;
}
/* pushed in from the background, overshooting a hair before it settles */
@keyframes entry-lockup {
  0% { transform: rotate(-1deg) scale(.42) translateY(34px); opacity: 0; }
  62% { opacity: 1; }
  100% { transform: rotate(-1deg) scale(1) translateY(0); opacity: 1; }
}
.entry-presents { display: flex; align-items: center; gap: 13px; }
.entry-presents img { width: clamp(150px, 18vw, 215px); height: auto; }
.entry-presents span { color: #7ed4b2; font-size: 13px; font-weight: 950; letter-spacing: .3em; }
.entry-wordmark {
  width: clamp(340px, 56vw, 660px);
  height: auto;
  margin-top: 2px;
  filter: drop-shadow(0 6px 0 rgba(11, 37, 45, .85));
  animation: entry-wordmark 0.95s cubic-bezier(.16,.84,.3,1.2) 1.35s both;
}
@keyframes entry-wordmark {
  0% { transform: scale(.72); opacity: 0; }
  100% { transform: scale(1); opacity: 1; }
}
.entry-presents { animation: entry-fade .8s ease 1.05s both; }
@keyframes entry-fade { 0% { opacity: 0; transform: translateY(8px); } }
.entry-subtitle { display: none; }
.press-any-button {
  margin-top: 52px;
  min-width: 260px;
  padding: 15px 28px;
  border: 2px solid rgba(255,246,229,.5);
  border-radius: 999px;
  background: rgba(255,246,229,.08);
  box-shadow: none;
  color: #fff6e5;
  font-size: 13px;
  font-weight: 950;
  letter-spacing: .18em;
  /* arrives last, then settles into its idle pulse */
  animation: entry-button .7s cubic-bezier(.16,.84,.3,1.2) 2.15s both,
             press-any-pulse 1.1s ease-in-out 2.95s infinite alternate;
}
@keyframes entry-button {
  0% { transform: scale(.8) translateY(14px); opacity: 0; }
  100% { transform: scale(1) translateY(0); opacity: 1; }
}body:not(.keys-driving) .press-any-button:hover { transform: none; background: rgba(255,246,229,.16); box-shadow: none; }
.game-entry.mode-open .entry-hero { opacity: 0; transform: translateY(-24px) scale(.96); pointer-events: none; }
/* Mode select lives on the entry screen itself — no modal card, just the
   options styled onto the page after you press start. */
.mode-select {
  position: absolute;
  width: min(660px, calc(100% - 38px));
  padding: 0;
  color: #fff6e5;
  text-align: center;
  opacity: 0;
  transform: translateY(18px) scale(.98);
  transition: opacity .32s ease, transform .46s cubic-bezier(.18,.86,.24,1.1);
}
.mode-select.visible { opacity: 1; transform: translateY(0) scale(1); }
.mode-kicker { color: #7ed4b2; font-size: 10px; font-weight: 950; letter-spacing: .24em; }
.mode-select h1 { margin: 8px 0 26px; color: #fff6e5; font: 800 clamp(34px,5vw,46px)/1 "Fredoka", sans-serif; letter-spacing: -.02em; }
.mode-options { display: grid; gap: 14px; text-align: left; }
.mode-card {
  display: grid;
  grid-template-columns: 62px 1fr auto;
  align-items: center;
  gap: 16px;
  min-height: 92px;
  padding: 14px 18px;
  border: 3px solid rgba(255,255,255,.72);
  border-radius: 20px;
  background: #173e4a;
  box-shadow: 0 7px 0 #0b252d, 0 20px 40px rgba(0,0,0,.28);
  color: #fff6e5;
  text-align: left;
  transition: transform .14s ease, box-shadow .14s ease;
}
.mode-card.active { border-color: #6fd0bf; box-shadow: 0 7px 0 #0b252d, 0 0 0 4px rgba(111,208,191,.28), 0 20px 40px rgba(0,0,0,.3); }body:not(.keys-driving) .mode-card.active:hover { transform: translateY(-2px); box-shadow: 0 9px 0 #0b252d, 0 0 0 4px rgba(111,208,191,.34), 0 22px 44px rgba(0,0,0,.32); }
.mode-card:focus-visible { outline: 4px solid #f6be3e; outline-offset: 4px; }
.controls-link.active { color: #6fd0bf; outline: 3px solid rgba(111, 208, 191, .55); outline-offset: 4px; border-radius: 8px; }
.mode-number { display: grid; place-items: center; width: 56px; height: 56px; border-radius: 15px; background: #4aaeb0; color: #0b252d; font: 800 22px "Fredoka", "Avenir Next", "Trebuchet MS", system-ui, sans-serif; }
.mode-card > span:nth-child(2) { display: flex; flex-direction: column; gap: 4px; }
.mode-card strong { font: 800 20px "Fredoka", "Avenir Next", "Trebuchet MS", system-ui, sans-serif; letter-spacing: .02em; color: #fff6e5; }
.mode-card small { color: #a9d7d3; font-size: 11px; font-weight: 700; }
.mode-card b { padding: 7px 11px; border-radius: 999px; background: #55c48b; color: #123c31; font-size: 9px; letter-spacing: .12em; }
.mode-card.coming-soon { opacity: .5; cursor: not-allowed; filter: grayscale(.35); }
/* Gobble Days: the November challenge, in its poster's autumn colours. Not a
   choice yet: no pointer, no hover lift, and the keys walk past it. */
.mode-card.gobble {
  position: relative; pointer-events: none; cursor: default;
  border-color: #f6a623;
  background: linear-gradient(135deg, #4a2410 0%, #6b2f12 55%, #8a2b1a 100%);
  box-shadow: 0 7px 0 #2a130a, 0 20px 40px rgba(0,0,0,.28);
}
.mode-card.gobble .mode-number { background: linear-gradient(180deg, #ffd23f, #f28c28); color: #4a2410; }
.mode-card.gobble strong {
  background: linear-gradient(180deg, #ffe066 0%, #ffb52e 55%, #f2711c 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  letter-spacing: .04em;
  filter: drop-shadow(0 2px 0 #4a2410);
}
.mode-card.gobble small { color: #ffd9a8; }
.mode-card.gobble b { background: #c0392b; color: #fff6e5; box-shadow: inset 0 0 0 2px #ffb52e; white-space: nowrap; }
/* the turkey perches on the card's top-right corner, outside the grid */
.mode-card.gobble::after {
  content: "\1F983"; position: absolute; top: -16px; right: 14px;
  font-size: 28px; line-height: 1; transform: rotate(14deg); filter: drop-shadow(0 2px 0 rgba(0,0,0,.35));
}
.mode-card.coming-soon b { background: rgba(220,231,229,.5); color: #cfe0de; }
@keyframes press-any-pulse { to { opacity: .58; transform: scale(.985); } }

.controls-link {
  margin-top: 18px;
  padding: 9px 18px;
  border: 2px solid rgba(255,246,229,.4);
  border-radius: 999px;
  background: rgba(255,246,229,.06);
  box-shadow: none;
  color: #cfe7e2;
  font-size: 11px;
  font-weight: 900;
  letter-spacing: .14em;
}body:not(.keys-driving) .controls-link:hover { transform: none; box-shadow: none; background: rgba(255,246,229,.14); }

.controls-panel {
  position: absolute;
  width: min(900px, calc(100% - 38px));
  color: #fff6e5;
  text-align: center;
  z-index: 5;
  /* the panel outgrew short windows with nowhere to go: header and actions
     stay pinned, the middle scrolls */
  display: flex; flex-direction: column;
  max-height: calc(100vh - 88px);
}
.controls-panel.hidden { display: none; }
.controls-panel h1 { margin: 6px 0 16px; color: #fff6e5; font: 800 clamp(30px,4vw,40px)/1 "Fredoka", sans-serif; }
.controls-scroll {
  overflow-y: auto; min-height: 0;
  padding: 4px 10px 4px 4px; margin: 0 -6px 0 0;
  scrollbar-width: thin; scrollbar-color: rgba(159,224,211,.45) transparent;
}
.controls-scroll::-webkit-scrollbar { width: 8px; }
.controls-scroll::-webkit-scrollbar-thumb { background: rgba(159,224,211,.35); border-radius: 6px; }
.controls-scroll::-webkit-scrollbar-track { background: transparent; }
/* two matched cards side by side; one column when the window is narrow */
.controls-cols { display: grid; grid-template-columns: 1.08fr 1fr; gap: 14px; align-items: stretch; text-align: left; margin-bottom: 12px; }
@media (max-width: 780px) { .controls-cols { grid-template-columns: 1fr; } }
.controls-col, .controls-cols .controls-battle {
  padding: 14px 16px; border-radius: 16px;
  background: rgba(8, 34, 40, .35);
  border: 3px solid rgba(253, 246, 228, .18);
}
.controls-rows { display: grid; gap: 9px; text-align: left; }
.controls-row {
  display: grid;
  grid-template-columns: 1fr auto auto;
  gap: 9px;
  align-items: center;
  padding: 9px 14px;
  border: 3px solid rgba(255,255,255,.6);
  border-radius: 14px;
  background: #173e4a;
  box-shadow: 0 5px 0 #0b252d;
}
.controls-row > span { font: 800 15px "Fredoka", sans-serif; color: #fff6e5; }
.bind-chip {
  min-width: 76px;
  padding: 8px 12px;
  border: 2.5px solid rgba(255,255,255,.35);
  border-radius: 10px;
  background: rgba(255,255,255,.1);
  box-shadow: none;
  color: #9fe0d3;
  font: 900 12px "Fredoka", sans-serif;
  letter-spacing: .06em;
}body:not(.keys-driving) .bind-chip:hover { transform: none; box-shadow: none; background: rgba(255,255,255,.2); }
.bind-chip.listening { background: #f2b33d; border-color: #ffd98a; color: #123c47; animation: press-any-pulse .8s ease-in-out infinite alternate; }
.controls-gamepad { margin: 12px 0 0; color: #a9d7d3; font-size: 12.5px; font-weight: 700; }
.controls-gamepad b { color: #fff6e5; }

/* Battle's keys are a reference card, not a rebinder: same chips, no buttons. */
.controls-battle { text-align: left; }
.cb-head { display: block; font: 900 10.5px "Nunito", sans-serif; letter-spacing: .16em; color: #7fc3bd; margin-bottom: 12px; }
.cb-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.cb-seat { padding: 11px 13px; border-radius: 13px; background: rgba(255,255,255,.06); border: 2px solid rgba(255,255,255,.14); }
.cb-seat > b { display: block; font: 900 10.5px "Nunito", sans-serif; letter-spacing: .14em; margin-bottom: 9px; }
.cb-seat.p1 > b { color: #6fd6a8; }
.cb-seat.p2 > b { color: #f2938f; }
.cb-line { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 3px 0; }
.cb-line span { font: 700 12.5px "Nunito", sans-serif; color: #d6ecea; }
.cb-line i {
  font: 800 11px "Nunito", sans-serif; font-style: normal; letter-spacing: .06em;
  color: #fff6e5; background: rgba(255,255,255,.13);
  border: 2px solid rgba(255,255,255,.2); border-radius: 7px; padding: 3px 8px; white-space: nowrap;
}
.cb-pads { margin: 12px 0 0; color: #a9d7d3; font-size: 12px; font-weight: 700; }
.cb-pads b { color: #fff6e5; }
@media (max-width: 620px) { .cb-grid { grid-template-columns: 1fr; } }
.controls-actions { display: flex; gap: 10px; justify-content: center; margin-top: 12px; flex: none; }
.controls-actions button {
  padding: 11px 22px;
  border: 3px solid rgba(255,255,255,.6);
  border-radius: 12px;
  background: #173e4a;
  box-shadow: 0 5px 0 #0b252d;
  color: #fff6e5;
  font: 900 12px "Fredoka", sans-serif;
  letter-spacing: .1em;
}
#controls-done { background: #4fb3a5; color: #0b252d; }

.character-select {
  position: absolute;
  inset: 0;
  display: flex;
  min-height: 640px;
  overflow: hidden;
  background: #bfDEdc;
  z-index: 30;
}

.character-stage { position: relative; flex: 1 1 auto; min-width: 0; }
#character-canvas { display: block; width: 100%; height: 100%; outline: none; touch-action: none; }
.character-stage-heading { position: absolute; top: 28px; left: 32px; display: flex; flex-direction: column; gap: 18px; pointer-events: none; }
.character-logo { width: fit-content; padding: 14px 22px; border-radius: 10px; background: #16323b; box-shadow: 0 4px 0 rgba(9,45,59,.45), 0 10px 20px rgba(16,24,40,.08); }
.character-logo img { display: block; width: auto; height: 26px; }
.character-stage-heading span { display: block; margin-bottom: 6px; color: #115673; font-size: 12px; font-weight: 700; letter-spacing: .16em; }
.character-stage-heading h1 { margin: 0; color: #0f2f3a; font: 700 40px/1.04 "Avenir Next", sans-serif; letter-spacing: -.02em; }
.camera-hint { position: absolute; left: 32px; bottom: 26px; display: flex; align-items: center; gap: 10px; padding: 8px 14px; border-radius: 9999px; background: rgba(255,255,255,.72); color: #2f5d63; font-size: 13px; font-weight: 500; pointer-events: none; }
.camera-hint i { width: 7px; height: 7px; border-radius: 50%; background: #18779f; }

.character-panel { display: flex; flex: 0 0 396px; flex-direction: column; width: 396px; min-height: 0; background: #fbf8ef; box-shadow: -14px 0 40px rgba(9,45,59,.16); }
.character-panel > header { flex: 0 0 auto; padding: 12px 20px 13px; background: #16323b; }
.character-panel > header > span { color: #8fbac4; font-size: 11px; font-weight: 700; letter-spacing: .18em; }
.character-panel > header h2 { margin: 4px 0 0; color: #f6f2e7; font: 700 17px/1.15 "Avenir Next", sans-serif; }
.character-panel > header p { display: none; }
/* Everything fits without scrolling — a controller can reach every option. */
.character-options { display: flex; flex: 1 1 auto; flex-direction: column; gap: 15px; min-height: 0; padding: 16px 20px 8px; overflow-y: auto; }
.custom-section { display: flex; flex-direction: column; gap: 7px; }
.custom-section > label { color: #5f7a82; font-size: 10px; font-weight: 700; letter-spacing: .14em; }
.custom-section input { min-height: 38px; padding: 0 12px; border: 0; border-radius: 4px; outline: none; background: #fff; box-shadow: 0 0 0 1px #c5d0d3; color: #17313a; font: 400 14px inherit; }body:not(.keys-driving) .custom-section input:hover { box-shadow: 0 0 0 1px #81969c; }
.custom-section input:focus { box-shadow: 0 0 0 3px rgba(68,179,227,.7); }
.custom-section small { display: none; }
.option-grid { display: grid; gap: 8px; }
.option-grid.two { grid-template-columns: repeat(2, 1fr); }
.option-grid.three { grid-template-columns: repeat(3, 1fr); }
.option-chip { min-height: 38px; padding: 0 8px; border: 1.5px solid #c7d0d3; border-radius: 4px; background: #fff; box-shadow: none; color: #405860; font: 500 13px inherit; letter-spacing: 0; transition: all .15s ease-in-out; }body:not(.keys-driving) .option-chip:hover { transform: none; box-shadow: none; border-color: #81969c; }
.option-chip.selected { border-color: #156789; background: #18779f; color: #fff; }
.swatch-row { display: flex; flex-wrap: wrap; gap: 10px; }
.color-swatch { width: 34px; height: 34px; padding: 0; border: 2px solid #fbf8ef; border-radius: 9999px; background: var(--swatch); box-shadow: 0 0 0 1px rgba(16,24,40,.18); transition: box-shadow .15s ease-in-out; }body:not(.keys-driving) .color-swatch:hover { transform: none; box-shadow: 0 0 0 2px #79aab7; }
.color-swatch.selected { box-shadow: 0 0 0 3px #18779f; }
.scrub-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.scrub-option { display: flex; flex-direction: column; align-items: center; gap: 5px; padding: 8px 4px; border: 1.5px solid #c7d0d3; border-radius: 6px; background: #fff; box-shadow: none; color: #405860; font: 500 12px inherit; letter-spacing: 0; }body:not(.keys-driving) .scrub-option:hover { transform: none; box-shadow: none; border-color: #81969c; }
.scrub-option i { width: 26px; height: 26px; border-radius: 50%; background: var(--swatch); }
.scrub-option.selected { border-color: #156789; background: rgba(24,119,159,.12); color: #115673; }
.character-panel > footer { display: flex; flex: 0 0 auto; flex-direction: column; gap: 8px; padding: 10px 20px 14px; border-top: 1px solid #dfe5e6; background: #fbf8ef; }
.character-panel .start-shift { min-height: 42px; border-radius: 4px; background: #156789; box-shadow: 0 3px 0 #0e465d; font-size: 16px; }body:not(.keys-driving) .character-panel .start-shift:hover { transform: none; background: #115673; box-shadow: 0 3px 0 #0e465d; }
.custom-actions { display: flex; gap: 8px; }
.custom-actions button { flex: 1; min-height: 32px; padding: 5px; border: 1.5px solid #c7d0d3; border-radius: 4px; background: transparent; box-shadow: none; color: #405860; font-size: 14px; font-weight: 500; letter-spacing: 0; }body:not(.keys-driving) .custom-actions button:hover { transform: none; box-shadow: none; background: rgba(16,24,40,.05); }
.character-saved { display: flex; align-items: center; justify-content: center; gap: 7px; color: #2d6244; font-size: 13px; font-weight: 500; animation: tech-rise .25s ease-out; }
.character-saved img { width: 16px; height: 16px; }

@keyframes tech-rise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }

@media (max-width: 980px) {
  .character-panel { flex-basis: 360px; width: 360px; }
  .character-stage-heading h1 { font-size: 32px; }
}

/* Short windows compact the designer so it still fits without scrolling. */
@media (max-height: 800px) {
  .character-options { gap: 8px; padding: 8px 20px 4px; }
  .custom-section { gap: 5px; }
  .custom-section input { min-height: 30px; }
  .option-chip { min-height: 29px; }
  .color-swatch { width: 27px; height: 27px; }
  .scrub-option { gap: 3px; padding: 4px 4px; }
  .scrub-option i { width: 19px; height: 19px; }
}

.sales-call-modal {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 34px;
  background: rgba(8,28,34,.62);
  backdrop-filter: blur(7px);
  z-index: 45;
}

.tutorial-coach {
  /* pinned below the first cart card so the how-to reads as belonging to it */
  position: absolute;
  left: 0;
  top: 152px;
  z-index: 55;
  width: 244px;
  transform: translateY(-7px) scale(.96);
  padding: 16px 18px 15px;
  border: 3px solid #ffd85c;
  border-radius: 18px;
  background: rgba(255,250,240,.97);
  box-shadow: 0 6px 0 #173e4a, 0 13px 26px rgba(17,47,56,.24);
  text-align: left;
  pointer-events: none;
  opacity: 0;
  transition: opacity .25s ease, transform .25s cubic-bezier(.2,.9,.25,1.2), top .3s ease;
}
.tutorial-coach.show { opacity: 1; transform: translateY(0) scale(1); }
.tutorial-coach span { display:inline-block; padding:5px 10px; border-radius:999px; background:#e95c52; color:#fff; font-size:9.5px; font-weight:950; letter-spacing:.12em; }
.tutorial-coach h2 { margin: 10px 0 5px; color: #173e4a; font: 800 23px/1.06 "Fredoka", "Avenir Next", "Trebuchet MS", system-ui, sans-serif; }
.tutorial-coach p { margin: 0; color: #3d565e; font-size: 14px; font-weight: 600; line-height: 1.45; }

.inventory-panel.tutorial-focus {
  border-color: #ffd85c;
  box-shadow: 0 8px 0 #173e4a, 0 0 0 6px rgba(255,216,92,.28), 0 0 28px rgba(255,216,92,.62);
  animation: inventory-tutorial-pulse 1s ease-in-out infinite alternate;
}
@keyframes inventory-tutorial-pulse { to { transform: scale(1.035); } }
@keyframes inventory-receive {
  0% { transform: scale(1); }
  45% { transform: scale(1.22) rotate(-4deg); box-shadow: 0 0 0 5px rgba(246,190,62,.45); }
  100% { transform: scale(1); }
}
.sales-call-window {
  display: grid;
  grid-template-columns: minmax(360px, 1.05fr) minmax(360px, .95fr);
  width: min(1120px, 92vw);
  height: min(690px, 82vh);
  min-height: 540px;
  overflow: hidden;
  border: 5px solid white;
  border-radius: 26px;
  background: #fbf8ef;
  box-shadow: 0 14px 0 #16323b, 0 36px 90px rgba(0,0,0,.42);
}
.sales-call-video { position: relative; min-width: 0; background: #dbe4e6; }
#sales-call-canvas { display: block; width: 100%; height: 100%; outline: none; }
.sales-call-video > span { position: absolute; top: 18px; left: 18px; padding: 7px 10px; border-radius: 7px; background: #e95c52; color: white; font-size: 10px; font-weight: 900; letter-spacing: .13em; box-shadow: 0 3px 0 #a83e39; }
.sales-call-video > span.call-clock-note { left: auto; right: 18px; background: #f2b03a; color: #3a2a05; box-shadow: 0 3px 0 #c9901f; }
.sales-call-copy { display: flex; flex-direction: column; min-width: 0; padding: 34px; background: #fbf8ef; }
.sales-call-copy > div:first-child > span { color: #18779f; font-size: 11px; font-weight: 800; letter-spacing: .14em; }
.sales-call-copy h2 { margin: 8px 0 0; color: #16323b; font: 800 34px/1 "Avenir Next", sans-serif; }
.sales-call-copy > p { flex: 1 1 auto; margin: 34px 0 22px; color: #294850; font-size: clamp(20px, 2vw, 27px); font-weight: 650; line-height: 1.34; }
.sales-call-choices { display: flex; flex-direction: column; gap: 10px; }
.phone-skip-typing { align-self: flex-end; min-height: 32px; margin: -4px 0 8px; padding: 6px 11px; border: 2px solid #8db6bd; border-radius: 9px; background: #eaf4f3; box-shadow: none; color: #173e4a; font-size: 10px; letter-spacing: .1em; }body:not(.keys-driving) .phone-skip-typing:hover { transform: none; border-color: #18779f; background: #d8eeee; box-shadow: none; }
.sales-call-choices button { min-height: 46px; padding: 11px 14px; border: 2px solid #bed0d3; border-radius: 10px; background: white; box-shadow: none; color: #173e4a; text-align: left; font-size: 14px; letter-spacing: 0; }body:not(.keys-driving) .sales-call-choices button:hover { transform: translateY(-1px); border-color: #18779f; box-shadow: 0 3px 0 #9abac1; }
.sales-call-hangup { margin-top: 14px; min-height: 46px; border-radius: 10px; background: #e95c52; box-shadow: 0 4px 0 #ae3e39; }

@media (max-width: 860px) {
  .sales-call-modal { padding: 16px; }
  .sales-call-window { grid-template-columns: 1fr; grid-template-rows: 42% 58%; height: 94vh; min-height: 0; }
  .sales-call-copy { padding: 22px; }
  .sales-call-copy h2 { font-size: 27px; }
  .sales-call-copy > p { margin: 18px 0 14px; font-size: 18px; }
}

/* ── HUD: poster-game look — thick ink borders, hard offset shadows ──
   Top row: next task (left) · cart queue (centre) · shift + stars (right). */
:root {
  --ink: #123c47;
  --ink-deep: #0c2a33;
  --cream: #fdf6e4;
  --teal: #4fb3a5;
  --teal-deep: #2e8b7a;
  --coral: #e8524a;
  --gold: #f2b33d;
}

#hud {
  position: absolute;
  inset: 18px 20px auto;
  display: grid;
  /* first column hugs its content: with the next-task panel gone it takes no
     space, so the cart cards own the top-left; it grows only while the phone
     alert or tutorial coach needs the corner */
  grid-template-columns: auto 1fr auto;
  gap: 18px;
  align-items: start;
  pointer-events: none;
  z-index: 10;
}

.identity-stack { display: flex; flex-direction: column; gap: 10px; }

.player-guide { display: none; }

/* Incoming-call tile: a zoomed, front-facing ringing phone under the avatar. */
.phone-alert {
  width: 244px;
  display: grid;
  grid-template-columns: 66px 1fr;
  gap: 11px;
  align-items: center;
  margin-top: 9px;
  padding: 10px 11px;
  border: 3px solid #ffd9d3;
  border-radius: 18px;
  background: rgba(255,247,244,.98);
  box-shadow: 0 6px 0 rgba(148,52,40,.35), 0 10px 24px rgba(8,24,29,.16);
}
.phone-alert.hidden { display: none; }
.phone-alert-visual { position: relative; width: 66px; height: 66px; border: 4px solid #fff; border-radius: 16px; background: radial-gradient(circle at 50% 40%, #fff3ef 0%, #ffdcd4 70%, #ffc9be 100%); box-shadow: 0 0 0 2px #f0b3a8; overflow: hidden; }
.phone-alert-visual i { position: absolute; display: block; }
.pa-phone { position: absolute; left: 50%; top: 50%; width: 26px; height: 38px; transform: translate(-50%,-50%); border-radius: 5px; background: #f8faf8; box-shadow: 0 0 0 2px #16323b, inset -3px -3px 0 rgba(0,0,0,.07); animation: pa-shake .45s linear infinite; }
.pa-screen { left: 4px; top: 4px; width: 12px; height: 7px; border-radius: 2px; background: #72d2dc; }
.pa-light { right: 3px; top: 4px; width: 5px; height: 5px; border-radius: 50%; background: #e95c52; animation: pa-blink .55s steps(1) infinite; }
.pa-handset { left: 3px; top: 14px; width: 8px; height: 21px; border-radius: 3px; background: #18779f; box-shadow: 0 0 0 1.5px #0f5b7a; }
.pa-keys { right: 3px; top: 15px; width: 11px; height: 18px; background-image: radial-gradient(#16323b 40%, transparent 42%); background-size: 5.5px 6px; opacity: .85; }
.pa-line { left: 50%; top: 50%; width: 11px; height: 3px; border-radius: 2px; background: #f2a03a; transform-origin: -14px 50%; animation: pa-burst 1.1s ease-out infinite; }
.pa-line.a { transform: rotate(20deg) translateX(18px); }
.pa-line.b { transform: rotate(90deg) translateX(20px); }
.pa-line.c { transform: rotate(160deg) translateX(18px); }
.pa-line.d { transform: rotate(200deg) translateX(18px); }
.pa-line.e { transform: rotate(270deg) translateX(20px); }
.pa-line.f { transform: rotate(340deg) translateX(18px); }
.phone-alert-copy { min-width: 0; }
.phone-alert-copy span { display: inline-block; padding: 3px 8px; border-radius: 999px; background: #e95c52; color: #fff; font-size: 8px; font-weight: 950; letter-spacing: .14em; }
.phone-alert-copy strong { display: block; margin: 6px 0 3px; color: #8c2f22; font: 800 15px/1.1 "Fredoka", sans-serif; }
.phone-alert-copy small { color: #9a6055; font-size: 10.5px; font-weight: 700; }
@keyframes pa-shake { 0%,100% { transform: translate(-50%,-50%) rotate(-6deg); } 50% { transform: translate(-50%,-50%) rotate(6deg); } }
@keyframes pa-blink { 0%,49% { opacity: 1; } 50%,100% { opacity: .2; } }
@keyframes pa-burst { 0% { opacity: 0; } 15% { opacity: 1; } 60%,100% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  .pa-phone, .pa-line, .pa-light { animation: none; }
}

.player-guide-copy { min-width: 0; }
.player-guide-copy small { display: block; color: #8fb4bc; font-size: 10px; font-weight: 900; letter-spacing: .2em; }
.player-guide-copy strong { display: block; margin-top: 5px; color: var(--teal); font: 950 19px/1.05 "Fredoka", sans-serif; letter-spacing: -.01em; }

/* Cart queue: compact cards tucked against the next-task panel on the left. */
.orders { display: flex; justify-content: flex-start; align-items: flex-start; gap: 10px; }
/* Recall flood: identical compact cards in neat rows — no timers, no pulse
   scaling, everything the same size. */
.orders.flood { flex-wrap: wrap; gap: 7px; }
.orders.flood .order-card { width: 100px; animation: none !important; transform: none !important; }
.orders.flood .order-head { gap: 4px; padding: 4px 6px; }
.orders.flood .order-head strong { font-size: 10.5px; white-space: nowrap; }
.orders.flood .order-head span { white-space: nowrap; }
.orders.flood .order-sealed svg { width: 26px; height: 26px; }
.orders.flood .order-track, .orders.flood .order-scan-track { display: none; }
.murmur-bubble.recall-shout { z-index: 30; }

.order-card {
  --accent: var(--teal);
  --accent-ink: #0f5f56;
  position: relative;
  width: 132px;
  overflow: hidden;
  border: 3px solid var(--ink);
  border-radius: 13px;
  background: var(--cream);
  box-shadow: 0 5px 0 var(--ink-deep), 0 10px 20px rgba(8,24,29,.24);
}
.order-card.card-enter { animation: order-card-in .55s ease both; }
@keyframes order-card-in {
  from { opacity: 0; transform: translateY(-12px) scale(.95); }
  to { opacity: 1; transform: none; }
}
.order-card.warn { --accent: var(--gold); --accent-ink: #9a6c12; }
.order-card.overdue { --accent: var(--coral); --accent-ink: #a32e27; animation: pulse .72s infinite alternate; }

.order-head {
  display: flex; align-items: center; justify-content: space-between; gap: 5px;
  padding: 4px 7px;
  background: var(--accent);
  border-bottom: 3px solid var(--ink);
}
.order-head strong { color: #fff; font: 950 12.5px/1 "Fredoka", sans-serif; letter-spacing: .01em; text-shadow: 0 1px 0 rgba(0,0,0,.22); }
.order-head span { color: rgba(255,255,255,.94); font-size: 8px; font-weight: 900; letter-spacing: .09em; }

.order-items { display: flex; justify-content: center; gap: 7px; padding: 8px 6px 9px; }
.order-chip {
  position: relative;
  width: 36px; height: 36px;
  /* flex, not grid: extra icons have to overlap in place rather than stacking
     into extra rows */
  display: flex; align-items: center; justify-content: center;
  border: 2.5px solid var(--ink);
  border-radius: 8px;
  /* one tint per core drug, matching its bay: atropine lilac, epinephrine red,
     lidocaine blue. The chip, the bin and the vial cap all say the same thing. */
  background: #fbeecb;
}
.order-chip.med-pack { background: #fbeecb; }
.order-chip.syringe { background: #e7dff6; }
.order-chip.seal { background: #e2e8ea; }
.order-chip.amber { background: #dbe6f8; }
.order-chip.cold { background: #f8dedb; }
.order-chip img { width: 22px; height: 22px; object-fit: contain; }
/* Two or three of a drug fan out the way the kit bubbles do, so a cart card
   shows what it wants rather than a count on a red dot. The chip never grows. */
.order-chip[data-n="2"] img { width: 19px; height: 19px; }
.order-chip[data-n="2"] img:nth-child(1) { margin-right: -7px; transform: rotate(-11deg) translateY(1px); }
.order-chip[data-n="2"] img:nth-child(2) { transform: rotate(9deg) translateY(-1px); }
/* tighter, and less tilt: a rotated icon's box is wider than the icon, so at
   three the fan was spilling a couple of pixels past a 36px chip */
.order-chip[data-n="3"] img { width: 15px; height: 15px; }
.order-chip[data-n="3"] img:nth-child(1) { margin-right: -8px; transform: rotate(-13deg) translateY(2px); }
.order-chip[data-n="3"] img:nth-child(2) { margin-right: -8px; transform: translateY(-1px); }
.order-chip[data-n="3"] img:nth-child(3) { transform: rotate(13deg) translateY(2px); }
.order-chip img:nth-child(2) { z-index: 1; }
.order-chip img:nth-child(3) { z-index: 2; }
.order-chip b {
  position: absolute; right: -5px; bottom: -5px;
  min-width: 17px; height: 17px; padding: 0 3px;
  display: grid; place-items: center;
  border: 2.5px solid var(--cream);
  border-radius: 999px;
  background: var(--coral);
  color: #fff; font: 900 10px/1 "Fredoka", sans-serif;
}
.order-sealed { display: grid; justify-items: center; gap: 3px; padding: 7px 6px 9px; }
.order-sealed svg { width: 34px; height: 34px; fill: none; stroke: #a4bcc2; stroke-width: 2.6; stroke-linejoin: round; }
.order-sealed small { color: #7b959b; font-size: 9.5px; font-weight: 900; letter-spacing: .1em; }
.order-scanning { display: grid; justify-items: center; gap: 4px; padding: 7px 8px 9px; }
.order-scanning svg { width: 28px; height: 28px; fill: none; stroke: var(--gold); stroke-width: 2.6; stroke-linejoin: round; }
.order-scanning small { color: #9a6c12; font-size: 9.5px; font-weight: 900; letter-spacing: .08em; }
.order-scan-track { width: 100%; height: 9px; border: 2.5px solid var(--ink); border-radius: 999px; background: #e8eeeb; overflow: hidden; }
.order-scan-track i { display: block; height: 100%; background: var(--gold); transition: width .12s linear; }
@media (prefers-reduced-motion: no-preference) {
  .order-scanning svg { animation: order-scan-pulse .9s ease-in-out infinite alternate; }
  @keyframes order-scan-pulse { to { opacity: .45; } }
}
.order-empty { padding: 13px 8px; color: #6f8a91; font-size: 10.5px; font-weight: 800; letter-spacing: .08em; text-align: center; }

.order-track { height: 9px; background: #dfe8e6; border-top: 3px solid var(--ink); }
.order-track i { display: block; height: 100%; background: var(--accent); transition: width .2s; }

.order-card.active { box-shadow: 0 7px 0 var(--ink-deep), 0 0 0 4px rgba(79,179,165,.5), 0 14px 26px rgba(8,24,29,.26); }

/* Shift name + live star progress */
.shift-panel {
  border: 4px solid var(--ink);
  border-radius: 18px;
  background: var(--cream);
  box-shadow: 0 7px 0 var(--ink-deep), 0 14px 28px rgba(8,24,29,.28);
  overflow: hidden;
}
.shift-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 9px 12px 10px; }
.shift-head small { display: block; color: #6f8a91; font-size: 9px; font-weight: 900; letter-spacing: .2em; }
.shift-head strong { display: block; margin-top: 2px; color: var(--ink); font: 950 15px/1 "Fredoka", sans-serif; }
.live-stars { display: flex; gap: 2px; flex: 0 0 auto; }
.live-stars i { width: 15px; height: 15px; background: #d3ded9; clip-path: polygon(50% 0%,61% 35%,98% 35%,68% 57%,79% 91%,50% 70%,21% 91%,32% 57%,2% 35%,39% 35%); transition: background .25s; }
.live-stars i.on { background: var(--gold); }
.shift-foot { display: flex; align-items: center; gap: 9px; padding: 7px 12px 9px; background: var(--ink); }
.shift-foot .stat-label { color: #8fb4bc; font-size: 9px; font-weight: 900; letter-spacing: .16em; }
.shift-foot strong { flex: 1 1 auto; color: #fff; font: 950 20px/1 "Fredoka", sans-serif; }
.stat-label { display: block; font-size: 9px; letter-spacing: .15em; opacity: .68; }
#score.practice { font-size: 14px; letter-spacing: .01em; }

/* Bottom-right shift clock */
.timer-panel {
  position: absolute;
  right: 20px; bottom: 20px;
  z-index: 10;
  width: 190px;
  padding: 10px 14px 12px;
  border: 4px solid var(--ink);
  border-radius: 18px;
  background: var(--cream);
  box-shadow: 0 7px 0 var(--ink-deep), 0 14px 28px rgba(8,24,29,.28);
  pointer-events: none;
  text-align: center;
}
.timer-panel strong { display: block; color: var(--coral); font: 950 44px/1 "Fredoka", sans-serif; letter-spacing: .02em; }
.timer-panel strong.practice { font-size: 24px; letter-spacing: .04em; color: var(--teal-deep); }
.timer-track { height: 11px; margin-top: 8px; border: 3px solid var(--ink); border-radius: 999px; background: #e6efec; overflow: hidden; }
.timer-track i { display: block; height: 100%; width: 100%; background: var(--coral); transition: width .25s linear; }
.timer-panel.plenty strong { color: var(--teal-deep); }
.timer-panel.plenty .timer-track i { background: var(--teal); }

.time-toggle {
  display: block;
  width: 100%;
  margin-top: 6px;
  padding: 5px 7px;
  border: 1px solid rgba(255,255,255,.55);
  border-radius: 7px;
  background: rgba(255,255,255,.14);
  box-shadow: none;
  color: white;
  pointer-events: auto;
  font-size: 8px;
  letter-spacing: .08em;
}body:not(.keys-driving) .time-toggle:hover { transform: none; box-shadow: none; background: rgba(255,255,255,.24); }
.time-toggle:active { transform: none; box-shadow: none; }
.time-toggle.frozen { background: #f6be3e; border-color: #fff1b9; color: #463607; }
.time-toggle:disabled { cursor: default; opacity: .82; background: rgba(126,212,178,.28); color: #dff8ed; }

.screen-card {
  position: absolute;
  left: 50%;
  top: 50%;
  width: min(590px, calc(100% - 36px));
  transform: translate(-50%, -50%);
  padding: 32px 38px 34px;
  background: rgba(255,250,240,.96);
  border: 5px solid white;
  border-radius: 32px;
  text-align: center;
  box-shadow: 0 14px 0 #173e4a, 0 30px 80px rgba(3,20,26,.4);
  z-index: 20;
}

.eyebrow { color: #e95c52; font-size: 12px; font-weight: 900; letter-spacing: .18em; }
h1, h2 { margin: 7px 0 8px; font-family: "Fredoka", sans-serif; line-height: .95; }
h1 { font-size: clamp(54px, 8vw, 84px); color: #173e4a; letter-spacing: -.04em; }
h1 span { color: #e95c52; }
h2 { font-size: 48px; color: #173e4a; }
.screen-card > p { max-width: 450px; margin: 0 auto 22px; color: #58717a; font-size: 17px; }

.level-map {
  --route-ink: #123037;
  --route-muted: #5d746f;
  --route-paper: #f8f2e3;
  position: absolute;
  inset: 0;
  z-index: 32;
  display: flex;
  flex-direction: column;
  min-height: 620px;
  overflow: hidden;
  color: var(--route-ink);
  background: #0d252b;
  animation: map-enter .45s ease-out both;
}
.route-topbar { z-index: 4; display: flex; flex: 0 0 76px; align-items: center; gap: 22px; height: 76px; padding: 0 26px; border-bottom: 3px solid #0c2228; background: linear-gradient(180deg,#173a42,#123037); box-shadow: 0 6px 20px -8px rgba(0,0,0,.5); color: #eef6f2; }
.route-brand { width: 188px; height: auto; }
.route-divider { width: 2px; height: 34px; border-radius: 2px; background: rgba(255,255,255,.14); }
.route-facility { display: flex; flex-direction: column; min-width: 0; }
.route-facility span { color: #6fb6ab; font-size: 10px; font-weight: 900; letter-spacing: .2em; }
.route-facility strong { margin-top: 1px; color: #fff6e5; font: 800 20px/1.05 "Fredoka", sans-serif; }
.route-star-total { display: grid; grid-template-columns: 18px auto; align-items: center; gap: 0 8px; margin-left: auto; padding: 8px 14px; border: 1px solid rgba(255,255,255,.1); border-radius: 999px; background: rgba(255,255,255,.07); }
.route-star-total img { grid-row: 1 / span 2; width: 18px; height: 18px; }
.route-star-total small { color: #8fc4bb; font-size: 8px; font-weight: 900; letter-spacing: .14em; }
.route-star-total strong { color: white; font-size: 13px; }
.route-stage { position: relative; flex: 1 1 auto; min-height: 0; overflow: hidden; background: radial-gradient(ellipse at 18% 25%,rgba(255,255,255,.9) 0 4%,transparent 24%),radial-gradient(ellipse at 84% 74%,rgba(56,139,128,.14),transparent 28%),linear-gradient(180deg,#edf5f1 0 42%,#d2e6dc 42% 49%,#bfdacb 49% 100%); }
.route-stage::before { content: ""; position: absolute; inset: 0; pointer-events: none; background-image: linear-gradient(rgba(31,111,104,.075) 1px,transparent 1px),linear-gradient(90deg,rgba(31,111,104,.075) 1px,transparent 1px),linear-gradient(180deg,transparent 0 47%,rgba(255,255,255,.5) 47% 48%,rgba(57,133,122,.12) 48% 49%,transparent 49%); background-size: 64px 64px,64px 64px,100% 100%; background-position: center; mask-image: radial-gradient(145% 110% at 50% 42%,#000 64%,transparent 100%); }
.route-stage::after { content: "CHICKEN HEALTH  •  PHARMACY SERVICE ROUTE"; position: absolute; left: 50%; bottom: 13px; transform: translateX(-50%); color: rgba(31,111,104,.22); font-size: 10px; font-weight: 900; letter-spacing: .32em; white-space: nowrap; }
.route-board { position: absolute; left: 50%; top: 50%; width: 1160px; height: 600px; transform: translate(-50%,-50%); transform-origin: center; }
.route-landmarks { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.route-landmarks > div { position: absolute; display: grid; grid-template-columns: 30px auto; grid-template-rows: auto auto; align-items: center; column-gap: 10px; width: 210px; padding: 11px 14px; border: 1px solid rgba(61,132,121,.16); border-radius: 14px; background: rgba(255,255,255,.28); box-shadow: inset 0 1px rgba(255,255,255,.6); color: rgba(31,111,104,.5); }
.route-landmarks > div:nth-child(1) { left: 46px; top: 70px; }
.route-landmarks > div:nth-child(2) { left: 472px; top: 58px; }
.route-landmarks > div:nth-child(3) { right: 18px; top: 58px; }
.route-landmarks img { grid-row: 1 / span 2; width: 28px; height: 28px; opacity: .42; }
.route-landmarks span { font-size: 10px; font-weight: 900; letter-spacing: .12em; }
.route-landmarks small { margin-top: 2px; font-size: 7px; font-weight: 800; letter-spacing: .08em; }
.route-map-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.route-path-base,.route-path-guide,.route-path-done { fill: none; stroke-linecap: round; stroke-linejoin: round; }
.route-path-base { stroke: #b9d3c8; stroke-width: 20; opacity: .55; }
.route-path-guide { stroke: #8fb7ab; stroke-width: 5; stroke-dasharray: 2 22; opacity: .9; animation: route-flow 2.4s linear infinite; }
.route-path-done { stroke: url(#route-teal-line); stroke-width: 14; filter: drop-shadow(0 4px 6px rgba(31,111,104,.35)); }
.route-destination-zone { position: absolute; left: 958px; top: 152px; width: 184px; height: 196px; border: 4px dashed rgba(47,143,134,.38); border-radius: 22px; background: linear-gradient(145deg,rgba(255,255,255,.16),rgba(72,154,142,.07)); box-shadow: inset 0 0 0 10px rgba(255,255,255,.08); }
.route-node { position: absolute; z-index: 3; display: block; width: 70px; height: 70px; padding: 0; border: 0; border-radius: 50%; background: #fdf8ec; box-shadow: 0 0 0 6px white,0 0 0 8px rgba(18,48,55,.1),0 12px 20px -8px rgba(18,48,55,.5); color: var(--route-ink); }body:not(.keys-driving) .route-node:hover { transform: translateY(-3px); box-shadow: 0 0 0 6px white,0 0 0 8px rgba(18,48,55,.1),0 15px 22px -8px rgba(18,48,55,.55); }
.route-node > b { display: grid; place-items: center; width: 100%; height: 100%; font: 800 26px "Fredoka", sans-serif; }
.route-node > b img { width: 24px; height: 24px; }
.route-node > span { position: absolute; left: 50%; top: calc(100% + 16px); display: flex; flex-direction: column; width: max-content; min-width: 128px; max-width: 210px; transform: translateX(-50%); padding: 8px 14px 9px; border: 1px solid #ece0c7; border-radius: 12px; background: #fdf8ec; box-shadow: 0 10px 24px -10px rgba(18,48,55,.45),0 2px 0 rgba(18,48,55,.06); text-align: center; }
.route-node > span small { color: #1f6f68; font-size: 9px; font-weight: 900; letter-spacing: .16em; }
.route-node > span strong { margin-top: 2px; color: var(--route-ink); font: 800 14px/1.1 "Fredoka", sans-serif; white-space: nowrap; }
.route-node > span em { display: flex; justify-content: center; gap: 2px; margin-top: 5px; font-style: normal; }
.route-node > span em img { width: 13px; height: 13px; }
.route-node > span em img.empty-star,.route-meta b img.empty-star { opacity: .28; filter: grayscale(1); }
.route-node.origin { left: 78px; top: 208px; }
.route-node.current { width: 84px; height: 84px; background: radial-gradient(120% 120% at 50% 25%,#f07a63,#e86a52); color: white; box-shadow: 0 0 0 6px white,0 0 0 9px #e86a52,0 16px 26px -10px rgba(197,80,60,.7); }
.route-node.selected::after { content: ""; position: absolute; inset: -15px; border: 3px solid #e86a52; border-radius: 50%; animation: route-halo 2.2s ease-out infinite; }
.route-node.current > span em { min-width: 58px; }
.route-node.locked { width: 70px; height: 70px; cursor: pointer; background: repeating-linear-gradient(45deg,#f2b03a 0 12px,#22333a 12px 24px); }
.route-node.locked.selected::after { border-color: #2f8f86; }
.route-node.locked > b img { width: 22px; height: 22px; padding: 5px; border-radius: 8px; background: #fdf8ec; }
.route-node.locked > span strong { margin-top: 5px; padding: 3px 8px; border-radius: 6px; background: repeating-linear-gradient(45deg,#f7c65a 0 8px,#efe6cf 8px 16px); color: #8a5a12; font-size: 9px; letter-spacing: .1em; }
.route-node.level-two { left: 325px; top: 395px; }
.route-node.level-three { left: 585px; top: 245px; }
.route-node.level-four { left: 845px; top: 405px; }
.route-node.destination { left: 1020px; top: 220px; width: 60px; height: 60px; background: #3f9c93; color: #eafffb; }
.map-character-token { position: absolute; z-index: 5; left: 360px; top: 430px; width: 86px; height: 116px; transform: translate(-50%,-92%); pointer-events: none; filter: drop-shadow(0 8px 8px rgba(18,48,55,.34)); }
#map-character-canvas { display: block; width: 100%; height: 100%; background: transparent; }
.route-dock { z-index: 5; display: flex; flex: 0 0 116px; align-items: center; gap: 26px; min-height: 116px; padding: 15px 30px; border-top: 3px solid #ece0c7; background: linear-gradient(180deg,#fdf8ec,#f8f2e3); box-shadow: 0 -8px 22px -12px rgba(18,48,55,.4); }
.route-brief { flex: 1 1 auto; min-width: 0; }
.route-brief > span { color: #c5503c; font-size: 9px; font-weight: 900; letter-spacing: .2em; }
.route-brief h2 { margin: 3px 0 3px; color: var(--route-ink); font-size: 25px; line-height: 1; }
.route-brief p { margin: 0; color: var(--route-muted); font-size: 12px; font-weight: 600; }
.route-meta { display: flex; gap: 8px; margin-top: 8px; }
.route-meta > span { display: inline-flex; align-items: center; gap: 7px; padding: 5px 10px; border: 1px solid #ece0c7; border-radius: 999px; background: white; }
.route-meta small { color: var(--route-muted); font-size: 8px; font-weight: 900; letter-spacing: .12em; }
.route-meta b { color: var(--route-ink); font-size: 11px; }
.route-meta b img { width: 13px; height: 13px; }
.route-actions { display: flex; flex: 0 0 auto; flex-direction: column; align-items: flex-end; gap: 8px; }
.route-actions button { display: flex; align-items: center; gap: 10px; min-width: 220px; justify-content: center; padding: 14px 28px; border-radius: 16px; background: linear-gradient(180deg,#ef7259,#e86a52); box-shadow: 0 6px 0 #c5503c,0 14px 22px -8px rgba(197,80,60,.6); font-size: 15px; }
.route-actions button img { width: 18px; height: 18px; color: white; filter: brightness(0) invert(1); }
.route-actions button:disabled { cursor: default; background: linear-gradient(180deg,#7e9897,#657e7d); box-shadow: 0 6px 0 #4b6261,0 14px 22px -8px rgba(18,48,55,.35); opacity: 1; }
.route-actions > small { color: var(--route-muted); font-size: 10px; font-weight: 800; }
@keyframes route-flow { to { stroke-dashoffset: -24; } }
@keyframes route-halo { 0% { transform: scale(.9); opacity: .55; } 70%,100% { transform: scale(1.5); opacity: 0; } }
@keyframes map-enter { from { opacity: 0; transform: scale(1.025); } to { opacity: 1; transform: scale(1); } }
@media (max-height: 760px) { .route-topbar { flex-basis: 66px; height: 66px; } .route-dock { flex-basis: 104px; min-height: 104px; padding-top: 10px; padding-bottom: 10px; } }

.workflow { display: flex; align-items: center; justify-content: center; gap: 12px; margin: 18px 0; }
.workflow div { display: flex; flex-direction: column; align-items: center; gap: 5px; }
.workflow b { display: grid; place-items: center; width: 38px; height: 38px; border-radius: 12px; background: #55c48b; color: white; font: 700 21px "Fredoka", "Avenir Next", "Trebuchet MS", system-ui, sans-serif; }
.workflow span { font-size: 11px; text-transform: uppercase; letter-spacing: .05em; }
.workflow i { color: #b3c4c3; font: 700 34px "Fredoka", "Avenir Next", "Trebuchet MS", system-ui, sans-serif; }

.controls { display: flex; justify-content: center; flex-wrap: wrap; gap: 8px 16px; margin: 18px 0 22px; color: #58717a; font-size: 12px; }
kbd, .keycap { padding: 4px 7px; border: 0; border-radius: 7px; background: #dceae8; color: #173e4a; box-shadow: 0 3px 0 #b6cbc8; font: 900 11px "Nunito", "Avenir Next", "Trebuchet MS", system-ui, sans-serif; }

button {
  border: 0;
  border-radius: 15px;
  padding: 14px 24px;
  background: #e95c52;
  color: white;
  box-shadow: 0 6px 0 #ae3e39;
  cursor: pointer;
  font: 900 14px "Nunito", "Avenir Next", "Trebuchet MS", system-ui, sans-serif;
  letter-spacing: .06em;
  transition: transform .12s, box-shadow .12s;
}body:not(.keys-driving) button:hover { transform: translateY(-2px); box-shadow: 0 8px 0 #ae3e39; }
button:active { transform: translateY(4px); box-shadow: 0 2px 0 #ae3e39; }

.interaction-prompt {
  position: absolute;
  left: 50%;
  bottom: 34px;
  display: flex;
  align-items: center;
  gap: 10px;
  transform: translateX(-50%);
  padding: 12px 24px 12px 12px;
  border: 4px solid var(--ink);
  border-radius: 999px;
  background: var(--ink);
  color: #fff;
  box-shadow: 0 7px 0 var(--ink-deep), 0 14px 26px rgba(8,24,29,.3);
  font: 950 15px "Nunito", "Avenir Next", "Trebuchet MS", system-ui, sans-serif;
  letter-spacing: .04em;
  z-index: 12;
}
/* ---- the guide voice ----------------------------------------------------------
   Out of reach of everything, the same pill turns into a cream ticket that says
   what to do next, with a small gold NEXT tab hanging off its top edge. It is
   never dark during a shift: the instruction is up until a press would do
   something, then the ink keycap takes over, then the ticket comes back. */
.interaction-prompt.guide {
  padding: 12px 22px 12px 22px;
  background: var(--cream); color: var(--ink);
  border-color: var(--ink);
  box-shadow: 0 6px 0 var(--ink-deep), 0 12px 22px rgba(8,24,29,.22);
  font: 950 15px "Fredoka", "Nunito", sans-serif; letter-spacing: .06em;
  animation: guide-in .28s cubic-bezier(.2,1.4,.4,1);
}
.interaction-prompt.guide .keycap { display: none; }
.interaction-prompt.guide #interaction-text { display: inline; }
.interaction-prompt.guide::before {
  content: "NEXT"; position: absolute; left: 18px; top: -13px;
  padding: 3px 8px 2px; border-radius: 7px 7px 3px 3px;
  background: var(--gold); color: var(--ink-deep); border: 3px solid var(--ink);
  font: 900 9px/1 "Nunito", sans-serif; letter-spacing: .24em;
  box-shadow: 0 2px 0 var(--ink-deep);
}
@keyframes guide-in { from { transform: translate(-50%, 10px) scale(.94); opacity: 0; } to { transform: translate(-50%, 0) scale(1); opacity: 1; } }
body.cabinet .interaction-prompt.guide { font-size: 23px; padding: 16px 30px; }
body.cabinet .interaction-prompt.guide::before { font-size: 12px; top: -16px; left: 24px; }

/* ---- the grab sticker ---------------------------------------------------------
   The tech faces AWAY from the camera when taking a tray off a cart, so the
   grab itself is invisible. A sticker slams in above their head the instant the
   tray is in hand and peels away a beat later; main.js projects it onto the
   player each frame while it lives. */
.grab-sticker {
  position: fixed; left: 0; top: 0; z-index: 30; pointer-events: none;
  transform: translate(-50%, -100%) rotate(-7deg);
  padding: 8px 16px; border-radius: 12px;
  background: var(--gold); color: var(--ink-deep);
  border: 4px solid var(--ink); box-shadow: 0 5px 0 var(--ink-deep), 0 10px 18px rgba(8,24,29,.28);
  font: 950 22px/1 "Fredoka", sans-serif; letter-spacing: .06em; white-space: nowrap;
  animation: grab-stamp .95s cubic-bezier(.2,1.5,.4,1) forwards;
}
.grab-sticker::after {
  content: ""; position: absolute; left: 50%; bottom: -11px; width: 12px; height: 12px;
  transform: translateX(-50%) rotate(45deg); background: var(--ink); border-radius: 0 0 3px 0; z-index: -1;
}
@keyframes grab-stamp {
  0%   { transform: translate(-50%, -100%) rotate(-18deg) scale(2.4); opacity: 0; }
  18%  { transform: translate(-50%, -100%) rotate(-7deg) scale(1); opacity: 1; }
  78%  { transform: translate(-50%, -100%) rotate(-7deg) scale(1); opacity: 1; }
  100% { transform: translate(-50%, -130%) rotate(-3deg) scale(.9); opacity: 0; }
}
body.cabinet .grab-sticker { font-size: 34px; padding: 11px 22px; }
/* the hands slot that just received the tray slams in too */
.inventory-grid.got { animation: slot-got .4s cubic-bezier(.2,1.6,.4,1); }
@keyframes slot-got { 0% { transform: scale(.6); } 60% { transform: scale(1.18); } 100% { transform: scale(1); } }

/* ---- the yellow button, and the green beside it -------------------------------
   The pill IS the button: a gold face with the disc and what a press will do -
   GRAB on its own, GRAB TRAY / PLACE TRAY / SCAN when you are on something. Lit
   pulses the disc. To its right, in green, the next action: where to go now.
   Two shapes, two jobs - the button is your hand, the green is your feet. */
.interaction-prompt {
  gap: 12px; padding: 9px 12px 9px 9px;
  background: var(--gold); color: var(--ink-deep); border-color: var(--ink);
  font: 950 15px "Fredoka", "Nunito", sans-serif; letter-spacing: .06em;
}
.interaction-prompt #interaction-text { display: inline; text-transform: uppercase; }
.interaction-prompt .keycap { border: 3px solid var(--ink); border-radius: 50%; background: #ffd400; box-shadow: inset 0 -4px 0 rgba(0,0,0,.18), inset 0 3px 0 rgba(255,255,255,.5); }
.interaction-prompt.lit .keycap { animation: keycap-pulse 1s ease-in-out infinite alternate; }
/* The button is no longer centred: main.js parks it directly above the hands
   panel (left/bottom set from the panel's live rect), by itself. */
.interaction-prompt { left: 20px; right: auto; transform: none; }
/* The green NEXT, its own element to the right of the hands panel. */
.next-action {
  position: absolute; z-index: 12; pointer-events: none;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 16px 9px 10px;
  border-radius: 999px; border: 4px solid var(--ink);
  background: #55c48b; color: var(--ink-deep);
  font: 900 13px "Nunito", sans-serif; letter-spacing: .14em; text-transform: uppercase; white-space: nowrap;
  box-shadow: 0 5px 0 var(--ink-deep), 0 10px 18px rgba(8,24,29,.22);
}
.next-action::before {
  content: "NEXT"; padding: 3px 7px 2px; border-radius: 6px;
  background: var(--ink); color: #b8f0d0; font: 900 8.5px/1 "Nunito", sans-serif; letter-spacing: .22em;
}
.next-action:empty, .next-action.hidden { display: none; }
body.cabinet .next-action { font-size: 19px; padding: 12px 22px 12px 14px; }
body.cabinet .next-action::before { font-size: 11px; }
/* Tutorial-only compact form: just the pulsing action key, no sentence. */
.interaction-prompt.compact { padding: 9px; }
.interaction-prompt.compact #interaction-text { display: none; }
.interaction-prompt.compact .next-action { display: none; }
.interaction-prompt.compact .keycap { animation: keycap-pulse 1s ease-in-out infinite alternate; }
@keyframes keycap-pulse { to { transform: scale(1.18); box-shadow: 0 3px 0 #b6cbc8, 0 0 14px rgba(242,179,61,.8); } }

.interaction-prompt .keycap {
  display: grid; place-items: center;
  width: 30px; height: 30px;
  border-radius: 9px;
  background: var(--gold);
  color: var(--ink-deep);
  font: 950 15px "Fredoka", sans-serif;
}
/* On the cabinet this prompt is read at arm's length from a standing player,
   across a room-sized screen, so it carries far more weight than it does on a
   desktop monitor a foot from your face. */
body.cabinet .interaction-prompt {
  bottom: 46px; gap: 16px; padding: 16px 32px 16px 16px;
  font-size: 24px; border-width: 5px;
}
body.cabinet .interaction-prompt .keycap { width: 46px; height: 46px; font-size: 23px; }
body.cabinet .interaction-prompt .keycap.pad-cab { width: 1.55em; height: 1.55em; }

/* ---- denial chips -----------------------------------------------------------
   A one-line reason a grab did not happen. .waste-chip had NO rule anywhere:
   the element was created, appended to the body, positioned over the bin and
   toggled, but never styled and never hidden - so "on" did nothing and the
   text simply sat on the screen as raw markup. The waste one is projected onto
   the bin (main.js writes left/top in viewport coords, hence fixed); the
   restock one is a screen chip, since the table it refers to is where you are
   already standing. */
.waste-chip {
  position: fixed; transform: translate(-50%, -125%);
  padding: 8px 16px; border-radius: 999px;
  background: #fdf0e2; color: #14343c; border: 3px solid #14343c;
  box-shadow: 0 4px 0 #14343c;
  font: 950 14px "Nunito", sans-serif; letter-spacing: .1em; white-space: nowrap;
  opacity: 0; pointer-events: none; z-index: 14; transition: opacity .18s ease;
}
.restock-chip {
  position: absolute; left: 50%; bottom: 104px;
  transform: translateX(-50%) translateY(8px);
  padding: 10px 20px; border-radius: 999px;
  background: #fdf0e2; color: #14343c; border: 4px solid #14343c;
  box-shadow: 0 5px 0 #14343c;
  font: 950 15px "Nunito", sans-serif; letter-spacing: .1em; white-space: nowrap;
  opacity: 0; pointer-events: none; z-index: 14;
  transition: opacity .18s ease, transform .18s ease;
}
.waste-chip.on { opacity: 1; }
.restock-chip.on { opacity: 1; transform: translateX(-50%) translateY(0); }
body.cabinet .waste-chip { font-size: 20px; padding: 11px 22px; }
body.cabinet .restock-chip { font-size: 23px; padding: 13px 26px; bottom: 132px; }

/* Hands: one slot per carried item, spread along the bottom-left. */
/* Battle's hands row, ported over. The shift's panel was carrying a 5px border,
   a 22px radius and an 8px drop plus a 32px blur, against battle's 3px, 15px and
   a flat 5px drop - so the same five slots sat under noticeably more chrome in
   one mode than the other. These are battle's numbers exactly. */
.inventory-panel {
  position: absolute;
  left: 20px;
  bottom: 20px;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 7px 9px;
  border: 3px solid var(--ink);
  border-radius: 15px;
  background: var(--cream);
  box-shadow: 0 5px 0 var(--ink-deep);
  z-index: 11;
}

/* Battle has no such caption and does not need one - five slots count
   themselves, the same reason the 0/5 came off the battle row. */
.hands-label { display: none; }
.hands-label b { color: var(--teal-deep); }

/* Hands at capacity: the whole panel goes coral and calls it out. */
.hands-full {
  display: none;
  padding: 6px 9px;
  border: 3px solid var(--coral);
  border-radius: 11px;
  background: var(--coral);
  color: #fff;
  font: 950 11px/1.15 "Fredoka", sans-serif;
  letter-spacing: .08em;
  text-align: center;
}
.inventory-panel.full { border-color: var(--coral); background: #fff2ef; box-shadow: 0 7px 0 #a32e27, 0 14px 28px rgba(163,46,39,.3); }
.inventory-panel.full .hands-label { color: var(--coral); }
.inventory-panel.full .hands-label b { color: var(--coral); }
.inventory-panel.full .inventory-slot { border-color: var(--coral); }
.inventory-panel.full .hands-full { display: block; }
@media (prefers-reduced-motion: no-preference) {
  .inventory-panel.full { animation: hands-full-pop .32s cubic-bezier(.2,.9,.3,1.5); }
  @keyframes hands-full-pop { 40% { transform: translateY(-4px) scale(1.02); } }
}

.inventory-grid {
  display: flex;
  gap: 6px;
}

.inventory-slot {
  position: relative;
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border: 3px solid var(--ink);
  border-radius: 13px;
  background: #fbeecb;
}
.inventory-slot.med-pack { background: #fbeecb; }
.inventory-slot.syringe { background: #e7dff6; }
.inventory-slot.seal { background: #e2e8ea; }
.inventory-slot.amber { background: #dbe6f8; }
.inventory-slot.cold { background: #f8dedb; }

.inventory-slot.empty {
  border-style: dashed;
  border-color: #a9bcc0;
  background: rgba(255,255,255,.5);
}
.inventory-slot.empty img, .inventory-slot.empty b { display: none; }
.inventory-slot img {
  width: 38px;
  height: 38px;
  object-fit: contain;
  filter: drop-shadow(0 2px 1px rgba(10,35,42,.22));
}
.inventory-slot b { display: none; }
.inventory-slot.received-item { animation: inventory-receive .34s cubic-bezier(.2,.9,.3,1.4); }

.bin-icon-layer {
  position: absolute;
  inset: 0;
  z-index: 9;
  pointer-events: none;
}
.bin-icon-layer img {
  position: absolute;
  width: 46px;
  height: 46px;
  transform: translate(-50%, -50%);
  object-fit: contain;
  filter: drop-shadow(0 3px 1px rgba(8,31,38,.4));
}
.item-fly {
  position: fixed;
  z-index: 90;
  width: 58px;
  height: 58px;
  object-fit: contain;
  pointer-events: none;
  filter: drop-shadow(0 7px 3px rgba(9,35,42,.38));
}

/* Real pause: dark overlay with a small menu; the world stops behind it. */
.pause-menu {
  position: absolute;
  inset: 0;
  z-index: 70;
  display: grid;
  place-items: center;
  background: rgba(9, 32, 40, .72);
}
.pause-card {
  display: grid;
  gap: 12px;
  justify-items: stretch;
  min-width: 300px;
  padding: 26px 28px 24px;
  border: 4px solid var(--ink);
  border-radius: 22px;
  background: var(--cream);
  box-shadow: 0 10px 0 var(--ink-deep), 0 26px 60px rgba(0,0,0,.4);
  text-align: center;
}
.pause-card h1 { margin: 0 0 6px; color: var(--ink); font: 800 34px/1 "Fredoka", "Avenir Next", sans-serif; }
.pause-card button { font: 900 13px "Fredoka", "Avenir Next", "Trebuchet MS", system-ui, sans-serif; letter-spacing: .1em; }
.pause-card #pause-resume { background: var(--teal); box-shadow: 0 6px 0 #2e8b7a; }
.pause-card #pause-sound { background: #f2b33d; box-shadow: 0 6px 0 #b07f18; color: #123c47; }
.pause-card #pause-quit { background: #7b959b; box-shadow: 0 6px 0 #55707a; }

/* Recall finale: pulsing alarm vignette, Ed's shout, the StatStock pitch. */
.recall-alarm {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 6;
  box-shadow: inset 0 0 140px rgba(232, 82, 74, .55);
  animation: recall-pulse .5s ease-in-out infinite alternate;
}
@keyframes recall-pulse { to { box-shadow: inset 0 0 60px rgba(232, 82, 74, .2); } }
.murmur-bubble.recall-shout {
  max-width: 250px;
  border-color: #a32e27;
  background: #fff2ef;
  color: #a32e27;
  font: 900 14px/1.25 "Fredoka", "Avenir Next", "Trebuchet MS", system-ui, sans-serif;
  animation: recall-shake .14s linear infinite alternate;
  z-index: 12;
}
@keyframes recall-shake { from { margin-top: -2px; } to { margin-top: 2px; } }
.recall-card { max-width: 430px; }
.recall-kicker { color: #a32e27; font-size: 11px; font-weight: 950; letter-spacing: .22em; }
.recall-card h1 { font-size: 30px; }
.recall-card p { margin: 2px 0 8px; color: #4a666e; font-size: 14px; font-weight: 600; line-height: 1.45; }
.recall-card #recall-buy { background: #e8524a; box-shadow: 0 6px 0 #a32e27; }
.recall-card #recall-buy b { color: #ffe9a0; }
.recall-card #recall-continue { background: var(--teal); box-shadow: 0 6px 0 #2e8b7a; }
.recall-card input {
  min-height: 44px;
  padding: 0 14px;
  border: 3px solid var(--ink);
  border-radius: 10px;
  outline: none;
  background: #fff;
  color: var(--ink);
  font: 700 16px "Avenir Next", "Trebuchet MS", system-ui, sans-serif;
  text-align: center;
}
.recall-card input:focus { border-color: var(--teal); }
.recall-card #recall-idk, .recall-card #recall-guess { background: #7b959b; box-shadow: 0 6px 0 #55707a; }
.recall-card #recall-monthly, .recall-card #recall-yearly,
.recall-card #recall-tags-next, .recall-card #recall-where-next { background: var(--teal); box-shadow: 0 6px 0 #2e8b7a; }

/* Waiting staff grumble to each other about the missing cart. */
/* Coins live in their own little box beside the shift timer. */
.coin-panel {
  position: absolute;
  right: 224px; bottom: 20px;
  z-index: 10;
  display: flex; align-items: center; gap: 9px;
  padding: 14px 18px;
  border: 4px solid var(--ink);
  border-radius: 18px;
  background: var(--cream);
  box-shadow: 0 7px 0 var(--ink-deep), 0 14px 28px rgba(8,24,29,.28);
  pointer-events: none;
}
.coin {
  width: 26px; height: 26px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #ffe9a6, #f2b33d 62%, #c8871c);
  border: 3px solid #8a5e12;
  box-shadow: inset 0 -3px 0 rgba(0,0,0,.18);
}
#coin-total { display: inline-block; font: 900 26px/1 "Fredoka", "Avenir Next", "Trebuchet MS", system-ui, sans-serif; color: #b07f18; }
#coin-total.bump { animation: coin-bump .3s ease; }
@keyframes coin-bump { 35% { transform: scale(1.3); } }

.murmur-bubble {
  position: fixed;
  left: 0; top: 0;
  transform: translate(-50%, -115%);
  max-width: 168px;
  padding: 7px 11px;
  border: 3px solid var(--ink);
  border-radius: 12px;
  background: var(--cream);
  box-shadow: 0 4px 0 var(--ink-deep);
  color: #234a54;
  font: 800 11px/1.25 "Fredoka", "Avenir Next", "Trebuchet MS", system-ui, sans-serif;
  text-align: center;
  pointer-events: none;
  z-index: 8;
  transition: opacity .18s linear;
}
.murmur-bubble::after {
  content: "";
  position: absolute;
  left: 50%; bottom: -10px;
  width: 12px; height: 12px;
  transform: translateX(-50%) rotate(45deg);
  background: var(--ink);
  clip-path: polygon(0 0, 100% 100%, 100% 0);
}

/* Overcooked-style needs: free-floating item circles with corner quantities. */
.slot-bubble {
  position: fixed;
  left: 0; top: 0;
  transform: translate(-50%, -100%);
  transition: opacity .12s linear;
  /* A COLUMN, not a row. Laid out sideways, a tray wanting four or five drugs
     grew wider than the gap between squares and sat on its neighbour — worse
     in battle, which has four squares at the same spacing. The anchor pins the
     bubble above its own square, so growing downward is impossible and growing
     UPWARD is free: there is nothing over the table but wall. */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 4px;
  pointer-events: none;
  z-index: 9;
  text-align: center;
}
.sb-cart { display: none; }
.sb-unknown {
  position: relative;
  display: grid; place-items: center;
  width: 33px; height: 33px;
  border: 3.5px solid var(--ink);
  border-radius: 50%;
  background: #fff;
  font: 950 16px/1 "Fredoka", sans-serif; color: #7f95d2;
}
.sb-scan {
  position: relative;
  display: grid; place-items: center;
  width: 33px; height: 33px;
  border: 3.5px solid var(--ink);
  border-radius: 50%;
  background: #fff;
  font: 950 11px/1 "Fredoka", sans-serif; color: #b07f18;
}
.sb-ready {
  padding: 8px 12px;
  border: 3px solid #2f8f5f;
  border-radius: 999px;
  background: #fff;
  box-shadow: 0 4px 0 rgba(12,42,51,.3);
  font: 950 13px/1 "Fredoka", sans-serif; color: #2f8f5f;
}
.slot-bubble small {
  padding: 2px 7px;
  border: 2px solid var(--ink);
  border-radius: 999px;
  background: #fff;
  font-size: 8px; font-weight: 900; letter-spacing: .12em; color: #8aa0a6;
}
/* Three across, wrapping to a second row at four.
   Bubbles alternate north and south of the table, so the nearest bubble at the
   same depth is TWO squares away, not one — about 13.6% of the canvas rather
   than 6.8%. That is 142px at a 1045 canvas and 258px at 1900, which is enough
   for a proper row of three at a readable size. */
/* One row, however many kinds there are. This was pinned to three columns, so a
   tray wanting four drugs dropped the fourth onto a second line under the other
   three and the bubble stopped reading as a row at all. auto-flow column keeps
   them on one line, and the chips give up size to make room rather than the
   bubble growing into its neighbour. */
.sb-chips {
  display: grid;
  grid-auto-flow: column;
  justify-content: center;
  gap: 5px;
}
.sb-chips[data-kinds="4"] { gap: 4px; }
.sb-chips[data-kinds="4"] .sb-chip { width: clamp(24px, 3.2vw, 56px); height: clamp(24px, 3.2vw, 56px); border-width: 3.5px; }
.sb-chips[data-kinds="5"] { gap: 3px; }
.sb-chips[data-kinds="5"] .sb-chip { width: clamp(21px, 2.7vw, 46px); height: clamp(21px, 2.7vw, 46px); border-width: 3px; }
.sb-chip {
  position: relative;
  display: grid; place-items: center;
  /* A third of the doubled spacing, less the gaps between columns. 42px on a
     1045 canvas and 70px on a wide one — well up from the 38px these were —
     and it gives way before it can collide on a small one. */
  width: clamp(28px, 4vw, 70px);
  height: clamp(28px, 4vw, 70px);
  border: 4px solid var(--ink);
  border-radius: 50%;
  background: #fff;
}
/* grid stacked extra icons into extra rows; a centred flex row lets them
   overlap in place instead */
.sb-chip { display: flex; align-items: center; justify-content: center; }
/* outlines colour-matched to each item's bay: blue / pink / amber */
/* The bubbles over a kit now carry the same washed plate the inventory slots
   do, so an icon sits on its drug's colour whether it is in your hands or on
   the board. Ring and count badge stay the full-strength colour. */
.sb-chip.med-pack { border-color: #f2c230; background: #fbeecb; }
.sb-chip.med-pack::after { background: #f2c230; }
.sb-chip.syringe { border-color: #7b52c4; background: #e7dff6; }
.sb-chip.syringe::after { background: #7b52c4; }
.sb-chip.seal { border-color: #8d9aa3; background: #e2e8ea; }
.sb-chip.seal::after { background: #8d9aa3; }
.sb-chip.amber { border-color: #3f7fd0; background: #dbe6f8; }
.sb-chip.amber::after { background: #3f7fd0; }
.sb-chip.cold { border-color: #d33426; background: #f8dedb; }
.sb-chip.cold::after { background: #d33426; }
.sb-chip img { width: 66%; height: 66%; object-fit: contain; }
/* Two or three of a drug fan out like cards in a hand: each steps out from
   behind the last, tilted just enough to separate. They shrink and overlap into
   the room the bubble already has, so the bubble never grows to hold them. */
.sb-chip[data-n="2"] img { width: 58%; height: 58%; }
.sb-chip[data-n="2"] img:nth-child(1) { margin-right: -22%; transform: rotate(-11deg) translateY(3%); }
.sb-chip[data-n="2"] img:nth-child(2) { transform: rotate(9deg) translateY(-3%); }
.sb-chip[data-n="3"] img { width: 48%; height: 48%; }
.sb-chip[data-n="3"] img:nth-child(1) { margin-right: -19%; transform: rotate(-16deg) translateY(5%); }
.sb-chip[data-n="3"] img:nth-child(2) { margin-right: -19%; transform: translateY(-4%); }
.sb-chip[data-n="3"] img:nth-child(3) { transform: rotate(16deg) translateY(5%); }
/* the last card drawn sits on top, the way a fanned hand reads */
.sb-chip img:nth-child(2) { z-index: 1; }
.sb-chip img:nth-child(3) { z-index: 2; }
.sb-chip b {
  position: absolute; right: -5px; bottom: -5px;
  min-width: 19px; height: 19px; padding: 0 3px; font-size: 12px;
  display: grid; place-items: center;
  border: 2px solid #fff;
  border-radius: 999px;
  background: var(--coral);
  color: #fff; font: 900 9px/1 "Fredoka", sans-serif;
  z-index: 1;
}
/* every circle wears a little tail pointing down at its tray */
/* The pin under a bubble: a small rounded point, not a sharp square. The 10px
   square rotated 45 degrees read as a map marker stuck in the table; this reads
   as a speech bubble aimed at its tray. The chips also get a little lift so
   they sit OVER the room instead of flat against it. */
.sb-chip::after, .sb-unknown::after, .sb-scan::after {
  content: "";
  position: absolute;
  left: 50%; bottom: -7px;
  width: 9px; height: 9px;
  border-radius: 0 0 2.5px 0;
  transform: translateX(-50%) rotate(45deg);
  background: var(--ink);
  z-index: -1;
}
.sb-chip, .sb-unknown, .sb-scan { box-shadow: 0 3px 0 rgba(20, 52, 60, .55), 0 6px 12px rgba(8, 24, 29, .18); }

/* A bubble on the near side of the table hangs BELOW its anchor and points UP
   at it. Sharing the northern bubbles' geometry left the southern ones sitting
   under the table with their pins aimed at the floor, which pointed at nothing
   and read as belonging to whatever was beneath them. */
.slot-bubble.south { transform: translate(-50%, 0); }
.slot-bubble.south .sb-chip::after,
.slot-bubble.south .sb-unknown::after,
.slot-bubble.south .sb-scan::after { bottom: auto; top: -9px; }

/* Dispatch juice: stars fly into the score, confetti rains, tray-complete tick. */
.score-star {
  position: fixed;
  left: 0; top: 0;
  font-size: 22px;
  line-height: 1;
  color: #f6be3e;
  text-shadow: 0 0 10px rgba(246,190,62,.85), 0 2px 4px rgba(0,0,0,.35);
  pointer-events: none;
  z-index: 200;
  will-change: transform, opacity;
}

.confetti-layer {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 19;
}
.confetti-layer i {
  position: absolute;
  top: 0;
  left: var(--x);
  width: 9px;
  height: 15px;
  background: var(--color);
  border-radius: 2px;
  opacity: 0;
}
.confetti-layer i.round { width: 12px; height: 12px; border-radius: 50%; }
.confetti-layer.celebrate i { animation: confetti-fall var(--fall) cubic-bezier(.18,.75,.36,1) var(--delay) both; }

/* Celebration badge: the circle-and-check, docked below the shift panel so
   it never covers the floor. */
/* Training Academy: one line, big, top centre, while you walk the floor
   before Ed rings. Same cream-on-ink chrome as the completion pill. */
.first-day {
  position: absolute; top: 22px; left: 50%; transform: translateX(-50%);
  z-index: 20; pointer-events: none; white-space: nowrap;
  padding: 12px 30px;
  border: 5px solid var(--ink); border-radius: 999px;
  background: var(--cream); color: var(--ink);
  font: 950 clamp(26px, 4.2vw, 44px)/1 "Fredoka", sans-serif; letter-spacing: .01em;
  box-shadow: 0 7px 0 var(--ink-deep), 0 14px 30px rgba(8,24,29,.3);
  animation: first-day-in .6s cubic-bezier(.2,.9,.3,1.3) both;
}
.first-day.hidden { display: none; }
@keyframes first-day-in { from { opacity: 0; transform: translate(-50%, -18px) scale(.9); } to { opacity: 1; transform: translateX(-50%) scale(1); } }
@media (prefers-reduced-motion: reduce) { .first-day { animation: none; } }
.completion-burst {
  position: absolute;
  top: 18px;
  right: 20px;
  display: grid;
  justify-items: center;
  gap: 9px;
  opacity: 0;
  transform-origin: top center;
  pointer-events: none;
  z-index: 20;
  text-align: center;
}
.completion-check {
  display: grid; place-items: center;
  width: 86px; height: 86px;
  border: 5px solid var(--ink);
  border-radius: 50%;
  background: var(--teal);
  box-shadow: 0 7px 0 var(--ink-deep), 0 14px 30px rgba(8,24,29,.3);
  color: var(--cream);
  font: 950 44px/1 "Fredoka", sans-serif;
}
.completion-burst strong {
  padding: 7px 16px;
  border: 4px solid var(--ink);
  border-radius: 999px;
  background: var(--cream);
  color: var(--ink);
  font: 950 18px/1 "Fredoka", sans-serif;
  letter-spacing: .01em;
  box-shadow: 0 5px 0 var(--ink-deep), 0 10px 22px rgba(8,24,29,.28);
  white-space: nowrap;
}
.completion-burst span {
  padding: 4px 11px;
  border-radius: 999px;
  background: var(--ink);
  color: #9fe0d3;
  font-size: 9.5px; font-weight: 900; letter-spacing: .15em;
  box-shadow: 0 3px 0 var(--ink-deep);
  white-space: nowrap;
}
.completion-burst.dispatch .completion-check { background: var(--gold); color: var(--ink); }
.completion-burst.show { animation: completion-burst 1.9s cubic-bezier(.2,.9,.3,1.3) both; }
@keyframes completion-burst {
  0% { opacity: 0; transform: translateY(-12px) scale(.55); }
  14% { opacity: 1; transform: translateY(0) scale(1.07); }
  26% { transform: translateY(0) scale(1); }
  80% { opacity: 1; transform: translateY(0) scale(1); }
  100% { opacity: 0; transform: translateY(-8px) scale(.92); }
}

@keyframes confetti-fall {
  0% { opacity: 0; transform: translate(-50%, -18px) rotate(0deg) scale(.7); }
  10% { opacity: 1; }
  100% { opacity: 0; transform: translate(calc(-50% + var(--drift)), 72vh) rotate(var(--spin)) scale(1); }
}

@media (max-width: 800px) {
  #hud { grid-template-columns: 1fr 155px; }
  .identity-stack { display: none; }
  .orders { justify-content: flex-start; overflow: hidden; }
  .order-card { min-width: 98px; }
}

@media (max-height: 700px) {
  .screen-card { padding: 20px 30px 24px; }
  h1 { font-size: 54px; }
  .workflow { margin: 12px 0; }
  .controls { margin: 12px 0 16px; }
}

/* Ed's call: the skip-tutorial escape hatch. One quiet button under the
   replies — pressing it asks in-dialogue, so the conversation stays the only
   thing to read. */
.sales-call-skipbar { margin-top: 12px; }
.sales-call-skipbar button {
  width: 100%;
  min-height: 40px;
  border: 2px dashed #bed0d3;
  border-radius: 10px;
  background: transparent;
  box-shadow: none;
  color: #5b7e86;
  font-size: 12px;
  font-weight: 900;
  letter-spacing: .08em;
}body:not(.keys-driving) .sales-call-skipbar button:hover {
  transform: none;
  border-style: solid;
  border-color: #18779f;
  background: #eaf4f3;
  color: #173e4a;
}

/* ---- tray inspection: the training-mode concept, cut into the game ---------
   Its own full-screen scene, so the chrome here is the concept's chrome:
   a countdown ring over the well, a clipboard that gets scribbled on, and a
   pile of what the count turned up. Nothing borrows the ward's HUD. */
.tray-inspect-modal {
  position: fixed; inset: 0; z-index: 240;   /* above the dev toolbar */
  background: #5d6f79;
  --ti-ink: #123c47; --ti-ink-deep: #0c2a33; --ti-cream: #fdf6e4;
  --ti-gold: #f2b33d; --ti-coral: #e8524a; --ti-teal: #18779f;
  --ti-hand: 'Bradley Hand', 'Chalkboard SE', 'Segoe Script', cursive;
}
.tray-inspect-modal.hidden { display: none; }

/* The ward dims behind the cut, so the scene visibly grows out of a darkened
   room instead of a hard swap between two bright pictures. */
/* The last pocket counted is the end of the job, so say so and get out. No
   waiting for the pencil — this lands the moment the ninth well is counted. */
.ti-done {
  position: absolute; z-index: 9;
  top: 50%; left: 50%;
  display: grid; justify-items: center; gap: 4px;
  padding: 18px 34px 20px;
  border: 4px solid var(--ti-ink); border-radius: 20px;
  background: var(--ti-cream);
  box-shadow: 0 8px 0 var(--ti-ink-deep), 0 22px 44px rgba(8, 24, 29, .4);
  text-align: center; pointer-events: none;
  transform: translate(-50%, -50%) scale(1);
  animation: ti-done-pop .34s cubic-bezier(.2, .9, .3, 1.6);
}
.ti-done.hidden { display: none; }
.ti-done i {
  display: grid; place-items: center;
  width: 42px; height: 42px; border-radius: 50%;
  border: 3px solid var(--ti-ink); background: #2e8b7a;
  color: #fff; font-size: 24px; font-style: normal; font-weight: 900;
}
.ti-done strong { color: var(--ti-ink); font-size: 19px; letter-spacing: .04em; }
.ti-done span { font-size: 10px; font-weight: 900; letter-spacing: .14em; color: #5b7e86; }
@keyframes ti-done-pop {
  0% { transform: translate(-50%, -50%) scale(.5); opacity: 0; }
  60% { transform: translate(-50%, -50%) scale(1.06); opacity: 1; }
}

.ti-veil {
  position: fixed; inset: 0; z-index: 239;
  background: #0c2a33;
  opacity: 0;
  transition: opacity .3s ease;
  pointer-events: none;
}
.ti-veil.on { opacity: .62; }
.ti-veil.hidden { display: none; }

/* The cut grows out of the tray's own spot on the bench and settles into frame.
   Going in takes its time and overshoots a hair, like a head dropping toward the
   work; coming out is quicker and clean, because the shift is still running. */
.tray-inspect-modal {
  transition: transform .42s cubic-bezier(.16, .84, .3, 1.06), opacity .2s ease;
}
/* the small state has to snap, not ease — otherwise the base transition
   animates INTO it and the cut reads as a wobble instead of a push-in */
.tray-inspect-modal.entering { transform: scale(.26); opacity: 0; transition: none; }
.tray-inspect-modal.leaving {
  transform: scale(.26); opacity: 0;
  transition: transform .3s cubic-bezier(.55, 0, .75, .3), opacity .3s ease-in;
}
/* the chrome fades a beat behind the scene, so the tray lands first */
.tray-inspect-modal .ti-bar,
.tray-inspect-modal .ti-needed { transition: opacity .26s ease .12s; }
.tray-inspect-modal.entering .ti-bar,
.tray-inspect-modal.entering .ti-needed,
.tray-inspect-modal.leaving .ti-bar,
.tray-inspect-modal.leaving .ti-needed { opacity: 0; transition-delay: 0s; }
.tray-inspect-modal.entering .ti-clipboard,
.tray-inspect-modal.leaving .ti-clipboard { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  .tray-inspect-modal,
  .tray-inspect-modal.entering,
  .tray-inspect-modal.leaving { transition: opacity .18s ease; transform: none; }
}
#tray-inspect-canvas {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  display: block; outline: none;
}

.ti-bar {
  position: absolute; z-index: 5;
  top: 14px; left: 50%; transform: translateX(-50%);
  display: flex; align-items: center; gap: 12px;
  padding: 8px 16px;
  border: 3px solid var(--ti-ink); border-radius: 14px;
  background: var(--ti-cream);
  box-shadow: 0 4px 0 var(--ti-ink-deep);
}
.ti-cart {
  padding: 4px 10px; border-radius: 8px;
  background: var(--ti-ink); color: var(--ti-cream);
  font-size: 11px; font-weight: 950; letter-spacing: .1em;
}
.ti-left { font-size: 26px; color: var(--ti-ink); font-variant-numeric: tabular-nums; }
.ti-title { font-size: 9px; font-weight: 900; letter-spacing: .14em; color: #5b7e86; line-height: 1.4; }
.ti-dots { display: flex; gap: 4px; }
.ti-dots s {
  width: 12px; height: 12px; border-radius: 4px;
  border: 2px solid var(--ti-ink); background: #fff; text-decoration: none;
}
.ti-dots s.open { background: #2e8b7a; }

/* the countdown ring, sitting on the pocket being counted */
.ti-ring {
  position: absolute; z-index: 7; width: 108px; height: 108px;
  transform: translate(-50%, -50%); pointer-events: none;
}
.ti-ring.hidden { display: none; }
.ti-ring svg { width: 100%; height: 100%; overflow: visible; }
.ti-ring .track { fill: rgba(12, 42, 51, .34); stroke: rgba(12, 42, 51, .5); stroke-width: 9; }
.ti-ring .fill {
  fill: none; stroke: var(--ti-gold); stroke-width: 9; stroke-linecap: round;
  /* mirrored so the arc drains anti-clockwise from twelve o'clock */
  transform: rotate(-90deg) scaleX(-1); transform-origin: 50% 50%;
  filter: drop-shadow(0 0 5px rgba(242, 179, 61, .8));
}
.ti-ring.low .fill { stroke: var(--ti-coral); filter: drop-shadow(0 0 6px rgba(232, 82, 74, .9)); }
.ti-ring b {
  position: absolute; inset: 0; display: grid; place-items: center;
  color: var(--ti-cream); font-size: 26px; font-weight: 950;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 2px 4px rgba(0, 0, 0, .5);
}
.ti-ring .cap {
  position: absolute; left: 50%; top: 100%; transform: translate(-50%, 6px);
  padding: 3px 9px; border-radius: 7px; background: rgba(12, 42, 51, .85);
  color: #ffe08a; font-size: 9px; font-weight: 900; letter-spacing: .12em; white-space: nowrap;
}

.ti-key {
  position: absolute; z-index: 6; width: 38px; height: 38px;
  transform: translate(-50%, -50%);
  display: grid; place-items: center;
  border: 3px solid var(--ti-ink); border-radius: 10px;
  background: var(--ti-gold); color: var(--ti-ink);
  font-size: 17px; font-weight: 950;
  box-shadow: 0 4px 0 var(--ti-ink-deep), 0 8px 18px rgba(8, 24, 29, .35);
  pointer-events: none;
}
.ti-key.hidden { display: none; }
@media (prefers-reduced-motion: no-preference) {
  .ti-key { animation: ti-key-bounce .9s ease-in-out infinite; }
  @keyframes ti-key-bounce { 50% { transform: translate(-50%, -62%); } }
}

/* ---- the manual log: clipboard, ruled paper, pencil ----------------------- */
.ti-clipboard {
  position: absolute; left: 26px; bottom: 26px; z-index: 8; width: 252px;
  border: 4px solid #6b5636; border-radius: 12px;
  background: #a9855a;
  box-shadow: 0 8px 0 #5d4a2e, 0 18px 34px rgba(8, 24, 29, .38);
  padding: 8px 8px 12px;
  transform: translate(-24px, 130%) rotate(-7deg);
  opacity: 0;
  transition: transform .34s cubic-bezier(.2, .9, .3, 1.25), opacity .22s ease;
  pointer-events: none;
}
.ti-clipboard.show { transform: translate(0, 0) rotate(-1.5deg); opacity: 1; }
.ti-clamp {
  width: 96px; height: 15px; margin: -16px auto 7px;
  border: 3px solid #4c4034; border-radius: 5px;
  background: linear-gradient(#cfd6d8, #9aa4a8);
}
.ti-paper {
  position: relative; height: 236px; overflow: hidden;
  border-radius: 4px;
  background:
    linear-gradient(90deg, transparent 0 26px, rgba(216, 90, 90, .35) 26px 27px, transparent 27px),
    repeating-linear-gradient(#fffdf3 0 25px, #d9e3e8 25px 26px);
  box-shadow: inset 0 2px 5px rgba(0, 0, 0, .12);
}
.ti-paper h4 {
  margin: 0; padding: 4px 12px 1px 34px;
  display: flex; justify-content: space-between;
  font-size: 9px; font-weight: 900; line-height: 15px;
  letter-spacing: .12em; color: #7b8b91;
}
.ti-paper h4 u { text-decoration: none; }
#ti-log-lines, #demo-log-lines { padding: 0 12px 0 34px; }
.ti-log-line { position: relative; height: 26px; display: flex; align-items: center; gap: 7px; }
/* the date column — semi-legible, the way a real par sheet reads */
.ti-log-line .exp {
  flex: 0 0 auto; width: 46px; text-align: right;
  font: 400 13px/1 var(--ti-hand); color: #4a6570;
  opacity: 0; transform: translateX(-5px);
  transition: opacity .14s ease, transform .18s ease;
}
.ti-log-line .exp.in { opacity: .9; transform: none; }
.ti-log-line .exp.soon { color: #9a7118; font-weight: 700; }
/* fast handwriting seen from across a room: a wavy ink stroke, not words */
.ti-log-line .scribble {
  height: 15px; width: 0; flex: 0 0 auto;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='58' height='15'%3E%3Cpath d='M0 11 q4 -8 8 -1 t7 0 q4 -7 8 -1 t7 1 q5 -8 9 -1 t8 1' fill='none' stroke='%2324404b' stroke-width='1.9' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: repeat-x;
  opacity: .82;
}
.ti-log-line .act {
  flex: 0 0 auto; width: 34px; text-align: right;
  opacity: 0; transform: scale(.6);
  font: 700 14px/1 var(--ti-hand);
  transition: opacity .16s ease, transform .2s cubic-bezier(.2, .9, .3, 1.6);
}
.ti-log-line .act.in { opacity: 1; transform: scale(1); }
.ti-log-line .act.add { color: #b5312a; }
.ti-log-line .act.ok { color: #2c7a5f; }
#ti-pencil, #demo-pencil {
  position: absolute; width: 46px; height: 46px; z-index: 9;
  transform: translate(-6px, -30px) rotate(8deg); display: none;
  pointer-events: none; filter: drop-shadow(0 3px 3px rgba(0, 0, 0, .3));
}
#ti-pencil.show, #demo-pencil.show { display: block; }
.ti-foot {
  display: flex; justify-content: space-between; align-items: center;
  padding: 7px 6px 0; font-size: 9px; font-weight: 900;
  letter-spacing: .12em; color: #f2e6cf;
}
.ti-foot b { color: #ffe08a; }

/* ---- needed items pile, bottom right -------------------------------------- */
.ti-needed {
  position: absolute; right: 22px; top: 18px; z-index: 8; width: 264px;
  border: 4px solid var(--ti-ink); border-radius: 16px; background: var(--ti-cream);
  box-shadow: 0 7px 0 var(--ti-ink-deep), 0 16px 30px rgba(8, 24, 29, .3);
  overflow: hidden;
}
.ti-needed header {
  display: flex; justify-content: space-between; align-items: center;
  padding: 9px 14px; background: var(--ti-ink); color: var(--ti-cream);
  font-size: 10.5px; font-weight: 900; letter-spacing: .12em;
}
.ti-needed header b { color: var(--ti-gold); }
.ti-needed ul {
  margin: 0; padding: 12px 14px 14px; list-style: none; min-height: 74px;
  display: flex; flex-wrap: wrap; gap: 12px; align-content: flex-start;
}
.ti-empty { font-size: 11.5px; font-weight: 700; line-height: 1.5; color: #9aa9ad; font-style: italic; }
.ti-chip {
  position: relative; width: 44px; height: 44px; border-radius: 50%;
  background: #fff; border: 4px solid var(--ti-coral);
  display: grid; place-items: center;
  box-shadow: 0 3px 0 rgba(12, 42, 51, .35);
}
.ti-chip svg { width: 26px; height: 26px; }
.ti-chip b {
  position: absolute; right: -7px; bottom: -7px;
  min-width: 19px; height: 19px; padding: 0 3px; border-radius: 999px;
  border: 2px solid #fff; background: var(--ti-coral);
  color: #fff; font-size: 11px; font-weight: 900; line-height: 16px; text-align: center;
}
.ti-chip.landed { animation: ti-chip-land .34s cubic-bezier(.2, .9, .3, 1.5); }
@keyframes ti-chip-land { 0% { transform: scale(1.5); } 60% { transform: scale(.9); } }
/* the copy in flight from the clipboard to the pile */
.ti-chip.flying {
  position: fixed; z-index: 250; margin: 0;
  transition: left .62s cubic-bezier(.35, .1, .25, 1), top .62s cubic-bezier(.5, -0.4, .3, 1);
}

/* the dev overlay lives above everything; the cut-away outranks it */
body.ti-cut-open .opdev-root { display: none !important; }

/* The shift clock is still running while you count, so it rides above the cut
   and keeps its corner. Everything else in the ward HUD stays behind. */
body.ti-cut-open #timer-panel { z-index: 250; }

/* one-line training hint inside the cut-away — tutorial cart only */
.ti-hint {
  position: absolute; z-index: 3;
  /* sits left of centre so the shift clock keeps its corner clear */
  bottom: 22px; left: 42%; transform: translateX(-50%);
  padding: 7px 14px; border-radius: 10px;
  background: rgba(12, 42, 51, .8); color: #cfe3ef;
  font-size: 12px; font-weight: 700; white-space: nowrap;
}
.ti-hint b { color: #ffe08a; }
.ti-hint.hidden { display: none; }

/* ============================================================================
   ACT ONE — the pressure, and Kurt's screen share
   ========================================================================= */

/* The room heats up as you fall behind: a red bloom creeping in from the
   edges, driven from actOne.js rather than any one event. */
#act-heat {
  position: absolute; inset: 0; z-index: 46; pointer-events: none;
  opacity: 0; transition: opacity .6s ease;
  box-shadow: inset 0 0 150px 40px rgba(232, 82, 74, .6);
}
#act-heat.on { opacity: 1; }

/* Ed runs hot, Kurt runs cold-open — the modal borrows a tint for each. */
.sales-call-modal.call-rage .sales-call-speaker { color: var(--coral); }
.sales-call-modal.call-cold .sales-call-speaker { color: var(--teal); }

/* ---- the monitor on the pharmacy workstation ---------------------------- */
.demo-modal {
  position: absolute; inset: 0; z-index: 90;
  display: grid; place-items: center;
  background: linear-gradient(180deg, #cfd9dd 0%, #bec9ce 58%, #a9b6bc 100%);
  animation: demo-in .6s ease both;
}
@keyframes demo-in { 0% { opacity: 0; } }
.demo-desk { display: flex; flex-direction: column; align-items: center; width: 100%; height: 100%; justify-content: center; }
/* The share IS the screen: the bezel is a thin frame around the whole viewport
   rather than a monitor sitting on a desk in the distance. */
.demo-monitor {
  position: relative; width: 100%; height: 100%;
  padding: clamp(7px, .8vw, 13px); border-radius: clamp(8px, 1vw, 16px);
  background: linear-gradient(180deg, #1c272c, #10181c);
  box-shadow: 0 2px 0 rgba(255,255,255,.12) inset;
}
.demo-screen { position: relative; width: 100%; height: 100%; border-radius: clamp(6px,.8vw,12px); overflow: hidden; background: #22343c; }
#demo-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; outline: none; }
.demo-glare {
  position: absolute; inset: 0; z-index: 44; pointer-events: none;
  background: linear-gradient(112deg, rgba(255,255,255,.075) 0%, rgba(255,255,255,.028) 26%, transparent 42%);
}
.demo-led { position: absolute; right: 26px; bottom: 4px; width: 7px; height: 7px; border-radius: 50%;
  background: #7ef2b0; box-shadow: 0 0 7px rgba(126,242,176,.9); }
.demo-stand, .demo-base { display: none; }

/* the split seam + lane chips */
.demo-seam { position: absolute; top: 0; bottom: 0; left: 50%; width: 6px; z-index: 14; transform: translateX(-50%);
  background: var(--ink); box-shadow: 0 0 0 2px rgba(244,240,226,.12), 0 0 18px rgba(8,24,29,.5); }
.demo-chips { position: absolute; inset: 0; z-index: 13; pointer-events: none; opacity: 0; transition: opacity .4s ease; }
.demo-chips.on { opacity: 1; }
.demo-chip { position: absolute; top: 20px; transform: translateX(-50%); padding: 7px 15px; border-radius: 999px;
  border: 3px solid var(--ink); background: var(--cream); color: var(--ink);
  font: 900 11px/1 "Avenir Next", sans-serif; letter-spacing: .12em; box-shadow: 0 4px 0 var(--ink-deep); }
.demo-chip.l { left: 17%; }
.demo-chip.r { left: 83%; color: var(--teal-deep); }

.demo-clock { position: absolute; top: 14px; left: 50%; transform: translateX(-50%); z-index: 19; display: none;
  padding: 8px 20px 9px; text-align: center; border: 3px solid var(--ink); border-radius: 14px;
  background: var(--cream); box-shadow: 0 5px 0 var(--ink-deep); }
.demo-clock.on { display: block; }
.demo-clock b { display: block; font: 800 30px/1 "Fredoka", sans-serif; color: var(--ink); }
.demo-clock.stopped b { color: var(--coral); }
.demo-clock small { display: block; margin-top: 2px; font: 900 8.5px/1 "Avenir Next", sans-serif; letter-spacing: .16em; color: #8aa2a9; }

.demo-ring { position: absolute; width: 110px; height: 110px; transform: translateX(-50%); z-index: 12; display: none; pointer-events: none; }
.demo-ring svg { width: 100%; height: 100%; overflow: visible; }
.demo-ring .track { fill: rgba(12,42,51,.35); stroke: rgba(12,42,51,.55); stroke-width: 9; }
.demo-ring .fill { fill: none; stroke: var(--gold); stroke-width: 9; stroke-linecap: round;
  filter: drop-shadow(0 0 7px rgba(242,179,61,.85)); }

.demo-winner { position: absolute; right: 4%; top: 20%; width: 290px; z-index: 19; display: none; text-align: center;
  padding: 12px 18px 14px; border: 4px solid var(--ink); border-radius: 16px; background: var(--teal);
  box-shadow: 0 6px 0 #1c5a4e, 0 14px 28px rgba(8,24,29,.4); animation: win-pop .42s cubic-bezier(.2,.9,.3,1.7); }
.demo-winner.on { display: block; }
@keyframes win-pop { 0% { transform: scale(.3); opacity: 0; } 60% { transform: scale(1.12); } }
.demo-winner i { display: grid; place-items: center; width: 36px; height: 36px; margin: 0 auto 5px;
  border: 3px solid #fff; border-radius: 50%; background: rgba(255,255,255,.18); color: #fff; font-style: normal; font: 900 19px/1 sans-serif; }
.demo-winner b { display: block; font: 800 24px/1 "Fredoka", sans-serif; color: #fff; }
.demo-winner small { display: block; margin-top: 3px; font: 900 9.5px/1 "Avenir Next", sans-serif; letter-spacing: .1em; color: #bdf0e2; }

/* READY / SET / GO sat cream-on-cream against the pharmacy floor and washed
   out. They now carry a heavy ink outline, a hard drop shadow and a soft dark
   pool behind them, so they read against any part of either lane. */
.demo-count {
  position: absolute; inset: 0; z-index: 22; display: grid; place-items: center;
  pointer-events: none; opacity: 0;
}
.demo-count span, .demo-count { font: 800 clamp(80px, 15vw, 210px)/1 "Fredoka", sans-serif; }
.demo-count {
  color: var(--cream);
  -webkit-text-stroke: clamp(7px, 1.2vw, 16px) var(--ink);
  paint-order: stroke fill;
  /* a hard ink ring in eight directions, then the drop, then a dark pool —
     the ring is what actually separates it from a pale pharmacy floor */
  text-shadow:
    -3px -3px 0 var(--ink), 3px -3px 0 var(--ink),
    -3px 3px 0 var(--ink), 3px 3px 0 var(--ink),
    0 -4px 0 var(--ink), 0 4px 0 var(--ink),
    -4px 0 0 var(--ink), 4px 0 0 var(--ink),
    0 clamp(8px, 1.1vw, 16px) 0 var(--ink-deep),
    0 0 clamp(40px, 5vw, 80px) rgba(8, 24, 29, .95),
    0 0 clamp(80px, 10vw, 150px) rgba(8, 24, 29, .75);
  letter-spacing: .02em;
}
/* GO reads hottest of the three */
.demo-count.go { text-shadow:
    -3px -3px 0 var(--ink), 3px -3px 0 var(--ink),
    -3px 3px 0 var(--ink), 3px 3px 0 var(--ink),
    0 -4px 0 var(--ink), 0 4px 0 var(--ink),
    -4px 0 0 var(--ink), 4px 0 0 var(--ink),
    0 clamp(8px, 1.1vw, 16px) 0 #8a5f10,
    0 0 clamp(46px, 6vw, 96px) rgba(242, 179, 61, .55),
    0 0 clamp(90px, 11vw, 170px) rgba(8, 24, 29, .8); }
.demo-count.on { opacity: 1; animation: count-pop .68s cubic-bezier(.2,.9,.3,1.4); }
.demo-count.go { color: var(--gold); }
@keyframes count-pop { 0% { transform: scale(2.4); opacity: 0; } 34% { transform: scale(1); opacity: 1; } }

.demo-confetti { position: absolute; inset: 0; z-index: 30; pointer-events: none; overflow: hidden; }
.demo-confetti i {
  position: absolute; border-radius: 2px;
  /* each piece carries its own drift, spin and starting tilt (set inline), so
     the fall flutters instead of dropping in a flat sheet */
  animation: demo-fall cubic-bezier(.3, .1, .55, 1) forwards;
  transform: rotate(var(--tilt, 0deg));
}
@keyframes demo-fall {
  0% { transform: translate3d(0, 0, 0) rotate(var(--tilt, 0deg)); opacity: 1; }
  55% { opacity: 1; }
  100% {
    transform: translate3d(var(--drift, 0), 105vh, 0) rotate(calc(var(--tilt, 0deg) + var(--spin, 720deg)));
    opacity: 0;
  }
}

.demo-blur { position: absolute; inset: 0; z-index: 25; display: none; background: rgba(12,42,51,.62); }
.demo-blur.on { display: block; backdrop-filter: blur(6px) saturate(.7); -webkit-backdrop-filter: blur(6px) saturate(.7);
  animation: veil-in .55s ease; }
@keyframes veil-in { 0% { opacity: 0; } }

/* results sheet + study cards + end card all share the staged reveal */
.demo-results, .demo-card, .demo-end { position: absolute; inset: 0; z-index: 27; display: none; place-items: center;
  text-align: center; padding: 4vh 4vw; }
.demo-results.on, .demo-card.on, .demo-end.on { display: grid; animation: veil-in .5s ease; }
.demo-card.on { background: var(--ink); }
.demo-end.on { background: var(--ink); }
.step { opacity: 0; transform: translateY(18px); }
.step.in { opacity: 1; transform: none; transition: opacity .38s ease, transform .38s cubic-bezier(.16,.84,.3,1); }

.demo-results .sheet { width: min(560px, 92vw); padding: 26px 28px 20px; border: 4px solid var(--ink);
  border-radius: 20px; background: var(--cream); box-shadow: 0 8px 0 var(--ink-deep), 0 22px 44px rgba(0,0,0,.4); }
.demo-results h4 { margin: 0 0 16px; font: 800 30px/1 "Fredoka", sans-serif; color: var(--ink); letter-spacing: .02em; }
.demo-results .row { display: flex; align-items: center; gap: 14px; padding: 13px 16px; margin-bottom: 9px;
  border: 3px solid var(--ink); border-radius: 13px; background: #fff; }
.demo-results .row.win { background: #eafaf4; border-color: var(--teal-deep); }
.demo-results .pos { font: 800 22px/1 "Fredoka", sans-serif; color: #9bb0b6; }
.demo-results .row.win .pos { color: var(--teal-deep); }
.demo-results .who { flex: 1; text-align: left; font: 900 12px/1 "Avenir Next", sans-serif; letter-spacing: .12em; color: var(--ink); }
.demo-results .row b { font: 800 30px/1 "Fredoka", sans-serif; color: var(--ink); }
.demo-results .row.win b { color: var(--teal-deep); }
.demo-results p { margin: 14px 0 0; font: 700 15px/1.5 "Avenir Next", sans-serif; color: var(--ink); }
.demo-results p b { color: var(--coral); }

.demo-card .inner, .demo-end .inner { width: min(880px, 94vw); }
.demo-card .kicker, .demo-end .kicker { display: block; margin-bottom: 2.2vh;
  font: 900 clamp(10px,1.35vw,15px)/1.4 "Avenir Next", sans-serif; letter-spacing: .22em; color: #7ed4b2; }
.demo-card .hero { font: 800 clamp(46px,10vw,124px)/.92 "Fredoka", sans-serif; color: var(--cream); text-shadow: 0 6px 0 rgba(0,0,0,.28); }
.demo-card .hero em {
  display: block; font-style: normal; color: var(--gold);
  margin-top: 1.4vh;
  font-size: clamp(20px, 3.4vw, 46px); line-height: 1.08;
  max-width: 18ch; margin-left: auto; margin-right: auto;
}
.demo-card .hero small { display: block; margin-top: 1.2vh; font: 800 clamp(19px,3.9vw,48px)/1 "Fredoka", sans-serif; color: #7ef2b0; }
.demo-card .sub { margin: 2.4vh auto 0; max-width: 30ch; font: 800 clamp(15px,2vw,25px)/1.4 "Avenir Next", sans-serif; color: #dff0fa; }
.demo-card .sub .line { display: block; }
.demo-card .sub b { color: #fff; }
.demo-card .sub b.good { color: #7ef2b0; }
.demo-card .cite { margin: 4vh auto 0; max-width: 62ch; padding-top: 1.6vh; border-top: 2px solid rgba(255,255,255,.18);
  font: 600 clamp(9px,1.02vw,12px)/1.6 "Avenir Next", sans-serif; color: rgba(223,240,250,.62); }
.demo-card .cite em { font-style: italic; }

.demo-end b { display: block; font: 800 clamp(40px,8vw,96px)/1 "Fredoka", sans-serif; color: var(--gold); }
.demo-end small { display: block; margin-top: 2.4vh; font: 700 clamp(14px,1.8vw,20px)/1.5 "Avenir Next", sans-serif; color: #cfe3e6; }

/* the bar stops short of Kurt's tile rather than running under it */
/* above the title slide: he is talking over his own deck, so his words have
   to be readable while it is up */
.demo-say { position: absolute; left: 26px; bottom: 26px; z-index: 26;
  right: calc(clamp(150px, 15vw, 232px) + 48px); max-width: 760px;
  padding: 12px 18px 14px; border: 3px solid var(--ink); border-radius: 16px; background: var(--cream);
  box-shadow: 0 6px 0 var(--ink-deep), 0 16px 30px rgba(0,0,0,.35); }
.demo-say small { display: block; font: 900 9px/1 "Avenir Next", sans-serif; letter-spacing: .16em; color: var(--teal-deep); margin-bottom: 5px; }
.demo-say p { margin: 0; font: 700 15px/1.45 "Avenir Next", sans-serif; color: var(--ink); min-height: 22px; }
.demo-say .cue { display: none; }
.demo-say.has-cue .cue { display: block; margin-top: 8px; text-align: right;
  font: 900 10px/1 "Avenir Next", sans-serif; letter-spacing: .12em; color: #7a8d95; }
.demo-say .cue b { display: inline-grid; place-items: center; min-width: 19px; height: 19px; padding: 0 5px; margin-right: 5px;
  border-radius: 5px; background: var(--gold); border: 2px solid var(--ink); color: var(--ink); }

/* ---- the night between: fade to black, a time card, then the call ------- */
.act-cut {
  position: absolute; inset: 0; z-index: 95;
  display: grid; place-items: center;
  background: #05121a;
  opacity: 0; pointer-events: none;
  transition: opacity .9s ease;
}
.act-cut.fading { opacity: 1; pointer-events: auto; }
.act-cut.hidden { display: none; }
.act-cut-card { text-align: center; opacity: 0; transform: translateY(14px); }
.act-cut.showing .act-cut-card {
  opacity: 1; transform: none;
  transition: opacity .7s ease, transform .7s cubic-bezier(.16,.84,.3,1);
}
.act-cut.leaving .act-cut-card { opacity: 0; transition: opacity .5s ease; }
.act-cut-card span {
  display: block; margin-bottom: 14px;
  font: 900 clamp(10px,1.3vw,14px)/1 "Avenir Next", sans-serif;
  letter-spacing: .38em; color: #4fb3a5;
}
.act-cut-card b {
  display: block;
  font: 800 clamp(52px,9vw,120px)/1 "Fredoka", sans-serif;
  color: #fdf6e4; letter-spacing: .01em;
}
.act-cut-card small {
  display: block; margin-top: 18px;
  font: 700 clamp(13px,1.7vw,19px)/1 "Avenir Next", sans-serif;
  color: rgba(253,246,228,.6);
}

/* ---- Kurt's video tile: bottom-right, over his own screen share --------- */
/* above the title slide and the veil: on a real call his tile never
   disappears behind the deck being shared */
.demo-pip {
  position: absolute; right: 22px; bottom: 22px; z-index: 28;
  width: clamp(150px, 15vw, 232px);
  border: 3px solid var(--ink); border-radius: 13px; overflow: hidden;
  background: #0c2a33;
  box-shadow: 0 6px 0 var(--ink-deep), 0 16px 30px rgba(0,0,0,.42);
  /* No fill mode: the entrance is a flourish, not a gate. With `both` the tile
     held its 0%-opacity frame whenever the animation could not run — a
     backgrounded tab meant Kurt was simply absent. It now fails visible. */
  opacity: 1;
  animation: pip-in .5s cubic-bezier(.2,.9,.3,1.4);
}
/* transform only — never opacity. A running animation applies its first
   keyframe even with fill:none, so animating opacity from 0 meant any stalled
   or throttled timeline left Kurt invisible. He must always be on screen. */
@keyframes pip-in { 0% { transform: translateY(20px) scale(.86); } }
.demo-pip canvas { display: block; width: 100%; aspect-ratio: 4 / 3; outline: none; }
.demo-pip footer {
  display: flex; align-items: center; justify-content: space-between;
  padding: 6px 9px; background: var(--ink);
  font: 900 8px/1 "Avenir Next", sans-serif; letter-spacing: .1em; color: var(--cream);
}
.demo-pip footer i {
  display: flex; align-items: center; gap: 4px; font-style: normal; color: #9fb6bc;
}
.demo-pip footer i::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: var(--coral); box-shadow: 0 0 6px var(--coral);
}
/* Kurt stays on screen for the whole call, infographics included — he is
   talking over them. The cards keep clear of his corner instead. */
.demo-card .inner, .demo-end .inner { padding-bottom: clamp(90px, 12vh, 150px); }

/* ---- the deck Kurt opens on -------------------------------------------- */
.demo-title {
  position: absolute; inset: 0; z-index: 24; display: none; place-items: center;
  background: linear-gradient(160deg, #12333d 0%, #0d252d 62%, #0a1f26 100%);
}
.demo-title.on { display: grid; }
.demo-title .inner { text-align: center; opacity: 0; transform: translateY(16px); }
.demo-title.showing .inner {
  opacity: 1; transform: none;
  transition: opacity .8s ease, transform .8s cubic-bezier(.16,.84,.3,1);
}
.demo-title .lockup { display: flex; align-items: center; justify-content: center; gap: clamp(14px, 1.8vw, 26px); }
.demo-title .cube {
  position: relative; display: block;
  width: clamp(46px, 5.4vw, 78px); height: clamp(46px, 5.4vw, 78px);
}
/* the same three-faced cube the door badge wears */
.demo-title .cube i { position: absolute; inset: 0; }
.demo-title .cube i:nth-child(1) { background: #48b3a1; clip-path: polygon(50% 0, 100% 25%, 50% 50%, 0 25%); }
.demo-title .cube i:nth-child(2) { background: #2e9184; clip-path: polygon(0 25%, 50% 50%, 50% 100%, 0 75%); }
.demo-title .cube i:nth-child(3) { background: #1f7568; clip-path: polygon(100% 25%, 100% 75%, 50% 100%, 50% 50%); }
.demo-title b {
  font: 400 clamp(44px, 7vw, 96px)/1 "Fredoka", sans-serif;
  color: #eaf4f2; letter-spacing: -.01em;
}
.demo-title b em { font-style: normal; font-weight: 800; color: var(--teal); }
.demo-title .rule {
  display: block; width: clamp(180px, 26vw, 380px); height: 4px; margin: clamp(20px, 2.6vh, 30px) auto 0;
  background: var(--teal); border-radius: 2px;
}
.demo-title small {
  display: block; margin-top: clamp(14px, 1.8vh, 22px);
  font: 900 clamp(9px, 1.1vw, 13px)/1 "Avenir Next", sans-serif;
  letter-spacing: .34em; color: rgba(234,244,242,.55);
}
.demo-title.leaving { opacity: 0; transition: opacity .6s ease; }

/* the title entrance is decoration: honour a reduced-motion preference */
@media (prefers-reduced-motion: reduce) {
  .game-entry::before, .entry-logo-lockup, .entry-wordmark,
  .entry-presents, .press-any-button { animation: none !important; }
  .press-any-button { animation: press-any-pulse 1.1s ease-in-out infinite alternate !important; }
}

/* ---- sound toggle on the title screen ---------------------------------- */
/* pinned to the screen corner, not the hero: at narrow widths it used to sit
   on top of PRESS ANY BUTTON */
.entry-sound {
  position: fixed; right: clamp(14px, 2.4vw, 30px); bottom: clamp(14px, 2.4vw, 30px);
  z-index: 3;
  display: flex; align-items: center; gap: 9px;
  padding: 9px 16px 9px 13px;
  border: 2px solid rgba(255, 246, 229, .34);
  border-radius: 999px;
  background: rgba(255, 246, 229, .07);
  color: #fff6e5;
  font: 950 11px/1 "Avenir Next", sans-serif; letter-spacing: .14em;
  box-shadow: none;
  animation: entry-button .7s cubic-bezier(.16,.84,.3,1.2) 2.35s both;
}body:not(.keys-driving) .entry-sound:hover { background: rgba(255, 246, 229, .16); transform: none; box-shadow: none; }
/* a speaker drawn from two boxes, with waves that hide when it is off */
.entry-sound-icon {
  position: relative; width: 15px; height: 14px; flex: none;
}
.entry-sound-icon::before {
  content: ""; position: absolute; left: 0; top: 4px;
  width: 5px; height: 6px; background: currentColor;
}
.entry-sound-icon::after {
  content: ""; position: absolute; left: 4px; top: 0;
  width: 0; height: 0; border: 7px solid transparent;
  border-right: 6px solid currentColor; border-left: 0;
}
.entry-sound .waves {
  position: absolute; right: -5px; top: 2px; width: 7px; height: 10px;
  border-right: 2px solid currentColor; border-radius: 0 8px 8px 0;
  opacity: .9;
}
.entry-sound.muted { color: rgba(255, 246, 229, .5); border-color: rgba(255, 246, 229, .2); }
.entry-sound.muted .waves { opacity: 0; }
/* a slash across the speaker when it is off */
.entry-sound.muted .entry-sound-icon::before,
.entry-sound.muted .entry-sound-icon::after { opacity: .55; }
.entry-sound.muted .entry-sound-icon { position: relative; }
.entry-sound.muted .entry-sound-icon .slash {
  position: absolute; left: -2px; top: 6px; width: 20px; height: 2px;
  background: currentColor; transform: rotate(-28deg);
}
@media (prefers-reduced-motion: reduce) { .entry-sound { animation: none !important; } }

/* ---- the manual par log, ported from the approved concept -------------- */
/* ---- the manual log: clipboard, ruled paper, pencil ----------------------- */
.ti-clipboard {
  position: absolute; left: 26px; bottom: 26px; z-index: 8; width: 252px;
  border: 4px solid #6b5636; border-radius: 12px;
  background: #a9855a;
  box-shadow: 0 8px 0 #5d4a2e, 0 18px 34px rgba(8, 24, 29, .38);
  padding: 8px 8px 12px;
  transform: translate(-24px, 130%) rotate(-7deg);
  opacity: 0;
  transition: transform .34s cubic-bezier(.2, .9, .3, 1.25), opacity .22s ease;
  pointer-events: none;
}
.ti-clipboard.show { transform: translate(0, 0) rotate(-1.5deg); opacity: 1; }
.ti-clamp {
  width: 96px; height: 15px; margin: -16px auto 7px;
  border: 3px solid #4c4034; border-radius: 5px;
  background: linear-gradient(#cfd6d8, #9aa4a8);
}
.ti-paper {
  position: relative; height: 236px; overflow: hidden;
  border-radius: 4px;
  background:
    linear-gradient(90deg, transparent 0 26px, rgba(216, 90, 90, .35) 26px 27px, transparent 27px),
    repeating-linear-gradient(#fffdf3 0 25px, #d9e3e8 25px 26px);
  box-shadow: inset 0 2px 5px rgba(0, 0, 0, .12);
}
.ti-paper h4 {
  margin: 0; padding: 4px 12px 1px 34px;
  display: flex; justify-content: space-between;
  font-size: 9px; font-weight: 900; line-height: 15px;
  letter-spacing: .12em; color: #7b8b91;
}
.ti-paper h4 u { text-decoration: none; }
#ti-log-lines, #demo-log-lines { padding: 0 12px 0 34px; }
.ti-log-line { position: relative; height: 26px; display: flex; align-items: center; gap: 7px; }
/* the date column — semi-legible, the way a real par sheet reads */
.ti-log-line .exp {
  flex: 0 0 auto; width: 46px; text-align: right;
  font: 400 13px/1 'Bradley Hand', 'Chalkboard SE', 'Segoe Script', cursive; color: #4a6570;
  opacity: 0; transform: translateX(-5px);
  transition: opacity .14s ease, transform .18s ease;
}
.ti-log-line .exp.in { opacity: .9; transform: none; }
.ti-log-line .exp.soon { color: #9a7118; font-weight: 700; }
/* fast handwriting seen from across a room: a wavy ink stroke, not words */
.ti-log-line .scribble {
  height: 15px; width: 0; flex: 0 0 auto;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='58' height='15'%3E%3Cpath d='M0 11 q4 -8 8 -1 t7 0 q4 -7 8 -1 t7 1 q5 -8 9 -1 t8 1' fill='none' stroke='%2324404b' stroke-width='1.9' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: repeat-x;
  opacity: .82;
}
.ti-log-line .act {
  flex: 0 0 auto; width: 34px; text-align: right;
  opacity: 0; transform: scale(.6);
  font: 700 14px/1 'Bradley Hand', 'Chalkboard SE', 'Segoe Script', cursive;
  transition: opacity .16s ease, transform .2s cubic-bezier(.2, .9, .3, 1.6);
}
.ti-log-line .act.in { opacity: 1; transform: scale(1); }
.ti-log-line .act.add { color: #b5312a; }
.ti-log-line .act.ok { color: #2c7a5f; }
#ti-pencil, #demo-pencil {
  position: absolute; width: 46px; height: 46px; z-index: 9;
  transform: translate(-6px, -30px) rotate(8deg); display: none;
  pointer-events: none; filter: drop-shadow(0 3px 3px rgba(0, 0, 0, .3));
}
#ti-pencil.show, #demo-pencil.show { display: block; }
.ti-foot {
  display: flex; justify-content: space-between; align-items: center;
  padding: 7px 6px 0; font-size: 9px; font-weight: 900;
  letter-spacing: .12em; color: #f2e6cf;
}
.ti-foot b { color: #ffe08a; }
#demo-clipboard { z-index: 15; left: 24px; bottom: 18px; width: 246px; padding: 8px 8px 10px; }
#demo-clipboard .ti-paper { height: 176px; }
#demo-clipboard .ti-foot { padding: 7px 4px 0; font-size: 8px; letter-spacing: .08em; white-space: nowrap; }
#demo-clipboard .ti-paper h4 { padding: 4px 10px 1px 30px; font-size: 8.5px; }
#demo-log-lines { padding: 0 10px 0 30px; }
/* the line-four reveal: the clipboard comes to centre stage */
  #demo-clipboard.reveal {
    left: 50%; bottom: 34%; width: 280px;
    transform: translateX(-50%) rotate(-1.5deg) scale(1.25) !important;
  }
.ti-log-line .ln { flex: 0 0 14px; font: 900 9px/1 var(--ui); color: #b5c2c7; }
.ti-log-line .act.pull { color: #8a2621; font-size: 10px; letter-spacing: .04em; }
.ti-log-line.sel { background: rgba(242, 179, 61, .28); border-radius: 6px; outline: 2px solid var(--gold); }
#demo-clipboard.reveal .ti-paper { height: 258px; }
.ti-log-line.busted {
    background: rgba(232, 82, 74, .16); border-radius: 6px;
    outline: 2px solid var(--coral);
  }
#today-stamp {
    position: absolute; right: 6px; top: 44%; z-index: 4;
    padding: 5px 9px; border: 3px solid var(--coral); border-radius: 8px;
    color: var(--coral); background: rgba(255, 253, 243, .92);
    font: 900 12px/1 var(--ui); letter-spacing: .06em;
    transform: rotate(-9deg) scale(.4); opacity: 0;
    transition: transform .25s cubic-bezier(.2, .9, .3, 1.6), opacity .15s ease;
  }
#today-stamp.on { transform: rotate(-9deg) scale(1); opacity: 1; }

/* ============================================================================
   ACT TWO — the recall, on a hospital blueprint
   ========================================================================= */
.demo-blueprint {
  position: absolute; inset: 0; z-index: 26; display: none;
  grid-template-rows: auto 1fr auto;
  /* The readout is the third grid row, so it needs no runway underneath it.
     The old 210px bottom padding was dead space that shoved the plan upward. */
  padding: clamp(26px, 4.4vh, 62px) clamp(20px, 3vw, 46px) clamp(18px, 3vh, 40px);
  background: linear-gradient(165deg, #dfe3dd, #cfd6d2 70%);
}
.demo-blueprint.on { display: grid; animation: veil-in .6s ease; }
.bp-head { text-align: center; margin-bottom: clamp(12px, 2.4vh, 30px); }
.bp-kicker {
  display: block; font: 900 clamp(9px, 1.05vw, 12px)/1 "Avenir Next", sans-serif;
  letter-spacing: .26em; color: #b3382f; margin-bottom: clamp(9px, 1.4vh, 16px);
}
.bp-head h4 {
  margin: 0; font: 800 clamp(20px, 2.6vw, 34px)/1 "Fredoka", sans-serif;
  color: #16242b; letter-spacing: .01em;
}
.bp-stage { display: grid; place-items: center; min-height: 0; }
#bp-plan { width: 100%; height: 100%; max-height: 100%; }

/* Construction-document look: solid poché walls on a white sheet. Walls read
   as mass because the envelope is filled and the rooms are cut out of it. */
.bp-sheet { fill: #f6f4ee; }
.bp-poche { fill: #1d2b33; }
.bp-room { fill: #ffffff; }
.bp-room-target { fill: #eaf6f2; }
.bp-corr { fill: #eceae2; }
.bp-core { fill: #dfe4e2; }
.bp-fix { fill: none; stroke: #9aa8af; stroke-width: 1.3; }
.bp-tag { fill: #1d2b33; font: 900 9px "Avenir Next", sans-serif; letter-spacing: .1em; }
.bp-tag-target { fill: #1d6a5c; }
.bp-num { fill: #6a7a82; font: 700 7.5px "Avenir Next", sans-serif; letter-spacing: .06em; }
.bp-dim { stroke: #8b9aa2; stroke-width: .9; }
.bp-dimtxt { fill: #6a7a82; font: 700 7px "Avenir Next", sans-serif; letter-spacing: .08em; }
.bp-title-txt { fill: #1d2b33; font: 900 12px "Avenir Next", sans-serif; letter-spacing: .2em; }

/* the carts: drawn from the side, no rings and nothing pulsing */
.bp-cart .cbody { fill: #8fa3aa; stroke: #101c22; stroke-width: 1.6; transition: fill .4s ease; }
.bp-cart .crail { stroke: #101c22; stroke-width: 1.2; }
.bp-cart .cwheel { fill: none; stroke: #101c22; stroke-width: 1.5; }
.bp-cart.pulled .cbody { fill: #e8524a; }
.bp-cart.flagged .cbody { fill: #e8524a; }
/* The alarm beat: carts hold station and flash before they move, so the recall
   reads as an order going out rather than furniture sliding about. Fill only —
   the <g> transform is driven from script and a CSS transform would fight it,
   and rings were ruled out for this plan. */
.bp-cart.alarm .cbody { animation: bp-alarm .58s ease-in-out infinite; }
.bp-cart.alarm .crail, .bp-cart.alarm .cwheel { stroke: #6f1712; }
/* Deep red to bright red — never toward white. A pulse that passes through a
   pale tint reads as washed out on a light sheet instead of as an alarm. */
@keyframes bp-alarm {
  0%, 100% { fill: #b8281f; }
  50% { fill: #ff6f63; }
}
.bp-cart.cleared { opacity: .3; }
.bp-cart.cleared .cbody { fill: #b8c4c8; }

.bp-readout {
  display: flex; justify-content: center; gap: clamp(14px, 2.4vw, 36px);
  margin-top: clamp(10px, 1.6vh, 20px);
}
.bp-stat {
  min-width: clamp(120px, 13vw, 190px); padding: 11px 16px 12px; text-align: center;
  border: 3px solid var(--ink); border-radius: 14px; background: var(--cream);
  box-shadow: 0 5px 0 var(--ink-deep);
  transition: background .4s ease, color .4s ease;
}
.bp-stat b { display: block; font: 800 clamp(26px, 3.4vw, 46px)/1 "Fredoka", sans-serif; color: var(--ink); }
.bp-stat small {
  display: block; margin-top: 4px; font: 900 8.5px/1 "Avenir Next", sans-serif;
  letter-spacing: .17em; color: #7a8d95;
}
.bp-stat.hot { background: var(--coral); }
.bp-stat.hot b { color: #fff; }
.bp-stat.hot small { color: #ffd9d6; }
.bp-stat.wins { background: var(--teal); }
.bp-stat.wins b { color: #fff; }
.bp-stat.wins small { color: #d3f4ea; }
.bp-stat.hidden { display: none; }

/* Kurt is hidden for the capture take, since the take records the scene clean
   and finishes with him alone on key green. */
body.cap-no-kurt #demo-pip { visibility: hidden; }

/* ---- capture take -------------------------------------------------------
   One continuous run for screen recording: a countdown, the acts with Kurt
   hidden, then Kurt alone on a flat field that keys out cleanly. */
.take-count {
  position: fixed; inset: 0; z-index: 300; display: none;
  place-items: center; align-content: center;
  background: #0b1f27; text-align: center;
}
.take-count.on { display: grid; }
.take-count b {
  display: block; font: 800 clamp(120px, 22vw, 300px)/1 "Fredoka", sans-serif;
  color: var(--cream); -webkit-text-stroke: clamp(5px, .9vw, 12px) var(--ink);
  paint-order: stroke fill;
}
.take-count small {
  display: block; margin-top: 3vh; font: 900 clamp(10px, 1.3vw, 15px)/1 "Avenir Next", sans-serif;
  letter-spacing: .34em; color: #7ed4b2;
}

/* Kurt's isolated segment: flat key green, nothing else in frame */
.take-kurt {
  position: fixed; inset: 0; z-index: 300; display: none;
  place-items: center; background: #00b140;   /* broadcast key green */
}
.take-kurt.on { display: grid; }
.take-kurt canvas {
  /* an explicit ratio, not height:auto — a canvas with auto height keeps its
     300x150 default and the engine has nothing to size the backing store to */
  /* 4:3 tile sized off the SHORT edge, so it fills the frame on a wide
     screen instead of leaving a band of key colour top and bottom */
  width: min(115vh, 88vw); aspect-ratio: 4 / 3; height: auto; display: block;
  /* the call tile's own frame, scaled up: same border, radius and drop as the
     corner PiP, so the segment cuts against the demo without re-styling */
  border: 6px solid var(--ink); border-radius: 22px;
  box-shadow: 0 10px 0 var(--ink-deep), 0 26px 54px rgba(0, 0, 0, .42);
}
.take-lab {
  position: absolute; left: 50%; bottom: 3vh; transform: translateX(-50%);
  font: 900 11px/1 "Avenir Next", sans-serif; letter-spacing: .28em; color: rgba(0,0,0,.45);
}
/* ---- capture take: the par log on its own ---------------------------------
   The same argument the race makes, held still: nine pockets counted by hand,
   two of them already out of date and both waved through with a tick. Every
   size is in `em` off the board's own font-size, so the whole sheet scales
   with the viewport as one piece. */
.take-clip {
  position: fixed; inset: 0; z-index: 300; display: none;
  place-items: center; background: #00b140;   /* broadcast key green */
}
.take-clip.on { display: grid; }
.tc-board {
  /* One knob drives the whole sheet. It has to answer to BOTH axes: sized off
     height alone the board runs off the sides of a narrow frame. */
  position: relative; font-size: clamp(11px, min(3.1vh, 2.8vw), 34px);
  width: 30em; padding: .8em .8em 1em;
  border: .26em solid #6b5636; border-radius: .8em;
  background: #a9855a;
  box-shadow: 0 .5em 0 #5d4a2e, 0 1.2em 2.4em rgba(8, 24, 29, .42);
  transform: rotate(-1.1deg);
}
.tc-clamp {
  width: 8em; height: 1.15em; margin: -1.5em auto .55em;
  border: .2em solid #4a5c62; border-radius: .3em;
  background: linear-gradient(#eef3f4, #c3ced1);
}
.tc-paper {
  position: relative; background: #fffdf3; border-radius: .35em;
  padding: .85em 1em .9em 2.6em; min-height: 24em; overflow: hidden;
}
/* the margin rule every ruled pad has */
.tc-paper::before {
  content: ""; position: absolute; left: 1.9em; top: 0; bottom: 0;
  width: .1em; background: rgba(232, 82, 74, .5);
}
.tc-paper h4 {
  display: flex; align-items: baseline; gap: .8em; margin: 0 0 .55em;
  padding-bottom: .45em; border-bottom: .14em solid #cbd5d8;
  font: 900 1.05em/1 var(--ui); letter-spacing: .1em; color: #123c47;
}
.tc-paper h4 span { flex: 1 1 auto; }
.tc-paper h4 em {
  flex: 0 0 3.1em; font-style: normal; text-align: right;
  font-size: .72em; letter-spacing: .12em; color: #7d8f95;
}
.tc-line {
  position: relative; height: 2.25em; display: flex; align-items: center; gap: .7em;
  border-bottom: 1px dashed #e2e8e5;
}
.tc-line .ln { flex: 0 0 1.5em; font: 900 .82em/1 var(--ui); color: #a4b4b9; }
/* The sheet is already filled in when the shot opens: the count has been done,
   and the only thing that changes is what it turns out to have missed. */
.tc-line .nm {
  flex: 1 1 auto; min-width: 0; overflow: hidden; white-space: nowrap;
  font: 700 .92em/1 var(--ui); color: #2b3f47;
  transition: color .3s ease;
}
.tc-line .exp {
  flex: 0 0 4.3em; text-align: right;
  font: 800 .92em/1 var(--ui); color: #3b4f56;
  transition: color .3s ease;
}
.tc-line .act {
  flex: 0 0 3.1em; text-align: right;
  font: 900 1.02em/1 var(--ui); color: #2c7a5f;
  transition: color .3s ease;
}
.tc-line .act.add { color: #b5312a; }

/* the reveal: these two were already out of date and got a tick anyway */
.tc-line.bust {
  background: rgba(232, 82, 74, .17); border-radius: .35em;
  outline: .15em solid #e8524a; outline-offset: .1em;
  transition: background .3s ease;
  /* transform only, and the resting frame is the visible one — a stalled
     timeline must still show the rows flagged */
  animation: tc-pulse 1.6s ease-in-out infinite;
}
@keyframes tc-pulse { 0%, 100% { transform: none; } 50% { transform: scale(1.03); } }
.tc-line.bust .nm { color: #8a2621; font-weight: 900; }
.tc-line.bust .exp { color: #b5312a; font-weight: 900; }
.tc-line.bust .act { color: #b5312a; font-size: .74em; letter-spacing: .06em; }

.tc-foot {
  display: flex; align-items: center; justify-content: space-between;
  padding: .6em .3em 0;
  font: 900 .76em/1 var(--ui); letter-spacing: .12em; color: #f2e6cf;
}
.tc-foot b { color: #ffe08a; }
.tc-foot b.bad { color: #ffb3ad; }

/* The take hides everything the recording should not contain. Kurt's dialogue
   and the state labels are added back in the edit, so nothing he says is
   burned into the footage. */
body.take-running .opdev-root { display: none !important; }
/* Kurt's take can be fired from the title screen, so the title screen has to
   get out of the way rather than sit on top of him. */
body.take-running #game-entry { display: none !important; }
body.take-running #demo-say { display: none !important; }
body.take-running .take-lab { display: none !important; }
body.take-running #skiphint { display: none !important; }

/* ============================================================================
   THE NINE O'CLOCK CALL — the walkthrough film
   ========================================================================= */
/* It sits above the pharmacy and below the capture layers. The time card fades
   out underneath it, so both are on screen together for the length of the
   crossfade and the cut has no black frame in it. */
.walkthrough {
  position: fixed; inset: 0; z-index: 120;
  display: grid; place-items: center;
  /* the user's own desk at nine in the morning: wall above, desktop below,
     in the pharmacy's palette so the cut from the game is not a change of
     world. The desk edge sits at 72% so the monitor overlaps it. */
  background:
    linear-gradient(180deg, rgba(255, 244, 214, .05), transparent 42%),
    linear-gradient(180deg,
      #17414d 0%, #123641 58%, #0f2f39 71.7%,
      #33626e 72%, #2a5661 86%, #1e4650 100%);
  opacity: 0; transition: opacity 1.4s ease;
}
.walkthrough.on { opacity: 1; }
.walkthrough.hidden { display: none; }
/* The monitor. The screen is a true 16:9 panel sized off BOTH axes, so the
   film fills it exactly and nothing can be cut off by the window's shape. The
   chin below is what makes it read as hardware rather than a letterbox. */
.wt-monitor { display: grid; justify-items: center; }
.wt-screen {
  position: relative;
  /* as big as either axis allows: 16/9 of the height, capped by the width.
     The 86vh leaves room for the chin without pushing it off screen. */
  width: min(96vw, 152.8vh);   /* 86vh * 16/9 */
  aspect-ratio: 16 / 9;
  border: clamp(6px, .9vw, 14px) solid #16242b;
  border-bottom-width: clamp(8px, 1.1vw, 18px);
  border-radius: clamp(10px, 1.4vw, 22px);
  background: #05161b;
  box-shadow: 0 18px 50px rgba(0, 0, 0, .55), inset 0 0 0 2px rgba(255,255,255,.04);
  overflow: hidden;
}
#wt-video {
  width: 100%; height: 100%; display: block;
  /* cover, not contain: the panel is the film's own 16:9, so cover crops
     nothing — but it does close the sub-pixel seams that contain leaves in
     the rounded corners, where the dark backing showed through */
  object-fit: cover;
  background: #0d252d;
  outline: none;
}
/* the stand: a neck down to a foot on the desk, with the call badge on it */
.wt-chin {
  position: relative;
  display: flex; align-items: center; gap: 10px;
  padding: clamp(6px, .9vh, 10px) clamp(18px, 2.2vw, 32px);
  border-radius: clamp(8px, .9vw, 14px);
  background: linear-gradient(180deg, #1d2f38, #101f26);
  box-shadow: 0 5px 0 #0a161c, 0 18px 34px rgba(0, 0, 0, .45);
}
/* the neck between panel and foot */
.wt-chin::before {
  content: ""; position: absolute; left: 50%; bottom: 100%;
  transform: translateX(-50%);
  width: clamp(34px, 4vw, 62px); height: clamp(10px, 1.6vh, 20px);
  background: linear-gradient(180deg, #101f26, #1d2f38);
}
.wt-monitor { filter: drop-shadow(0 26px 30px rgba(0, 0, 0, .5)); }
.wt-chin i {
  width: 7px; height: 7px; border-radius: 50%;
  background: #4fb3a5; box-shadow: 0 0 8px rgba(79, 179, 165, .9);
}
.wt-chin small {
  font: 900 clamp(7px, .8vw, 10px)/1 "Avenir Next", sans-serif;
  letter-spacing: .3em; color: rgba(234, 244, 242, .55);
}
/* desk dressing, so the surface reads as a workspace rather than a stripe:
   a keyboard in front of the stand and a coffee off to the right */
.wt-desk-kb {
  position: absolute; pointer-events: none;
}
.wt-desk-kb {
  left: 50%; bottom: clamp(24px, 5.5vh, 64px);
  transform: translateX(-50%) perspective(300px) rotateX(38deg);
  width: clamp(180px, 22vw, 340px); height: clamp(20px, 3.4vh, 40px);
  border-radius: 8px;
  background: linear-gradient(180deg, #e9e2cf, #cfc5ac);
  box-shadow: 0 5px 0 #8f8266, 0 12px 20px rgba(0, 0, 0, .3);
}

/* Kurt's own tile lives inside the recording, so the subtitle bar is the only
   thing drawn over it. Same shape as the demo's, so the film and the game do
   not caption differently. */
/* Styled as the game's own speech bubble — cream card, ink border, the hard
   drop — so the film captions in the same voice as the rest of the game. */
.wt-sub {
  position: absolute; left: 50%; bottom: clamp(20px, 5vh, 56px);
  transform: translateX(-50%);
  max-width: 84%; padding: 12px 22px 14px;
  border: 3px solid var(--ink); border-radius: 16px; background: var(--cream);
  box-shadow: 0 6px 0 var(--ink-deep), 0 16px 30px rgba(0, 0, 0, .35);
  font: 700 clamp(14px, 1.45vw, 21px)/1.45 "Avenir Next", sans-serif;
  color: var(--ink); text-align: center; text-wrap: balance;
  opacity: 0; transition: opacity .18s ease; pointer-events: none;
}
.wt-sub.on { opacity: 1; }

/* only appears if the browser refuses to autoplay */
.wt-tap {
  position: absolute; z-index: 4; display: none;
  padding: 18px 30px; border: 0; border-radius: 14px; cursor: pointer;
  background: #4fb3a5; box-shadow: 0 5px 0 #2e8b7a;
  font: 900 14px/1 "Avenir Next", sans-serif; letter-spacing: .18em; color: #08262c;
}
.wt-tap.on { display: block; }

/* The offer. One button, because he asked a question with one answer. */
.wt-offer {
  position: absolute; inset: 0; z-index: 6; display: none; place-items: center;
  background: rgba(5, 22, 27, .72);
  backdrop-filter: blur(7px);
}
.wt-offer.on { display: grid; animation: wt-offer-in .34s ease both; }
@keyframes wt-offer-in { from { opacity: 0; } to { opacity: 1; } }
.wt-offer .inner {
  text-align: center; padding: clamp(28px, 4.4vh, 54px) clamp(30px, 5vw, 76px);
  border-radius: 20px; border: 3px solid var(--ink);
  background: linear-gradient(165deg, #143b46, #0c2a33);
  box-shadow: 0 12px 0 var(--ink-deep), 0 30px 60px rgba(0, 0, 0, .5);
  /* transform only: an entrance that animates opacity from zero leaves the
     offer invisible whenever the timeline is not running */
  animation: wt-pop .42s cubic-bezier(.2, .9, .3, 1.5) both;
}
@keyframes wt-pop { from { transform: translateY(16px) scale(.94); } to { transform: none; } }
.wt-offer .kicker {
  display: block; margin-bottom: 14px;
  font: 900 clamp(8px, .95vw, 11px)/1 "Avenir Next", sans-serif;
  letter-spacing: .28em; color: var(--teal);
}
.wt-offer b {
  display: block; margin-bottom: clamp(20px, 3vh, 34px);
  font: 400 clamp(26px, 3.4vw, 46px)/1.1 "Fredoka", "Avenir Next", sans-serif;
  color: #eaf4f2;
}
.wt-buy {
  padding: 17px 34px; border: 0; border-radius: 14px; cursor: pointer;
  background: var(--teal); box-shadow: 0 6px 0 var(--teal-deep);
  font: 900 clamp(12px, 1.2vw, 15px)/1 "Avenir Next", sans-serif;
  letter-spacing: .16em; color: #08262c;
}body:not(.keys-driving) .wt-buy:hover { background: #5cc4b5; }
.wt-buy:active { transform: translateY(4px); box-shadow: 0 2px 0 var(--teal-deep); }
.wt-buy:focus-visible { outline: 3px solid var(--cream); outline-offset: 4px; }

/* the film is the recording of the demo, so it never belongs in a capture */
body.take-running .walkthrough { display: none !important; }


/* ---- the install celebration ---------------------------------------------
   Banner and confetti over the reveal. Transform-only entrances, and the
   resting frames are the visible ones, so a stalled timeline still shows the
   card rather than hiding it. */
.install-banner {
  position: absolute; inset: 0; z-index: 90;
  display: grid; place-items: start center;
  padding-top: 13vh;
  pointer-events: none;
  overflow: hidden;
}
.install-banner.hidden { display: none; }
.ib-card {
  text-align: center; padding: 20px 42px 24px;
  border: 4px solid var(--ink); border-radius: 20px; background: var(--cream);
  box-shadow: 0 8px 0 var(--ink-deep), 0 22px 44px rgba(8, 24, 29, .4);
  transform: translateY(-16px) scale(.9);
  transition: transform .38s cubic-bezier(.2, .9, .3, 1.5);
}
.install-banner.on .ib-card { transform: none; }
.ib-kicker {
  display: block; margin-bottom: 8px;
  font: 900 clamp(9px, 1vw, 12px)/1 "Avenir Next", sans-serif;
  letter-spacing: .3em; color: var(--teal-deep);
}
.ib-card b {
  display: block; font: 600 clamp(26px, 3.4vw, 44px)/1 "Fredoka", "Avenir Next", sans-serif;
  color: var(--ink); letter-spacing: .01em;
}
.ib-card b em { font-style: normal; font-weight: 700; color: var(--teal-deep); }
.ib-card small {
  display: block; margin-top: 9px;
  font: 800 clamp(11px, 1.15vw, 15px)/1.3 "Avenir Next", sans-serif; color: #5d7078;
}
/* the confetti layer covers the screen; each piece is driven by the burst's
   own physics (position, spin, tumble), so there is no keyframe here at all */
.ib-confetti { position: fixed; inset: 0; overflow: hidden; pointer-events: none; }
.ib-confetti i {
  position: absolute; left: 0; top: 0;
  width: 11px; height: 15px; border-radius: 2.5px;
  will-change: transform, opacity;
}
.ib-confetti i.sq { width: 12px; height: 12px; border-radius: 3px; }


/* ---- the walkthrough's live Kurt tile --------------------------------------
   Sits over the film the way the demo's own tile sits over the share: same
   ink frame, same footer, bottom-right of the screen panel. */
.wt-pip {
  position: absolute; right: 2.4%; bottom: 4.2%; z-index: 3;
  width: clamp(120px, 21%, 300px);
  border: 3px solid var(--ink); border-radius: 12px; overflow: hidden;
  background: #16323b;
  box-shadow: 0 5px 0 var(--ink-deep), 0 14px 28px rgba(0, 0, 0, .45);
}
.wt-pip canvas { display: block; width: 100%; aspect-ratio: 4 / 3; outline: none; }
.wt-pip footer {
  display: flex; align-items: center; gap: 6px;
  padding: 5px 8px; background: var(--ink);
  font: 900 8px/1 "Avenir Next", sans-serif; letter-spacing: .1em; color: var(--cream);
}
.wt-pip footer i {
  width: 6px; height: 6px; border-radius: 50%;
  background: #e8524a; box-shadow: 0 0 6px rgba(232, 82, 74, .9);
}

/* ---- shift-complete pageantry ----------------------------------------------
   Entrance and star pops are transform-only, and the lit state is a class
   that stays — a stalled timeline shows the finished card, never a blank. */
#results-screen.celebrate { animation: rs-in .5s cubic-bezier(.2, .9, .3, 1.4); }
@keyframes rs-in { from { transform: translateY(26px) scale(.92); } }
#results-screen .stars {
  letter-spacing: .1em; margin: 8px 0 12px;
  font-size: clamp(58px, 7.4vw, 92px); line-height: 1;
}
/* Each star is a socket with a gold copy stacked on it. The gold layer's
   width is driven by the score counter, so the stars pour full left to right
   in step with the number — a meter wearing a costume. */
#results-screen .star {
  position: relative; display: inline-block;
  color: rgba(18, 60, 71, .16);        /* unearned: an inked-out socket */
}
#results-screen .star i {
  position: absolute; left: 0; top: 0; height: 100%;
  width: 0; overflow: hidden;
  font-style: normal; color: var(--gold);
  text-shadow: 0 3px 0 rgba(18, 60, 71, .22);
  pointer-events: none;
}
#results-screen .star.pop { animation: star-pop .5s cubic-bezier(.2, .9, .3, 1.6); }
@keyframes star-pop {
  0%   { transform: scale(.2) rotate(-30deg); }
  60%  { transform: scale(1.45) rotate(8deg); }
  100% { transform: none; }
}

/* ---- controller-aware keycaps ----------------------------------------------
   With a pad connected the interact chip becomes a round face button, tinted
   the way the hardware tints it: green A on Xbox pads, blue cross on
   PlayStation. Text and layout everywhere else stay untouched. */
.keycap.pad, .ti-key.pad {
  border-radius: 50%;
  min-width: 24px; text-align: center;
}
.keycap.pad-xbox, .ti-key.pad-xbox { background: #d9ecd2; color: #2f7d24; box-shadow: 0 3px 0 #a9c9a0; }
.keycap.pad-ps, .ti-key.pad-ps { background: #dbe3f4; color: #3f5fb8; box-shadow: 0 3px 0 #adbedd; }
/* On the cabinet the chip IS the button: a yellow disc, the same one the
   player's hand is on. The label text stays in the DOM and is clipped out of
   sight - spelling "YELLOW" made this chip several times wider than the "E"
   it replaced, wide enough to sit on top of the cryo bin's symbol. */
.keycap.pad-cab, .ti-key.pad-cab {
  border-radius: 50%; width: 1.55em; height: 1.55em; min-width: 0; padding: 0;
  overflow: hidden; text-indent: 120%; white-space: nowrap;
  background: #ffd400; border: .13em solid #14343c;
  box-shadow: inset 0 -.18em 0 rgba(0,0,0,.2), inset 0 .16em 0 rgba(255,255,255,.5), 0 .16em 0 #c9a600;
}


/* ---- battle sandbox ---------------------------------------------------------
   Two score chips and a shared clock; hit words float in the world. Same
   cream-and-ink language as every other HUD piece. */
.bt-hud {
  position: fixed; top: 16px; left: 50%; transform: translateX(-50%); z-index: 40;
  display: flex; align-items: center; gap: 16px; pointer-events: none;
}
.bt-hud.hidden { display: none; }
.bt-chip {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 14px; border: 3px solid var(--ink); border-radius: 14px;
  background: var(--cream); box-shadow: 0 4px 0 var(--ink-deep);
}
.bt-chip b { font: 900 11px/1 "Avenir Next", sans-serif; letter-spacing: .12em; }
.bt-chip.p1 b { color: var(--team1, #2e8b7a); }
.bt-chip.p2 b { color: var(--team2, #8e3b4a); }
.bt-chip strong { font: 800 26px/1 "Fredoka", "Avenir Next", sans-serif; color: var(--ink); }
.bt-chip small { font: 900 8px/1.5 "Avenir Next", sans-serif; letter-spacing: .1em; color: #7d8f95; }
.bt-chip small i { font-style: normal; color: var(--ink); font-size: 10px; }
.bt-clock {
  padding: 10px 18px; border: 3px solid var(--ink); border-radius: 14px;
  background: var(--cream); box-shadow: 0 4px 0 var(--ink-deep);
  font: 800 24px/1 "Fredoka", "Avenir Next", sans-serif; color: var(--ink);
}
.bt-bam {
  position: fixed; z-index: 45; transform: translate(-50%, -50%) rotate(-6deg);
  font: 900 24px/1 "Avenir Next", sans-serif; letter-spacing: .04em; color: var(--coral);
  text-shadow: 0 2px 0 var(--ink-deep); pointer-events: none;
  animation: bt-bam .85s ease-out forwards;
}
@keyframes bt-bam {
  0% { transform: translate(-50%, -50%) rotate(-6deg) scale(.4); opacity: 0; }
  25% { transform: translate(-50%, -50%) rotate(-6deg) scale(1.2); opacity: 1; }
  100% { transform: translate(-50%, -90%) rotate(-6deg) scale(1); opacity: 0; }
}
.bt-result {
  position: fixed; inset: 0; z-index: 60; display: none; place-items: center;
  background: rgba(5, 22, 27, .62);
}
.bt-result.on { display: grid; }
.bt-result .inner {
  text-align: center; padding: 34px 54px 38px;
  border: 4px solid var(--ink); border-radius: 20px; background: var(--cream);
  box-shadow: 0 10px 0 var(--ink-deep), 0 28px 56px rgba(0, 0, 0, .45);
}
.bt-result .kicker {
  display: block; margin-bottom: 10px;
  font: 900 10px/1 "Avenir Next", sans-serif; letter-spacing: .3em; color: #8e3b4a;
}
.bt-result b { display: block; font: 600 44px/1 "Fredoka", "Avenir Next", sans-serif; color: var(--ink); }
.bt-result .line { margin: 12px 0 22px; font: 800 26px/1 "Fredoka", sans-serif; color: #5d7078; }
.bt-result button {
  margin: 0 6px; padding: 13px 26px; border: 0; border-radius: 12px; cursor: pointer;
  font: 900 12px/1 "Avenir Next", sans-serif; letter-spacing: .14em;
}
#bt-rematch { background: var(--teal); box-shadow: 0 4px 0 var(--teal-deep); color: #08262c; }
#bt-exit { background: #d9d2c0; box-shadow: 0 4px 0 #a89f88; color: var(--ink); }

.bt-controls {
  position: fixed; bottom: 12px; left: 50%; transform: translateX(-50%); z-index: 40;
  font: 800 10px/1 "Avenir Next", sans-serif; letter-spacing: .06em;
  color: rgba(253, 246, 228, .78); pointer-events: none;
  text-shadow: 0 1px 2px rgba(8, 24, 29, .6);
  display: none;
}
.bt-controls b { color: var(--gold); letter-spacing: .1em; }
body:has(#bt-hud:not(.hidden)) .bt-controls { display: block; }

/* what a scanned tray is short of, floating over its slot */
.bt-need {
  position: fixed; z-index: 42; transform: translate(-50%, -100%);
  display: flex; gap: 4px; pointer-events: none;
}
.bt-need i {
  font: 900 10px/1 "Avenir Next", sans-serif; font-style: normal; letter-spacing: .04em;
  padding: 5px 7px; border: 2px solid var(--ink); border-radius: 8px;
  background: var(--cream); color: var(--ink); box-shadow: 0 2px 0 var(--ink-deep);
}
.bt-need i.med-pack { background: #fbeecb; }
.bt-need i.syringe { background: #e7dff6; }
.bt-need i.seal { background: #e2e8ea; }
.bt-need i.amber { background: #dbe6f8; }
.bt-need i.cold { background: #f8dedb; }
.bt-need i.bottle { background: #dbe6f8; }


/* battle: arcade's icon language in the score chips and the loading flyers */
.bt-flyer {
  position: fixed; z-index: 46; width: 34px; height: 34px;
  pointer-events: none; transform: translate(-50%, -50%);
  filter: drop-shadow(0 2px 2px rgba(18, 60, 71, .35));
}
.bt-hand {
  display: inline-grid; place-items: center; vertical-align: middle;
  width: 20px; height: 20px; margin-right: 3px;
  border: 2px solid var(--ink); border-radius: 50%; background: #fff;
  font-style: normal; font-size: 11px; color: var(--teal-deep);
}
.bt-hand img { width: 14px; height: 14px; }
.bt-hand.med-pack { background: #fbeecb; }
.bt-hand.syringe { background: #e7dff6; }
.bt-hand.seal { background: #e2e8ea; }
.bt-hand.amber { background: #dbe6f8; }
.bt-hand.cold { background: #f8dedb; }
.bt-hand.tray { background: #eafbf1; font-weight: 900; }
.bt-hand.empty { border-style: dashed; border-color: #b9c7cb; background: transparent; }


/* battle hands: arcade's inventory panel shape, one per player, at the bottom */
.bt-inv {
  position: fixed; bottom: 34px; z-index: 40;
  display: flex; align-items: center; gap: 9px;
  padding: 10px 14px; border: 3px solid var(--ink); border-radius: 16px;
  background: var(--cream); box-shadow: 0 5px 0 var(--ink-deep);
  pointer-events: none;
}
.bt-inv.hidden { display: none; }
.bt-inv.p1 { left: 18px; }
.bt-inv.p2 { right: 18px; }
.bt-inv > b {
  font: 900 10px/1.1 "Avenir Next", sans-serif; letter-spacing: .14em; color: var(--ink);
  writing-mode: vertical-rl; transform: rotate(180deg);
}
.bt-inv.p1 > b { color: var(--team1, #2e8b7a); }
.bt-inv.p2 > b { color: var(--team2, #8e3b4a); }
.bt-inv span { display: flex; gap: 6px; }
/* The shift's hands panel, in battle's colours. Slots hold their place when
   empty so "nearly full" is a shape you read rather than a number you count. */
.bt-inv .bt-hand {
  width: 44px; height: 44px; margin: 0;
  border: 3px solid var(--ink); border-radius: 11px;
  display: grid; place-items: center;
  font-size: 20px;
}
.bt-inv .bt-hand img { width: 32px; height: 32px; object-fit: contain; }
.bt-inv .bt-hand.empty {
  border-style: dashed;
  border-color: rgba(20, 52, 60, .3);
  background: transparent;
}
/* the same pop the shift gives a slot when something lands in it */
.bt-inv .bt-hand.received-item { animation: inventory-receive .34s cubic-bezier(.2,.9,.3,1.4); }

/* Cabinet: keep the physical button legend readable even with no ammo.
   Charge strips and the small cooldown bar carry availability, not a slash
   or a permanent gold Push highlight. Website styling stays unchanged. */
body.cabinet .bt-inv .bt-atk.push,
body.cabinet .bt-inv .bt-atk.spent {
  background: var(--cream); opacity: 1; border-style: solid;
}
body.cabinet .bt-inv .bt-atk.spent .bt-lab {
  color: var(--ink); text-decoration: none;
}
body.cabinet .bt-inv .bt-atk.sal.spent::before { background: #2f9fbf; }
body.cabinet .bt-inv .bt-atk.cry.spent::before { background: #4fb6d8; }
body.cabinet .bt-inv .bt-atk.push.spent::before { background: #4f86d8; }
.cab-tray-carry {
  position: fixed; z-index: 22; pointer-events: none;
  transform: translate(-50%, -100%);
  display: flex; align-items: center; gap: 6px;
  padding: 7px 10px; border: 2px solid var(--ink); border-radius: 12px;
  background: var(--cream); color: var(--ink);
  box-shadow: 0 3px 0 rgba(20,52,60,.25);
  font: 900 11px/1 "Nunito", sans-serif; letter-spacing: .03em; white-space: nowrap;
}
.cab-tray-carry[hidden] { display: none; }
.cab-tray-carry svg { width: 25px; height: 19px; flex: none; }
.cab-tray-carry.ready { background: #dff5e9; }
.cab-tray-carry.picked-up { animation: cab-tray-pickup .3s ease-out; }
@keyframes cab-tray-pickup {
  from { opacity: 0; transform: translate(-50%, -75%) scale(.85); }
  to { opacity: 1; transform: translate(-50%, -100%) scale(1); }
}
@media (prefers-reduced-motion: reduce) { .cab-tray-carry.picked-up { animation: none; } }
.bt-full {
  align-self: center; padding: 6px 10px; margin-left: 2px;
  border-radius: 9px; background: var(--coral, #e8524a); color: #fff;
  font: 950 10px/1.15 "Nunito", sans-serif; letter-spacing: .1em; text-align: center;
}


/* battle action prompts: the arcade pill, one per player, above their hands */
.bt-prompt {
  position: fixed; bottom: 96px; z-index: 41;
  display: flex; align-items: center; gap: 10px;
  padding: 10px 20px 10px 10px;
  border: 4px solid var(--ink); border-radius: 999px;
  background: var(--ink); color: #fff;
  box-shadow: 0 6px 0 var(--ink-deep), 0 12px 22px rgba(8,24,29,.3);
  font: 950 14px "Nunito", "Avenir Next", "Trebuchet MS", system-ui, sans-serif;
  letter-spacing: .04em;
  pointer-events: none;
  opacity: 0; transform: translateY(8px);
  transition: opacity .14s, transform .14s;
}
.bt-prompt.on { opacity: 1; transform: translateY(0); }
.bt-prompt.hidden { display: none; }
/* Beside the weapons, on that player's own side. At 18px these sat on top of
   the very buttons they were describing; out at 25% they were adrift in the
   middle of the floor, nowhere near the seat they belonged to. The weapon column
   runs 16 to 128, so 140 clears it with a gap, and the height clears the hands
   row underneath. Mirrored for P2. */
.bt-prompt.p1 { left: 140px; right: auto; }
.bt-prompt.p2 { right: 140px; left: auto; }
.bt-prompt .keycap {
  display: grid; place-items: center;
  width: 27px; height: 27px; border-radius: 8px;
  background: var(--gold); color: var(--ink-deep);
  font: 950 14px "Fredoka", sans-serif;
  animation: keycap-pulse 1s ease-in-out infinite alternate;
}
.bt-prompt .act { display: flex; flex-direction: column; line-height: 1.05; }
.bt-prompt .act small { font-size: 10px; letter-spacing: .14em; opacity: .78; }
/* the second line under a bay grab when the player has no tray anywhere:
   the meds are legal to take, but they have nowhere to go yet */
.bt-prompt .sub {
  display: block; margin-top: 3px;
  font: 900 9.5px "Nunito", sans-serif; font-style: normal; letter-spacing: .14em;
  color: #f2938f;
}
/* Hint state: nothing in reach and no tray in play. Not an action, so no gold
   keycap - a cream pill in the room's own voice, with the cart it is pointing
   at. This is the pill a new player looks at for the first ten seconds. */
/* ---- the green NEXT ACTION ----------------------------------------------------
   Beside the bottom of the weapon stack, where the old pill sat. Green is the
   one colour nothing on the panel uses, so it can only mean "go here". It never
   carries a keycap: it is a direction, not a button - the yellow GRAB chip at
   the top of the stack is the button. */
.bt-prompt.next {
  background: #55c48b; color: var(--ink-deep); border-color: var(--ink);
  font-family: "Fredoka", "Nunito", sans-serif; letter-spacing: .06em;
  padding: 9px 18px 9px 10px; gap: 10px;
}
.bt-prompt.next .tag {
  padding: 3px 7px 2px; border-radius: 6px;
  background: var(--ink); color: #b8f0d0;
  font: 900 8.5px/1 "Nunito", sans-serif; letter-spacing: .22em;
}
.bt-prompt.next .act small { color: var(--ink-deep); opacity: .78; }
.bt-prompt.next .cart-glyph { margin-bottom: 8px; }
body.cabinet .bt-prompt.next .tag { font-size: 11px; }
.bt-prompt.hint .act small { color: #b84a3e; opacity: 1; }
.bt-prompt .cart-glyph {
  position: relative; flex: 0 0 auto;
  width: 30px; height: 22px; margin: 2px 2px 6px 2px;
  border-radius: 4px 4px 3px 3px;
  background: #dd8177; border: 3px solid var(--ink);
  box-shadow: inset 0 -6px 0 #b84a3e;
  animation: cart-glyph-nudge 1.1s ease-in-out infinite alternate;
}
.bt-prompt .cart-glyph::before, .bt-prompt .cart-glyph::after {
  content: ""; position: absolute; bottom: -9px; width: 8px; height: 8px;
  border-radius: 50%; background: var(--ink);
}
.bt-prompt .cart-glyph::before { left: 1px; }
.bt-prompt .cart-glyph::after { right: 1px; }
@keyframes cart-glyph-nudge { to { transform: translateX(3px); } }
body.cabinet .bt-prompt { font-size: 19px; padding: 13px 26px 13px 13px; }
body.cabinet .bt-prompt .sub { font-size: 12px; }
body.cabinet .bt-prompt .act small { font-size: 12.5px; }

/* the weapons pouch: a divider, then two smaller bubbles beside the meds */
.bt-inv .bt-sep {
  width: 3px; height: 30px; margin: 0 2px;
  border-radius: 2px; background: var(--ink);
  opacity: .25;
}
.bt-inv .bt-wpn {
  width: 22px; height: 22px; align-self: center;
  display: grid; place-items: center;
  border: 2.5px solid var(--ink); border-radius: 50%;
  font-style: normal; font-size: 10px;
}
.bt-inv .bt-wpn.saline { border-color: #2f9fbf; background: #e6f6fb; color: #2f9fbf; }
.bt-inv .bt-wpn.empty { border-style: dashed; border-color: #b9c7cb; background: transparent; }

/* ---- the battle cabinet: pick a side, pick a tech, go -------------------- */
.bt-setup {
  position: fixed; inset: 0; z-index: 130;
  display: grid; place-items: center;
  padding: 22px;
  background: radial-gradient(circle at 50% 18%, rgba(24,58,66,.82), rgba(8,24,29,.94));
  backdrop-filter: blur(3px);
}
.bt-setup.hidden { display: none; }
.bt-setup-card {
  position: relative;
  width: min(1080px, 100%); max-height: 100%;
  overflow: hidden auto;
  padding: 14px 22px 12px;
  border: 5px solid var(--ink); border-radius: 26px;
  background: var(--cream);
  box-shadow: 0 12px 0 var(--ink-deep), 0 26px 60px rgba(4,16,20,.5);
}
.bt-setup-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
  padding-bottom: 7px; margin-bottom: 8px;
  border-bottom: 3px dashed rgba(20,52,60,.28);
}
.bt-setup-title span { font: 900 11px/1 "Nunito", sans-serif; letter-spacing: .3em; color: var(--teal-deep); }
.bt-setup-title h2 { margin: 4px 0 0; font: 950 30px/1 "Fredoka", sans-serif; letter-spacing: .04em; color: var(--ink); }
.bt-setup-step {
  margin: 0; padding: 9px 16px;
  border: 3px solid var(--ink); border-radius: 999px; background: var(--gold);
  font: 950 12px "Nunito", sans-serif; letter-spacing: .14em; color: var(--ink-deep);
}
.bt-step.hidden { display: none; }

/* step one: the only question on screen */
.bt-choices { display: grid; gap: 12px; }
.bt-choice {
  display: block; width: 100%; text-align: left;
  padding: 18px 22px;
  border: 4px solid var(--ink); border-radius: 18px;
  background: #fff; color: var(--ink);
  box-shadow: 0 6px 0 var(--ink-deep);
  transition: transform .14s, box-shadow .14s, background .14s;
}
.bt-choice b { display: block; font: 950 21px "Fredoka", sans-serif; letter-spacing: .04em; }
.bt-choice small { display: block; margin-top: 4px; font: 700 12.5px/1.45 "Nunito", sans-serif; color: rgba(20,52,60,.68); }body:not(.keys-driving) .bt-choice:hover, .bt-choice:focus-visible { background: var(--gold); transform: translateY(-3px); box-shadow: 0 9px 0 var(--ink-deep); }

/* the host keeps the code in reach while they pick */
.bt-room-strip {
  display: flex; align-items: center; gap: 9px;
  padding: 5px 12px; border: 3px dashed rgba(20,52,60,.3); border-radius: 999px;
}
.bt-room-strip.hidden { display: none; }
.bt-room-code {
  font: 700 17px "Fredoka", sans-serif; letter-spacing: .22em; color: var(--ink);
}
.bt-room-strip input { display: none; }
.bt-room-strip button {
  padding: 5px 10px; border: 2.5px solid var(--ink); border-radius: 999px;
  background: #fff; color: var(--ink);
  font: 900 9px "Nunito", sans-serif; letter-spacing: .08em;
  box-shadow: 0 2px 0 var(--ink-deep); cursor: pointer;
}
.bt-room-strip .bt-party-state { margin: 0; font-size: 10.5px; }
.bt-setup-start.hidden { display: none; }

@media (max-width: 780px) {
}
.bt-mode {
  padding: 10px 16px; border: 3px solid var(--ink); border-radius: 999px;
  background: #fff; color: var(--ink);
  font: 950 12px "Nunito", sans-serif; letter-spacing: .1em;
  box-shadow: 0 4px 0 var(--ink-deep);
}
.bt-mode.on { background: var(--gold); }body:not(.keys-driving) .bt-mode:hover { transform: translateY(-2px); box-shadow: 0 6px 0 var(--ink-deep); }

.bt-setup-bays { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 14px; }
/* any seat still waiting on a player sits back until they arrive */
.bt-bay:not(.joined) { opacity: .5; filter: grayscale(.6); }
.bt-bay:not(.joined) .bt-arrow { opacity: .2; pointer-events: none; }
.bt-setup-vs { font: 950 26px "Fredoka", sans-serif; color: var(--ink); opacity: .5; }

.bt-bay {
  padding: 12px; border: 4px solid var(--ink); border-radius: 20px;
  background: #fff; box-shadow: 0 6px 0 var(--ink-deep);
  transition: box-shadow .16s, transform .16s;
}
.bt-bay.p1.joined { box-shadow: 0 6px 0 var(--ink-deep), inset 0 0 0 4px #4fb3a5; }
.bt-bay.p2.joined { box-shadow: 0 6px 0 var(--ink-deep), inset 0 0 0 4px #8e3b4a; }
.bt-bay.ready { transform: translateY(-3px); }
.bt-bay.p1.ready { box-shadow: 0 9px 0 var(--ink-deep), inset 0 0 0 6px #4fb3a5; }
.bt-bay.p2.ready { box-shadow: 0 9px 0 var(--ink-deep), inset 0 0 0 6px #8e3b4a; }

.bt-bay-flag { display: flex; align-items: baseline; justify-content: space-between; padding: 0 4px 8px; }
.bt-bay-flag b { font: 950 13px "Nunito", sans-serif; letter-spacing: .16em; }
.bt-bay.p1 .bt-bay-flag b { color: #2e8b7a; }
.bt-bay.p2 .bt-bay-flag b { color: #8e3b4a; }
.bt-bay-flag span { font: 900 11px "Nunito", sans-serif; color: rgba(20,52,60,.5); }

.bt-bay-stage { position: relative; border-radius: 14px; overflow: hidden; border: 3px solid var(--ink); }
.bt-pick-canvas { display: block; width: 100%; height: 232px; }
/* The bay is a fitting room: preview beside the same five choices the arcade
   builder offers, at full size now the match settings live in their own panel.
   Cursor-driven for pads: a row ring, and on a parts row the left/right step
   IS the choice. */
.bt-bay-body { display: grid; grid-template-columns: 1fr 1.45fr; gap: 10px; align-items: stretch; }
.bt-bay-body .bt-bay-stage { min-height: 264px; }
.bt-bay-opts { display: grid; align-content: center; gap: 9px; min-width: 0; }
.bt-bay-opts.locked { opacity: .5; pointer-events: none; }
/* ---- the lobby's roster: the arcade's star techs, the same tiles ---------- */
.bt-bay-plate { display: grid; gap: 3px; margin-bottom: 8px; }
.bt-bay-plate b { font: 700 clamp(18px, 2vw, 26px)/1 "Fredoka", sans-serif; color: var(--ink); letter-spacing: .02em; }
.bt-bay-plate small { font: 900 10px/1 "Nunito", sans-serif; letter-spacing: .2em; color: var(--teal-deep, #2e6b64); }
.bt-roster { gap: 6px; padding: 4px; border-radius: 12px; }
.bt-roster.focus { box-shadow: 0 0 0 2.5px var(--teal); background: rgba(79,179,165,.1); }
.bt-roster .cab-tile { display: block; width: auto; min-height: 0; margin: 0; padding: 0; font: inherit; cursor: pointer; box-shadow: none; }
.bt-roster .cab-tile span { font-size: clamp(7px, .6vw, 10px); }
.bt-roster .cab-tile.on { transform: translateY(-4px) scale(1.06); border-color: var(--ink); box-shadow: 0 5px 0 #06161b, 0 0 0 3px rgba(79,179,165,.45); }
.bt-bay.p2 .bt-roster .cab-tile.on { box-shadow: 0 5px 0 #06161b, 0 0 0 3px rgba(216,64,47,.4); }
.bt-bay-opts.locked .cab-tile:not(.on) { opacity: .25; }
.bt-opt-row { display: grid; grid-template-columns: 44px 1fr; align-items: center; gap: 5px; border-radius: 9px; padding: 3px 4px; }
.bt-opt-row.wide .bt-opt-set { flex-wrap: wrap; }
.bt-opt-row.focus .bt-opt-set { background: rgba(79, 179, 165, .16); box-shadow: 0 0 0 2.5px var(--teal); }
.bt-opt-row.focus small { color: var(--teal-deep, #2e6b64); }
.bt-opt-row small { font: 900 8.5px "Nunito", sans-serif; letter-spacing: .1em; color: rgba(20,52,60,.55); }
.bt-opt-row.act { grid-template-columns: 1fr; justify-items: center; }
.bt-opt-row.act small { display: none; }
/* Each row's options sit in ONE soft track, so a row reads as a single
   control rather than six loose buttons. Everything unchosen is quiet - no
   borders, slight fade - and only the chosen part and the cursor speak. */
.bt-opt-set {
  /* one line per group - a wrapped row is what made the rail read as
     disorganized. The one exception is HAIR (.wide): six real names beat six
     abbreviations, and that row alone is allowed a second line for them. */
  display: flex; flex-wrap: nowrap; gap: 5px; align-items: center;
  width: fit-content; max-width: 100%;
  padding: 4px 8px; border-radius: 999px;
  background: rgba(20,52,60,.06);
}
.bt-sw {
  width: 19px; height: 19px; padding: 0; border-radius: 50%;
  background: var(--sw); border: none;
  box-shadow: inset 0 0 0 1.5px rgba(20,52,60,.16);
  opacity: .85; cursor: pointer;
  transition: transform .12s ease, opacity .12s ease;
}
/* the global button:hover lifts and grows the red shadow (0 8px #ae3e39) -
   every rail part has to pin BOTH down or hovering a tiny swatch grew a big
   red wing under it */body:not(.keys-driving) .bt-sw:hover { opacity: 1; transform: none; box-shadow: inset 0 0 0 1.5px rgba(20,52,60,.16); }body:not(.keys-driving) .bt-sw.on:hover { box-shadow: 0 0 0 2.5px var(--ink); }
.bt-sw.on { opacity: 1; transform: scale(1.18); box-shadow: 0 0 0 2.5px var(--ink); }
.bt-part {
  /* the game's global button carries a red fill and a heavy red drop shadow -
     every one of these has to zero BOTH or the shadow bleeds through */
  padding: 3px 8px; border: none; border-radius: 999px;
  background: transparent; box-shadow: none; color: rgba(20,52,60,.62);
  font: 800 9px "Nunito", sans-serif; letter-spacing: .03em;
  cursor: pointer; white-space: nowrap;
}body:not(.keys-driving) .bt-part:hover { color: var(--ink); transform: none; box-shadow: none; background: rgba(20,52,60,.07); }body:not(.keys-driving) .bt-part.on:hover { background: var(--gold); box-shadow: 0 0 0 2px var(--ink); }body:not(.keys-driving) .bt-part.rnd:hover { background: transparent; box-shadow: 0 0 0 2px var(--ink); }
.bt-part.on { background: var(--gold); color: var(--ink); box-shadow: 0 0 0 2px var(--ink); }
.bt-part.rnd { box-shadow: 0 0 0 2px rgba(20,52,60,.35); padding: 5px 14px; color: var(--ink); }
/* the RANDOM row has no track, so the cursor ring lands on the button itself -
   without this the cursor reached the row but showed nothing, which read as
   "you cannot get down to random" */
.bt-opt-row.act.focus .bt-part.rnd { box-shadow: 0 0 0 2.5px var(--teal); background: rgba(79,179,165,.16); }

/* the options panel: everything about how the match runs, sliding over the
   card's right edge. An overlay, so the card itself can never grow a scroll */
.bt-options-panel {
  position: absolute; top: 0; right: 0; bottom: 0; z-index: 40;
  width: min(470px, 92%);
  padding: 18px 20px;
  background: var(--cream);
  border-left: 5px solid var(--ink);
  border-radius: 26px 0 0 26px;
  box-shadow: -18px 0 44px rgba(4,16,20,.35);
  transform: translateX(104%);
  transition: transform .24s cubic-bezier(.2,.75,.25,1);
  overflow-y: auto;
}
.bt-options-panel.open { transform: translateX(0); }
@media (prefers-reduced-motion: reduce) { .bt-options-panel { transition: none; } }
.bt-options-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
.bt-options-foot { display: flex; justify-content: flex-end; gap: 8px; }
.bt-options-foot .bt-drawer-act { padding: 9px 22px; font-size: 11px; }
.bt-options-head b { font: 700 20px "Fredoka", sans-serif; letter-spacing: .04em; color: var(--ink); }
.bt-drawer-act {
  padding: 6px 14px; border: 2.5px solid var(--ink); border-radius: 999px;
  background: #fff; color: var(--ink);
  font: 900 10px "Nunito", sans-serif; letter-spacing: .08em;
  box-shadow: 0 2px 0 var(--ink-deep); cursor: pointer;
}
.bt-drawer-act.primary { background: var(--gold); }
/* Inside the panel every setting is the same shape: a label column and one
   segmented track, quiet until chosen - the character rail's grammar. */
.bt-options-body { display: grid; gap: 12px; margin-top: 12px; }
.opt-group { display: grid; gap: 9px; padding: 12px 14px; border: 3px dashed rgba(20,52,60,.25); border-radius: 14px; }
.opt-group.locked { opacity: .55; }
.opt-group.locked .bt-rule, .opt-group.locked .bt-step, .opt-group.locked input { pointer-events: none; }
.opt-row { display: grid; grid-template-columns: 104px 1fr; gap: 10px; align-items: center; }
.opt-row > small { font: 900 8.5px "Nunito", sans-serif; letter-spacing: .12em; color: rgba(20,52,60,.55); }
.opt-seg { display: flex; gap: 4px; padding: 3px; border-radius: 999px; background: rgba(20,52,60,.06); }
.opt-seg .bt-rule {
  flex: 1; padding: 7px 6px; border: none; border-radius: 999px;
  background: transparent; box-shadow: none; color: rgba(20,52,60,.6);
  font: 900 9px "Nunito", sans-serif; letter-spacing: .05em; white-space: nowrap;
}body:not(.keys-driving) .opt-seg .bt-rule:hover { transform: none; box-shadow: none; background: rgba(20,52,60,.07); color: var(--ink); }
.opt-seg .bt-rule.on { background: var(--gold); color: var(--ink); box-shadow: 0 0 0 2px var(--ink); }body:not(.keys-driving) .opt-seg .bt-rule.on:hover { background: var(--gold); box-shadow: 0 0 0 2px var(--ink); }
.opt-amount { display: flex; align-items: center; gap: 8px; }
.opt-amount .bt-step {
  width: 34px; height: 34px; padding: 0;
  border: 3px solid var(--ink); border-radius: 10px;
  background: var(--cream); color: var(--ink);
  font: 950 16px "Fredoka", sans-serif;
  box-shadow: 0 3px 0 var(--ink-deep);
}body:not(.keys-driving) .opt-amount .bt-step:hover { transform: none; box-shadow: 0 3px 0 var(--ink-deep); }
/* the pad cursor: the ring lands on the row's track, like the rail */
.opt-row.opt-focus .opt-seg, .opt-row.opt-focus .opt-amount { border-radius: 999px; box-shadow: 0 0 0 3px var(--teal); }
#bt-options-done.cursor { outline: 3.5px solid var(--teal); outline-offset: 2px; }
/* the pad cursor on the how-are-you-playing cards and the code step */
.bt-choice.pad-focus, .bt-setup-start.pad-focus { box-shadow: 0 4px 0 var(--ink-deep), 0 0 0 3.5px var(--teal); }
/* An empty seat sits quietly: no blinking, just a soft veil and a line
   saying who it is waiting for. The how-to-join hint lives in the calm
   status line under the bay instead of pulsing over the portrait. */
.bt-bay-join {
  position: absolute; inset: 0; display: grid; place-items: center;
  padding: 0 14px; text-align: center;
  background: rgba(232,236,234,.72); color: rgba(20,52,60,.72);
  font: 950 13px "Nunito", sans-serif; letter-spacing: .14em;
}
.bt-bay.joined .bt-bay-join { display: none; }

/* Building a bay costs a WebGL context and a full character rig. That is a
   real wait, so the stage says it is working instead of showing an empty
   rectangle that reads as a crash. Three dots walk left to right the way a
   tech steps up to the podium; the label sits under them, calm, no spinner. */
.bt-bay-warm {
  position: absolute; inset: 0; z-index: 2;
  display: grid; place-items: center; align-content: center; gap: 12px;
  grid-auto-flow: row;
  background: rgba(232, 236, 234, .94);
  color: rgba(20, 52, 60, .62);
  font: 950 11px "Nunito", sans-serif; letter-spacing: .18em; text-transform: uppercase;
}
.bt-bay-warm span { grid-column: 1; }
.bt-bay-warm i {
  grid-row: 1; width: 9px; height: 9px; border-radius: 50%;
  background: currentColor; opacity: .25;
  animation: bt-warm-step 1.05s ease-in-out infinite;
}
.bt-bay-warm i:nth-child(1) { grid-column: 1; }
.bt-bay-warm i:nth-child(2) { grid-column: 2; animation-delay: .14s; }
.bt-bay-warm i:nth-child(3) { grid-column: 3; animation-delay: .28s; }
.bt-bay-warm span { grid-row: 2; grid-column: 1 / -1; }
.bt-bay-warm.hidden { display: none; }
@keyframes bt-warm-step {
  0%, 70%, 100% { opacity: .22; transform: translateY(0); }
  35%           { opacity: .85; transform: translateY(-4px); }
}

/* Under the start button: what the cabinet is doing after you commit. */
.bt-setup-note {
  margin: 8px 0 0; text-align: center;
  font: 800 12px "Nunito", sans-serif; letter-spacing: .1em;
  color: rgba(20, 52, 60, .6);
}
.bt-setup-note.hidden { display: none; }

@media (prefers-reduced-motion: reduce) {
  .bt-bay-warm i { animation: none; opacity: .5; }
}

.bt-bay:not(.joined) .bt-arrow, .bt-bay.ready .bt-arrow { opacity: .35; pointer-events: none; }
.bt-bay-status {
  margin: 0; min-height: 18px; text-align: center;
  font: 900 11px "Nunito", sans-serif; letter-spacing: .12em; color: rgba(20,52,60,.62);
}
.bt-bay.ready .bt-bay-status { color: #2e8b7a; font-size: 13px; }
.bt-bay.p2.ready .bt-bay-status { color: #8e3b4a; }

/* the party room */
.bt-party { padding: 6px 2px 2px; }
.bt-party.hidden { display: none; }
.bt-party-choice { display: flex; gap: 10px; justify-content: center; }
.bt-party-btn {
  padding: 12px 20px; border: 3px solid var(--ink); border-radius: 14px;
  background: #fff; color: var(--ink);
  font: 950 13px "Nunito", sans-serif; letter-spacing: .1em;
  box-shadow: 0 5px 0 var(--ink-deep);
}
.bt-party-btn.on { background: var(--gold); }
.bt-party-panel {
  margin-top: 14px; padding: 16px;
  display: grid; justify-items: center; gap: 10px;
  border: 3px dashed rgba(20,52,60,.3); border-radius: 16px;
}
.bt-party-panel.hidden { display: none; }
.bt-party-label { font: 900 11px "Nunito", sans-serif; letter-spacing: .22em; color: rgba(20,52,60,.6); }
.bt-party-code {
  font: 950 44px "Fredoka", sans-serif; letter-spacing: .22em; color: var(--ink);
  padding: 4px 18px; border-radius: 14px; background: var(--gold);
  border: 4px solid var(--ink); box-shadow: 0 5px 0 var(--ink-deep);
}
.bt-party-link { display: flex; gap: 8px; width: min(520px, 100%); }
.bt-party-link input {
  flex: 1; padding: 10px 12px;
  border: 3px solid var(--ink); border-radius: 12px;
  background: #fff; color: var(--ink);
  font: 800 12px "Nunito", sans-serif;
}
.bt-party-link button {
  padding: 10px 14px; border: 3px solid var(--ink); border-radius: 12px;
  background: var(--cream); color: var(--ink);
  font: 950 11px "Nunito", sans-serif; letter-spacing: .1em;
  box-shadow: 0 4px 0 var(--ink-deep);
}
.bt-party-entry {
  width: min(320px, 100%); padding: 12px;
  text-align: center; text-transform: uppercase;
  border: 4px solid var(--ink); border-radius: 14px;
  background: #fff; color: var(--ink);
  font: 950 30px "Fredoka", sans-serif; letter-spacing: .3em;
}
.bt-party-state { margin: 0; font: 800 12px "Nunito", sans-serif; color: rgba(20,52,60,.66); }
.bt-online-note {
  margin: 14px 0 0; padding: 10px 14px;
  border-left: 4px solid var(--gold); border-radius: 0 10px 10px 0;
  background: rgba(242,179,61,.14);
  font: 700 12px/1.5 "Nunito", sans-serif; color: var(--ink);
}
.bt-online-note.hidden { display: none; }

.bt-setup-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin-top: 16px; padding-top: 14px;
  border-top: 3px dashed rgba(20,52,60,.28);
}
.bt-setup-back {
  padding: 12px 20px; border: 3px solid var(--ink); border-radius: 14px;
  background: var(--cream); color: var(--ink);
  font: 950 12px "Nunito", sans-serif; letter-spacing: .1em;
  box-shadow: 0 5px 0 var(--ink-deep);
}
.bt-setup-start {
  padding: 14px 30px; border: 4px solid var(--ink); border-radius: 16px;
  background: var(--gold); color: var(--ink-deep);
  font: 950 16px "Fredoka", sans-serif; letter-spacing: .08em;
  box-shadow: 0 6px 0 var(--ink-deep);
}
.bt-setup-start:disabled { background: #d8ddda; color: rgba(20,52,60,.45); box-shadow: 0 6px 0 #aeb7b4; transform: none; }

@media (max-width: 780px) {
  .bt-setup-bays { grid-template-columns: 1fr; }
  .bt-setup-vs { justify-self: center; }
  .bt-pick-canvas { height: 190px; }
}

/* the attack chips: the button that does it, and the cooldown draining off */
.bt-inv .bt-atk {
  position: relative; overflow: hidden;
  width: 38px; height: 38px;
  display: grid; place-items: center; align-content: center; gap: 1px;
  border: 2.5px solid var(--ink); border-radius: 10px;
  background: #fff; font-style: normal;
}
.bt-inv .bt-atk b {
  min-width: 16px; padding: 0 3px; border-radius: 5px;
  background: var(--gold); color: var(--ink-deep);
  font: 950 10px/1.4 "Fredoka", sans-serif; text-align: center;
}
.bt-inv .bt-atk small { font: 900 6.5px/1 "Nunito", sans-serif; letter-spacing: .08em; color: var(--ink); }
.bt-inv .bt-atk .cd {
  position: absolute; left: 0; right: 0; bottom: 0;
  background: rgba(20, 52, 60, .45);
  pointer-events: none;
}
.bt-inv .bt-atk.cooling b { background: #cfd6d3; }
.bt-inv .bt-atk.spent { opacity: .4; }

/* match rules: one row of pills, one lit */
/* The two match settings share a row. Each is a label plus one choice, so
   side by side they read as a pair of dials rather than two more steps. */
.bt-settings { display: grid; grid-template-columns: 1.5fr 1fr; gap: 8px; margin-top: 8px; align-items: stretch; }
.bt-settings > .bt-rules { margin-top: 0; }
/* Label on its own line, controls beneath it: the stepper stopped fitting
   beside the mode buttons at half width and pushed the card into a scroll. */
.bt-settings > .bt-rules { display: grid; grid-template-columns: auto auto; align-content: start; row-gap: 8px; column-gap: 12px; }
.bt-settings > .bt-rules > .bt-party-label { grid-column: 1 / -1; }
@media (max-width: 780px) { .bt-settings { grid-template-columns: 1fr; } }
.bt-rules {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin-top: 14px; padding: 7px 14px;
  border: 3px dashed rgba(20,52,60,.3); border-radius: 14px;
}
.bt-rules.locked { opacity: .55; }
/* The drops row spans the settings grid and packs four labelled groups on one
   line. Everything in it is a size down from the row above: these are dials
   you set once, not the question the screen is asking. */
.bt-drops {
  grid-column: 1 / -1;
  /* one strip: the label sits inline with the groups instead of taking the
     grid's label-on-top row, and the padding is half the other boxes' - these
     are set-once dials, not the question the screen is asking */
  display: flex !important; align-items: center; gap: 14px;
  padding: 7px 14px;
}
.bt-drop-groups { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.bt-drop-group { display: flex; align-items: center; gap: 5px; }
.bt-drop-group small { font: 900 8.5px "Nunito", sans-serif; letter-spacing: .12em; color: rgba(20,52,60,.55); margin-right: 2px; }
.bt-rule.sm { padding: 5px 9px; font-size: 9px; letter-spacing: .06em; box-shadow: 0 2px 0 var(--ink-deep); border-width: 2.5px; }
.bt-rules.locked .bt-rule.sm { pointer-events: none; }
.bt-rules.locked .bt-rule { pointer-events: none; }
.bt-rule-opts { display: flex; gap: 7px; flex-wrap: wrap; }
.bt-rule {
  padding: 8px 13px; border: 3px solid var(--ink); border-radius: 999px;
  background: #fff; color: var(--ink);
  font: 950 11px "Nunito", sans-serif; letter-spacing: .08em;
  box-shadow: 0 3px 0 var(--ink-deep);
}
.bt-rule.on { background: var(--gold); }body:not(.keys-driving) .bt-rule:hover { transform: translateY(-1px); }

/* the rules amount: type it, or step it */
.bt-rule-amount { display: flex; align-items: center; gap: 7px; }
.bt-rule-amount .bt-step {
  width: 34px; height: 34px; padding: 0;
  border: 3px solid var(--ink); border-radius: 10px;
  background: var(--cream); color: var(--ink);
  font: 950 16px "Fredoka", sans-serif;
  box-shadow: 0 3px 0 var(--ink-deep);
}
#bt-rule-value {
  width: 86px; padding: 7px 4px; text-align: center;
  border: 3px solid var(--ink); border-radius: 10px;
  background: #fff; color: var(--ink);
  font: 950 17px "Fredoka", sans-serif; letter-spacing: .05em;
}
#bt-rule-hint { font: 900 8.5px "Nunito", sans-serif; letter-spacing: .12em; color: rgba(20,52,60,.55); }
.bt-rules.locked .bt-step, .bt-rules.locked #bt-rule-value { pointer-events: none; opacity: .6; }

/* the cryo vial in the pouch: frost blue */
.bt-inv .bt-wpn.cryo { border-color: #4fb6d8; background: #ecf8fd; color: #2f8fb8; }

/* ---- hands panel v2: elastic, corner-tabbed, half the footprint ----------
   Width is spent only on what the player holds. The team tab replaces the
   vertical spine; chips shrink to glance size; the keycap trio stays as the
   one constant, because the buttons never stop mattering. */
.bt-inv { gap: 6px; padding: 7px 10px; bottom: 26px; border-width: 3px; border-radius: 14px; box-shadow: 0 4px 0 var(--ink-deep); }
.bt-inv > b {
  writing-mode: horizontal-tb; transform: none;
  font-size: 9px; letter-spacing: .12em; padding: 4px 7px; border-radius: 8px;
}
.bt-inv.p1 > b { background: #2e8b7a; color: #fff; }
.bt-inv.p2 > b { background: #8e3b4a; color: #fff; }
.bt-inv span { gap: 4px; align-items: center; }
.bt-inv .bt-hand { width: 26px; height: 26px; border-width: 2px; font-size: 13px; }
.bt-inv .bt-hand img { width: 18px; height: 18px; }
.bt-count { font: 900 11px "Nunito", sans-serif; font-style: normal; color: rgba(20,52,60,.62); padding: 0 2px; }
.bt-inv .bt-sep { width: 2px; height: 24px; margin: 0 1px; }
.bt-inv .bt-wpn { width: 20px; height: 20px; border-width: 2px; font-size: 10px; }
.bt-inv .bt-atk { width: 30px; height: 34px; border-width: 2px; border-radius: 8px; }
.bt-inv .bt-atk b { min-width: 13px; padding: 0 2px; font-size: 9px; border-radius: 4px; }
.bt-inv .bt-atk small { font-size: 5.5px; letter-spacing: .04em; }
.bt-prompt { bottom: 106px; }

/* ---- hands panel v3: vertical sidebars ------------------------------------
   The floor is for playing; the edges are for carrying. Each panel is a
   column hugging its player's side of the screen — height is cheap there,
   so the chips get room back. */
.bt-inv { flex-direction: column; gap: 7px; padding: 10px 8px; bottom: auto; top: 50%; transform: translateY(-50%); }
.bt-inv.p1 { left: 12px; }
.bt-inv.p2 { right: 12px; }
.bt-inv span { flex-direction: column; gap: 5px; }
.bt-inv .bt-hand { width: 30px; height: 30px; font-size: 15px; }
.bt-inv .bt-hand img { width: 21px; height: 21px; }
.bt-inv .bt-wpn { width: 24px; height: 24px; font-size: 12px; }
.bt-inv .bt-sep { width: 26px; height: 2px; margin: 1px 0; }
.bt-inv .bt-atk { width: 36px; height: 38px; }
.bt-inv .bt-atk b { font-size: 10px; min-width: 15px; }
.bt-inv .bt-atk small { font-size: 6px; }
.bt-count { padding: 0; }
.bt-prompt { bottom: 106px; }

/* weapon counts live on their buttons: a corner badge, colored by kind */
.bt-inv .bt-atk .n {
  position: absolute; top: 1px; right: 1px;
  min-width: 13px; height: 13px; padding: 0 2px;
  border-radius: 7px; text-decoration: none;
  font: 900 9px/13px "Nunito", sans-serif; text-align: center;
  color: #fff;
}
.bt-inv .bt-atk.sal .n { background: #2f9fbf; }
.bt-inv .bt-atk.cry .n { background: #4fb6d8; }

/* ---- hands panel v4: horizontal again, bottom corners, taller -------------
   Same elastic structure — chips only for what you hold, counts on the
   buttons — but back on the floor line where the eyes already live, with
   every chip a size up. */
.bt-inv { flex-direction: row; align-items: center; top: auto; transform: none; bottom: 20px; gap: 8px; padding: 10px 12px; }
.bt-inv.p1 { left: 14px; }
.bt-inv.p2 { right: 14px; }
.bt-inv span { flex-direction: row; align-items: center; gap: 6px; }
.bt-inv .bt-hand { width: 36px; height: 36px; font-size: 17px; }
.bt-inv .bt-hand img { width: 25px; height: 25px; }
.bt-inv .bt-sep { width: 3px; height: 34px; margin: 0 2px; }
.bt-inv .bt-atk { width: 40px; height: 44px; }
.bt-inv .bt-atk b { font-size: 11px; min-width: 17px; }
.bt-inv .bt-atk small { font-size: 6.5px; }
.bt-inv .bt-atk .n { min-width: 15px; height: 15px; border-radius: 8px; font-size: 10px; line-height: 15px; }
.bt-count { font-size: 12px; }
.bt-prompt { bottom: 106px; }

/* the battle pause card's one extra line: why the clock may still be moving */
.bt-pause-note {
  margin: 0 0 4px; max-width: 34ch;
  font: 800 12px/1.5 "Nunito", sans-serif; color: rgba(20,52,60,.7);
}


/* The curtain between committing to a match and the arena existing.
   Full-bleed so nothing half-built shows through, and it names the wait
   rather than spinning: a frozen screen with no words is the thing being
   fixed here. */
#bt-curtain {
  position: fixed; inset: 0; z-index: 140;
  display: grid; place-items: center;
  background: radial-gradient(120% 100% at 50% 0%, #1d4d59 0%, #0e2b33 70%);
  animation: bt-curtain-in .16s ease-out both;
}
#bt-curtain.hidden { display: none; }
.bt-curtain-card { text-align: center; padding: 0 24px; }
.bt-curtain-card b {
  display: block; margin-bottom: 6px;
  font: 950 26px "Fredoka", sans-serif; letter-spacing: .1em; color: #eaf6f3;
}
.bt-curtain-card p {
  margin: 0; font: 700 13px "Nunito", sans-serif;
  letter-spacing: .06em; color: rgba(214, 238, 234, .68);
}
.bt-curtain-dots { display: flex; gap: 10px; justify-content: center; margin-bottom: 20px; }
.bt-curtain-dots i {
  width: 11px; height: 11px; border-radius: 50%; background: #6fd6c4;
  animation: bt-warm-step 1.05s ease-in-out infinite;
}
.bt-curtain-dots i:nth-child(2) { animation-delay: .14s; }
.bt-curtain-dots i:nth-child(3) { animation-delay: .28s; }
@keyframes bt-curtain-in { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  #bt-curtain { animation: none; }
  .bt-curtain-dots i { animation: none; }
}


/* ============================================================
   THE CLOCK-IN LOBBY
   ============================================================
   Three problems this answers: nothing said which key readied you up, the
   only clickable controls were the unimportant ones, and online play gave
   your opponent exactly as much room as your own tech even though only one
   of them is yours to change. */

/* The step spine. A genuine sequence — pick, clock in, start — so it is
   numbered; the order is information the player did not have. The guest gets
   a different third step, because starting was never theirs. */
.bt-spine { display: flex; align-items: center; justify-content: center; gap: 6px; flex-wrap: wrap; margin: 0 0 18px; }
.bt-spine.hidden { display: none; }
.bt-spine-step {
  display: flex; align-items: center; gap: 7px;
  padding: 6px 13px 6px 8px; border-radius: 999px;
  background: rgba(20, 52, 60, .07); color: rgba(20, 52, 60, .45);
  font: 800 11.5px/1 "Nunito", sans-serif; letter-spacing: .1em; text-transform: uppercase;
}
.bt-spine-step i {
  display: grid; place-items: center; width: 19px; height: 19px; border-radius: 6px;
  font: 800 10px/1 ui-monospace, Menlo, monospace; font-style: normal;
  background: rgba(20, 52, 60, .14); color: rgba(20, 52, 60, .55);
}
.bt-spine-step.now { background: var(--ink, #14343c); color: #fdf6e4; }
.bt-spine-step.now i { background: #4fb3a5; color: #14343c; }
.bt-spine-step.done { background: rgba(79, 179, 165, .2); color: #2e8b7a; }
.bt-spine-step.done i { background: #4fb3a5; color: #14343c; }
.bt-spine-arrow { color: rgba(20, 52, 60, .26); font-weight: 900; }

/* THE SIGNATURE: the key lives inside the control.
   One object answers both "what do I press" and "can I click it". The old
   screen advertised clickable arrows for browsing characters and hid the
   control that actually starts the match. */
.bt-clockin {
  display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 13px;
  width: 100%; margin-top: 10px; padding: 11px 15px;
  border: 4px solid #14343c; border-radius: 14px;
  background: #e8b64c; box-shadow: 0 5px 0 #b8862a;
  cursor: pointer; text-align: left;
  transition: transform .1s ease, box-shadow .1s ease;
}body:not(.keys-driving) .bt-clockin:hover { transform: translateY(-1px); box-shadow: 0 6px 0 #b8862a; }
.bt-clockin:active { transform: translateY(3px); box-shadow: 0 2px 0 #b8862a; }
.bt-clockin:focus-visible { outline: 3px solid #fdf6e4; outline-offset: 3px; }
.bt-keycap {
  display: grid; place-items: center; min-width: 36px; height: 36px; padding: 0 9px;
  border: 3px solid #14343c; border-radius: 9px;
  background: #fdf6e4; box-shadow: inset 0 -3px 0 rgba(20, 52, 60, .16);
  font: 800 15px/1 "Nunito", sans-serif; color: #14343c;
}
.bt-clockin-lab b {
  display: block; font: 900 14px/1.15 "Nunito", sans-serif;
  letter-spacing: .13em; text-transform: uppercase; color: #14343c;
}
.bt-clockin-lab small {
  display: block; margin-top: 3px;
  font: 700 11px/1 "Nunito", sans-serif; letter-spacing: .03em; color: rgba(20, 52, 60, .62);
}
/* the cursor walk ends on the card itself: same teal ring as every other stop */
.bt-clockin.cursor { outline: 3.5px solid var(--teal); outline-offset: 2px; }
/* Keys or a pad are driving: the pointer disappears until it moves, and every
   :hover style below is gated behind body:not(.keys-driving) so nothing glows
   under the parked, invisible pointer. VISUAL suppression only - an earlier
   version used pointer-events:none here, which also killed hit-testing, and a
   tap-to-click trackpad (no movement to wake the pointer first) lost the FIRST
   CLICK after any key press - reported in the wild as "the sound button does
   not work". Hover styles may not lie; clicks must always land. */
body.keys-driving, body.keys-driving * { cursor: none !important; }
/* the overlay walker's ring: any modal button the pad is pointing at */
.pad-ring { outline: 3.5px solid #4fb3a5 !important; outline-offset: 2px; }

.bt-setup-foot .cursor { outline: 3.5px solid var(--teal); outline-offset: 2px; }
/* clocked in: the card stamps, and says how to step back out */
.bt-clockin.on { background: #4fb3a5; box-shadow: 0 5px 0 #2e8b7a; }
.bt-clockin.on:active { box-shadow: 0 2px 0 #2e8b7a; }
.bt-clockin.on .bt-keycap { background: rgba(253, 246, 228, .94); }
.bt-clockin.on .bt-clockin-lab b { color: #06231f; }
.bt-clockin.on .bt-clockin-lab small { color: rgba(6, 35, 31, .68); }
/* an empty seat has nothing to clock in yet */
.bt-bay:not(.joined) .bt-clockin { display: none; }
/* the far seat online is a readout, never a control */
.bt-bay.mirror .bt-clockin { display: none; }

/* Online, your opponent stops getting half the screen. Your tech is the hero;
   theirs is a strip. Local co-op keeps its mirrored bays and its VS, because
   two people at one keyboard genuinely are peers — so the shape of the screen
   tells you which mode you are in. */
.bt-setup-bays.solo { grid-template-columns: 1.6fr 1fr; align-items: start; }
.bt-setup-bays.solo .bt-setup-vs { display: none; }
.bt-setup-bays.solo .bt-bay.mirror { align-self: start; }
.bt-setup-bays.solo .bt-bay.mirror .bt-bay-stage { height: 118px; }
.bt-setup-bays.solo .bt-bay.mirror .bt-pick-canvas { height: 118px; }
.bt-setup-bays.solo .bt-bay.mirror .bt-pick-name b { font-size: 19px; }
.bt-setup-bays.solo .bt-bay.mirror .bt-arrow { display: none; }

/* the ready lamp on the opponent strip: state as form, not just words */
.bt-lamp { display: inline-flex; align-items: center; gap: 7px; margin-top: 8px; }
.bt-lamp i { width: 10px; height: 10px; border-radius: 50%; background: rgba(20, 52, 60, .22); }
.bt-lamp b { font: 800 10.5px/1 "Nunito", sans-serif; letter-spacing: .14em; text-transform: uppercase; color: rgba(20, 52, 60, .45); }
.bt-lamp.on i { background: #4fb3a5; box-shadow: 0 0 0 4px rgba(79, 179, 165, .26); }
.bt-lamp.on b { color: #2e8b7a; }

/* The start button keeps one name for the whole flow; why it is unavailable
   is separate information, stated once, underneath. Previously the label WAS
   the error message, so the button kept changing its name. */
.bt-go-wrap { display: grid; gap: 6px; justify-items: center; }
.bt-go-wrap.hidden { display: none; }
.bt-blocker {
  margin: 0; min-height: 14px;
  font: 800 11.5px/1.3 "Nunito", sans-serif; letter-spacing: .05em; text-align: center;
  color: #c0603f;
}
.bt-blocker.ok { color: #2e8b7a; }

.bt-party-hint {
  margin: 10px 0 0; text-align: center;
  font: 700 12.5px/1.5 "Nunito", sans-serif; color: rgba(20, 52, 60, .6);
}

@media (prefers-reduced-motion: reduce) {
  .bt-clockin { transition: none; }body:not(.keys-driving) .bt-clockin:hover { transform: none; }
}

/* Hosting: your bay holds the left column for both rows, the opponent and the
   code you are meant to send them stack down the right. */
.bt-setup-bays.solo { grid-template-rows: auto auto; }
.bt-setup-bays.solo .bt-bay.p1 { grid-column: 1; grid-row: 1 / span 2; }
.bt-setup-bays.solo .bt-bay.mirror { grid-column: 2; grid-row: 1; }


/* Music level. Lives in menus only — never over gameplay. */
.music-row {
  /* a fixed label column, so the MUSIC and EFFECTS tracks line up */
  display: grid; grid-template-columns: 4.6em 1fr auto; align-items: center; gap: 12px;
  width: 100%; margin: 4px 0 2px; padding: 10px 14px;
  border: 3px solid rgba(253, 246, 228, .22); border-radius: 12px;
  background: rgba(8, 34, 40, .35);
}
.music-row > span {
  font: 900 11px/1 "Nunito", sans-serif; letter-spacing: .18em; color: rgba(253, 246, 228, .7);
}
.music-read {
  min-width: 42px; text-align: right;
  font: 800 12px/1 ui-monospace, Menlo, monospace; color: #6fd6c4;
  font-variant-numeric: tabular-nums;
}
.music-slider {
  -webkit-appearance: none; appearance: none;
  width: 100%; height: 8px; border-radius: 999px;
  background: rgba(253, 246, 228, .2);
  outline: none; cursor: pointer;
}
.music-slider::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 20px; height: 20px; border-radius: 50%;
  background: #4fb3a5; border: 3px solid #0e2b33;
  box-shadow: 0 2px 0 rgba(0, 0, 0, .35);
}
.music-slider::-moz-range-thumb {
  width: 20px; height: 20px; border-radius: 50%;
  background: #4fb3a5; border: 3px solid #0e2b33;
}
.music-slider:focus-visible { outline: 3px solid #6fd6c4; outline-offset: 4px; }

/* the controls panel sits on a light card, so the row inverts there */
.controls-panel .music-row { border-color: rgba(20, 52, 60, .18); background: rgba(20, 52, 60, .05); }
.controls-panel .music-row > span { color: rgba(253, 246, 228, .75); }

/* Online: the side that did not pause gets a notice, not a button. */
#bt-pause.far .pause-card > button#bt-pause-resume { display: none; }


}

/* ============================================================
   BATTLE HUD — two rows: hands above, buttons below
   ============================================================
   Defined here at the end on purpose. The panel had picked up overrides in
   several breakpoint blocks over time, each assuming a single horizontal row;
   restating the whole layout in one place is clearer than unpicking five.
   Media queries carry no extra specificity, so this wins by coming last. */
.bt-inv {
  position: fixed; bottom: 20px; z-index: 40;
  display: flex; flex-direction: column; align-items: stretch; gap: 8px;
  width: max-content;
  padding: 10px 12px;
  border: 3px solid var(--ink); border-radius: 16px;
  background: var(--cream);
  box-shadow: 0 5px 0 var(--ink-deep);
  transform: none; top: auto;
  pointer-events: none;
}
.bt-inv.p1 { left: 16px; right: auto; }
.bt-inv.p2 { right: 16px; left: auto; }
.bt-inv > span { display: flex; flex-direction: column; gap: 8px; }
.bt-inv .bt-row { display: flex; align-items: center; gap: 6px; }

/* the seat badge now rides in the hands row rather than above everything */
.bt-inv .bt-who {
  padding: 4px 7px; border-radius: 7px;
  font: 900 10px/1 "Nunito", sans-serif; letter-spacing: .12em; color: #fff;
  writing-mode: horizontal-tb; transform: none;
}
.bt-inv.p1 .bt-who { background: #2e8b7a; }
.bt-inv.p2 .bt-who { background: #8e3b4a; }

/* hands: bigger, because there is room for them once the row is its own */
.bt-inv .bt-hand {
  width: 52px; height: 52px; margin: 0;
  display: grid; place-items: center;
  border: 3px solid var(--ink); border-radius: 13px;
  font-size: 22px;
}
.bt-inv .bt-hand img { width: 38px; height: 38px; object-fit: contain; }
.bt-inv .bt-hand.empty {
  border-style: dashed; border-color: rgba(20, 52, 60, .3); background: transparent;
}
.bt-inv .bt-count {
  font: 900 13px/1 "Nunito", sans-serif; font-style: normal;
  color: rgba(20, 52, 60, .62); padding: 0 2px;
  font-variant-numeric: tabular-nums;
}

/* ── Option A: two panels turning the corner ───────────────────────────────
   The wrapper stops being a panel and becomes bare layout. Each row carries
   its own chrome instead, so hands read left to right along the bottom while
   the weapons stand vertically up the screen edge above them. The corner is
   made by alignment rather than drawn, which lets either row change length
   without the other having to be reshaped. */
.bt-inv {
  padding: 0; border: none; background: none; box-shadow: none;
  align-items: flex-start;
}
.bt-inv.p2 { align-items: flex-end; }
/* column-reverse: the markup emits hands then weapons, and this stands the
   weapons above without reordering what the game builds */
.bt-inv > span { flex-direction: column-reverse; gap: 10px; align-items: flex-start; }
.bt-inv.p2 > span { align-items: flex-end; }

.bt-inv .bt-row {
  padding: 7px 9px;
  border: 3px solid var(--ink); border-radius: 15px;
  background: var(--cream); box-shadow: 0 5px 0 var(--ink-deep);
}
/* The weapons column has no panel of its own. Each button is already a solid
   bordered chip, so wrapping the three in a second box was chrome around chrome
   and cost real screen for nothing. The hands row keeps its tray. */
.bt-inv .bt-row.wpns {
  flex-direction: column; align-items: stretch; gap: 7px;
  width: max-content;
  padding: 0; border: none; background: none; box-shadow: none;
}
/* the buttons stretched to fill when the row ran across; standing up they size
   to their content instead */
.bt-inv .bt-row.wpns .bt-atk { flex: 0 0 auto; }
/* GRAB is not part of the stack. It appears only when a press would do
   something, in its own column beside the weapons and level with the bottom
   one: to the right of the stack for P1, to the left for P2. */
.bt-inv .bt-cols { display: flex; align-items: flex-end; gap: 8px; }
.bt-inv.p2 .bt-cols { flex-direction: row-reverse; }
.bt-inv .bt-row.grabcol { padding: 0; border: none; background: none; box-shadow: none; }
.bt-inv .bt-row.grabcol .bt-atk { flex: 0 0 auto; animation: bt-grab-in .22s cubic-bezier(.2, 1.4, .4, 1) both; }
@keyframes bt-grab-in { from { opacity: 0; transform: scale(.6); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .bt-inv .bt-row.grabcol .bt-atk { animation: none; } }

/* buttons: key and word side by side, at a size you can read mid-run */
.bt-inv .bt-row.wpns { gap: 6px; }
.bt-inv .bt-atk {
  position: relative; overflow: hidden;
  flex: 1 1 0;
  display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 8px;
  width: auto; height: auto;
  padding: 7px 12px 11px 7px;
  border: 3px solid var(--ink); border-radius: 12px;
  background: var(--cream);
}
.bt-inv .bt-atk .bt-cap {
  display: grid; place-items: center;
  min-width: 32px; height: 30px; padding: 0 6px;
  border: 3px solid var(--ink); border-radius: 9px;
  background: var(--cream);
  box-shadow: inset 0 -3px 0 rgba(20, 52, 60, .16);
  font: 800 16px/1 "Nunito", sans-serif; color: var(--ink);
}
.bt-inv .bt-atk .bt-lab {
  font: 900 11px/1 "Nunito", sans-serif; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink); text-align: left;
}
/* push is the one always available, so it carries the accent */
.bt-inv .bt-atk.push { background: var(--amber, #e8b64c); }
/* ---- GRAB: the top of the stack, always ---------------------------------------
   The one button whose meaning changes with where you stand, so it says what
   it will do. Lit: gold, the cap pulsing, the action in the label. Idle: cream,
   the NEXT step written where the action would be, in a quieter weight. The
   second line (where to go, how many, the tray-first warning) sits under it. */
.bt-inv .bt-atk.grab { grid-template-columns: auto minmax(0, 1fr); min-width: 0; max-width: 190px; }
/* the label is a flex row elsewhere, which put the second line beside the first
   and stretched the whole column to 300px; here it stacks */
.bt-inv .bt-atk.grab .bt-lab { display: flex; flex-direction: column; align-items: flex-start; gap: 0; }
.bt-inv .bt-atk.grab .bt-lab small { white-space: normal; text-align: left; }
.bt-inv .bt-atk.grab::before { background: var(--gold); }
.bt-inv .bt-atk.grab.lit { background: var(--gold); border-color: var(--ink); }
.bt-inv .bt-atk.grab.lit .bt-cap { animation: keycap-pulse 1s ease-in-out infinite alternate; }
.bt-inv .bt-atk.grab.lit .bt-lab { color: var(--ink-deep); }
.bt-inv .bt-atk.grab.idle { background: var(--cream); }
.bt-inv .bt-atk.grab.idle::after {
  content: "NEXT"; position: absolute; right: 8px; top: -9px;
  padding: 2px 6px 1px; border-radius: 6px 6px 3px 3px;
  background: var(--gold); color: var(--ink-deep); border: 2px solid var(--ink);
  font: 900 8px/1 "Nunito", sans-serif; letter-spacing: .22em;
}
.bt-inv .bt-atk.grab.idle .bt-lab { color: var(--ink); font-weight: 900; }
.bt-inv .bt-atk.grab.idle .bt-cap { filter: saturate(.6) brightness(.96); }
.bt-inv .bt-atk .bt-lab small {
  display: block; margin-top: 3px;
  font: 900 8.5px/1.1 "Nunito", sans-serif; letter-spacing: .12em; color: rgba(20, 52, 60, .62);
}
.bt-inv .bt-atk .bt-lab small.warn { color: #b84a3e; }
body.cabinet .bt-inv .bt-atk.grab { min-width: 0; max-width: 250px; }
body.cabinet .bt-inv .bt-atk .bt-lab small { font-size: 11px; }
body.cabinet .bt-inv .bt-atk.grab.idle::after { font-size: 10px; top: -11px; }
/* Spent: still legible, plainly empty. Fading the whole chip to 45% left the
   label unreadable at the exact moment you want to know which button is out. */
.bt-inv .bt-atk.spent { opacity: .82; border-style: dashed; background: #eef1f0; }
.bt-inv .bt-atk.spent .bt-lab { color: rgba(20, 52, 60, .5); text-decoration: line-through; text-decoration-thickness: 2px; }
/* The disc keeps its colour when spent. It is the colour of the physical cap
   under the player's hand, and a grey cryo button on screen next to a red one
   on the panel reads as a different button. Spent is the dashed chip and the
   struck-through word, nothing more. */
.bt-inv .bt-atk.cooling .bt-cap { background: #cfd6d3; }
/* Each weapon wears its own colour down the left edge - the colour of the thing
   it does in the room (the glove, the bag, the vial) - so the three chips are
   told apart by shape AND colour rather than by reading three words. */
.bt-inv .bt-atk { border-radius: 14px; box-shadow: 0 4px 0 var(--ink-deep); }
.bt-inv .bt-atk::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 6px;
  background: #4f86d8;
}
.bt-inv .bt-atk.sal::before { background: #2f9fbf; }
.bt-inv .bt-atk.cry::before { background: #4fb6d8; }
.bt-inv .bt-atk.spent::before { background: #b9c2c6; }
.bt-inv .bt-atk .bt-lab { font-size: 12px; letter-spacing: .12em; padding-left: 2px; }
.bt-inv .bt-atk .bt-cap { box-shadow: inset 0 -3px 0 rgba(20, 52, 60, .16), 0 2px 0 rgba(20, 52, 60, .12); }
.bt-inv .bt-atk .cd { background: #4f86d8; opacity: .55; }
/* On the cabinet the cap holds an arcade disc rather than a letter. The chip's
   own box and border would frame it like a dot in a square, so it steps aside
   and lets the button be the button. */
.bt-inv .bt-atk .bt-cap:has(.cab-btn) { background: none; border: 0; padding: 0; min-width: 0; height: auto; box-shadow: none; }
.bt-inv .bt-atk .bt-cap .cab-btn { font-size: 30px; }
.bt-inv .bt-atk.cooling .bt-cap:has(.cab-btn) { background: none; }   /* the bar says cooling; the disc keeps its colour */
.bt-keycap:has(.cab-btn) { background: none; border: 0; box-shadow: none; padding: 0; min-width: 0; }
/* The cooldown fills the whole face of the button and drains away from the
   right, so you can see from across the room how long until the next shove.
   The disc and the word sit above the tint and stay readable throughout. */
.bt-inv .bt-atk .cd {
  position: absolute; left: 0; top: 0; bottom: 0;
  height: auto; background: var(--ink); opacity: .32;
  border-radius: 0; transition: width .12s linear;
}
.bt-inv .bt-atk .bt-cap, .bt-inv .bt-atk .bt-lab, .bt-inv .bt-atk .n { position: relative; z-index: 1; }
.bt-inv .bt-atk .n { position: absolute; }
.bt-inv .bt-atk.cooling .bt-lab { color: var(--ink); }
/* Charges as a lit strip along the foot of the button, not a floating badge.
   You can never hold more than two, so the count does not need reading: half
   the width is one, the full width is two, and the notch in the middle keeps
   them countable rather than just "more". It also stops a bright dot fighting
   the keycap for the same corner. */
.bt-inv .bt-atk .n {
  position: absolute; left: 0; bottom: 0; top: auto; right: auto;
  height: 7px; width: 50%;
  min-width: 0; padding: 0; border-radius: 0;
  text-decoration: none;
  font-size: 0; line-height: 0; color: transparent;
}
.bt-inv .bt-atk .n[data-n="2"] { width: 100%; }
/* the notch: only earns its place once both charges are lit */
.bt-inv .bt-atk .n[data-n="2"]::after {
  content: ""; position: absolute; top: 0; bottom: 0;
  left: calc(50% - 1.5px); width: 3px; background: var(--cream);
}
.bt-inv .bt-atk.sal .n { background: #2f9fbf; }
.bt-inv .bt-atk.cry .n { background: #4fb6d8; }

.bt-inv .bt-hand.received-item { animation: inventory-receive .34s cubic-bezier(.2,.9,.3,1.4); }

/* short windows: give the height back before anything is allowed to overlap */
@media (max-height: 720px) {
  .bt-inv { gap: 6px; padding: 8px 10px; bottom: 14px; }
  .bt-inv .bt-hand { width: 42px; height: 42px; border-radius: 11px; }
  .bt-inv .bt-hand img { width: 30px; height: 30px; }
  .bt-inv .bt-atk { padding: 5px 9px 9px 5px; }
  .bt-inv .bt-atk .bt-cap { min-width: 27px; height: 26px; font-size: 14px; }
  .bt-inv .bt-atk .bt-lab { font-size: 9.5px; }
}

/* ============================================================
   LEADERBOARD — initials entry, in the cabinet idiom
   ============================================================ */
/* The final step IS the scoreboard: the standings cabinet overlaid on the
   game, the backdrop translucent so the pharmacy stays visible behind it,
   the big OverStocked wordmark with HIGH SCORES beneath. */
.lb-entry.board-mode { background: rgba(8, 24, 29, .58); backdrop-filter: blur(1.5px); }
/* opened from the main menu there is no game behind the glass - hang the
   board over the pharmacy photo instead of the menu screen */
.lb-entry.browse {
  background:
    linear-gradient(rgba(8, 24, 29, .66), rgba(8, 24, 29, .66)),
    url("../../leaderboard/room.jpg?v=1") center / cover no-repeat #0e2b33;
  backdrop-filter: none;
}
.lb-entry.board-mode .lb-card {
  width: min(880px, 94vw); max-height: 94vh; overflow-y: auto;
  background: transparent; border: 0; box-shadow: none; padding: 10px;
}
.lb-logo { width: min(430px, 72vw); display: block; margin: 0 auto 2px;
  filter: drop-shadow(0 6px 18px rgba(4, 16, 20, .5)); }
.lb-board-title {
  margin: 0 0 14px;
  font: 600 clamp(20px, 3.4vw, 30px)/1 "Fredoka", sans-serif;
  letter-spacing: .24em; color: var(--cream);
  text-shadow: 0 2px 0 rgba(8, 24, 29, .6);
}
.lb-entry.board-mode #lb-placed { color: var(--cream); text-shadow: 0 2px 0 rgba(8,24,29,.55); }
.lb-entry.board-mode .lb-note { color: rgba(253, 246, 228, .75); }
.lb-entry.board-mode .lb-note a { color: #7fd6c6; }
/* the view toggle: same pill tabs the standings page used to carry */
.lb-tabs { display: flex; justify-content: center; gap: 8px; margin: 0 0 12px; }
.lb-tab {
  padding: 8px 16px; border: 3px solid rgba(253, 246, 228, .35); border-radius: 999px;
  background: transparent; box-shadow: none; color: rgba(253, 246, 228, .8);
  font: 900 10.5px/1 "Nunito", sans-serif; letter-spacing: .12em; cursor: pointer;
}
.lb-tab:hover { transform: none; box-shadow: none; background: rgba(253, 246, 228, .12); }
.lb-tab.on { background: var(--cream); border-color: var(--cream); color: var(--ink); }
/* full standings: one deck, every row, scrolling inside the cabinet */
.lb-duo.full { grid-template-columns: 1fr; }
.lb-duo .lb-deck > div { max-height: 46vh; overflow-y: auto; }
/* the cabinet, in the standings page's own chrome */
.lb-duo {
  display: grid; grid-template-columns: 1.15fr 1fr;
  border: 4px solid var(--ink); border-radius: 18px; overflow: hidden;
  background: var(--cream); color: var(--ink); text-align: left;
  box-shadow: 0 8px 0 var(--ink-deep), 0 20px 44px rgba(0, 0, 0, .35);
}
.lb-duo .lb-deck { min-width: 0; }
.lb-duo .lb-deck + .lb-deck { border-left: 4px solid var(--ink); }
.lb-deckhead {
  background: var(--ink); color: var(--cream); padding: 8px 15px;
  font: 900 10px/1 "Nunito", sans-serif; letter-spacing: .2em;
}
.lb-r {
  display: grid; grid-template-columns: 32px minmax(0, 1fr) auto;
  column-gap: 12px; align-items: baseline; padding: 7px 15px;
  border-bottom: 2px solid rgba(20, 52, 60, .09);
}
.lb-r:last-child { border-bottom: 0; }
.lb-rk { font: 600 14px "Fredoka", sans-serif; color: rgba(20, 52, 60, .5); }
.lb-r.top .lb-rk, .lb-r.top .lb-sc { color: #b8862a; }
.lb-who { min-width: 0; }
.lb-who b { display: block; font: 600 20px/1.05 "Fredoka", sans-serif; letter-spacing: .12em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lb-who small { display: block; font: 800 9.5px/1.3 "Nunito", sans-serif; color: rgba(20, 52, 60, .5); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lb-sc { font: 600 20px/1.05 "Fredoka", sans-serif; text-align: right; font-variant-numeric: tabular-nums; }
.lb-carts { display: block; font: 800 9px/1.3 "Nunito", sans-serif; letter-spacing: .12em; opacity: .55; }
.lb-chip {
  display: inline-grid; place-items: center; width: 22px; height: 22px;
  border: 2.5px solid var(--ink); border-radius: 7px; background: #fff;
  font: 800 9.5px/1 "Nunito", sans-serif; align-self: center;
}
.lb-spots { font: 600 15px/1 "Fredoka", sans-serif; color: #2e8b7a; text-align: right; }
.lb-empty { padding: 26px 16px; text-align: center; color: rgba(20, 52, 60, .5); font: 800 12px "Nunito", sans-serif; }
.lb-gap { text-align: center; color: rgba(20, 52, 60, .4); padding: 2px 0; }
/* the player's own row glows on the board */
.lb-r.me { background: rgba(79, 179, 165, .16); box-shadow: inset 3px 0 0 #2e8b7a; }
@media (max-width: 640px) {
  .lb-duo { grid-template-columns: 1fr; }
  .lb-duo .lb-deck + .lb-deck { border-left: 0; border-top: 4px solid var(--ink); }
}

.lb-entry {
  position: fixed; inset: 0; z-index: 150;
  display: grid; place-items: center;
  background: rgba(8, 24, 29, .55);
}
.lb-entry.hidden { display: none; }
.lb-card {
  width: min(480px, 92vw);
  padding: 26px 28px 24px;
  border: 4px solid var(--ink); border-radius: 20px;
  background: var(--cream);
  box-shadow: 0 8px 0 var(--ink-deep), 0 20px 44px rgba(8, 24, 29, .4);
  text-align: center;
}
.lb-kicker {
  display: block; margin-bottom: 6px;
  font: 900 11px/1 "Nunito", sans-serif; letter-spacing: .26em; color: #2e8b7a;
}
.lb-card h2 { margin: 0 0 18px; font: 600 26px/1.1 "Fredoka", sans-serif; color: var(--ink); }
.lb-slots { display: flex; justify-content: center; gap: 12px; margin-bottom: 16px; }
.lb-slot {
  width: 74px; height: 88px;
  display: grid; place-items: center;
  border: 4px solid rgba(20, 52, 60, .3); border-radius: 14px;
  background: #fff;
  font: 600 46px/1 "Fredoka", sans-serif; color: var(--ink);
}
.lb-slot.on {
  border-color: var(--ink);
  background: var(--amber, #e8b64c);
  box-shadow: 0 4px 0 #b8862a;
  animation: lb-blink 1.1s ease-in-out infinite;
}
@keyframes lb-blink { 50% { box-shadow: 0 4px 0 #b8862a, 0 0 0 5px rgba(232, 182, 76, .35); } }
.lb-hint { margin: 0; font: 800 12px/1.6 "Nunito", sans-serif; color: rgba(20, 52, 60, .55); }
.lb-hint b {
  display: inline-grid; place-items: center; min-width: 20px; height: 20px; padding: 0 4px;
  border: 2px solid var(--ink); border-radius: 6px; background: #fff;
  font-size: 11px; color: var(--ink);
}
.lb-note { min-height: 18px; margin: 10px 0 0; font: 800 12.5px/1.5 "Nunito", sans-serif; color: #c0603f; }
.lb-note a { color: #2e8b7a; }

.lb-skip {
  width: 100%; padding: 12px;
  border: 3px solid var(--ink); border-radius: 12px;
  background: var(--teal, #4fb3a5); box-shadow: 0 4px 0 #2e8b7a;
  font: 900 12.5px/1 "Nunito", sans-serif; letter-spacing: .1em; color: #06231f;
  cursor: pointer;
}body:not(.keys-driving) .lb-skip:hover { transform: translateY(-1px); }
.lb-skip:focus-visible { outline: 3px solid var(--ink); outline-offset: 3px; }
#lb-placed { font-size: 30px; }
@media (prefers-reduced-motion: reduce) { .lb-slot.on { animation: none; } }

/* the board, shown in the entry panel the moment a score lands.
   Same stock-level fill as the standings page: the row itself is the bar, so
   the span between initials and score carries the gap instead of sitting empty. */
.lb-board {
  max-height: 262px; overflow-y: auto;
  width: max-content; max-width: 100%; margin: 4px auto 12px;
  border: 3px solid var(--ink); border-radius: 12px;
  background: #fff;
  text-align: left;
}
.lb-row {
  /* fixed columns so the digits line up down the board */
  display: grid; grid-template-columns: 34px minmax(0, 96px) minmax(74px, auto);
  align-items: baseline; column-gap: 14px; justify-content: start;
  padding: 7px 14px;
  border-bottom: 2px solid rgba(20, 52, 60, .08);
}
.lb-row:last-child { border-bottom: 0; }
.lb-rank { font: 600 14px/1 "Fredoka", sans-serif; color: rgba(20, 52, 60, .5); }
.lb-who { font: 600 19px/1 "Fredoka", sans-serif; letter-spacing: .16em; color: var(--ink); }
.lb-sc { font: 600 19px/1 "Fredoka", sans-serif; text-align: right; color: var(--ink); font-variant-numeric: tabular-nums; }
/* your own run, picked out */
.lb-row.me {
  background: rgba(79, 179, 165, .1);
  box-shadow: inset 3px 0 0 #2e8b7a, inset -3px 0 0 #2e8b7a;
}
.lb-row.me .lb-who { color: #2e8b7a; }
.lb-row.me .lb-who::after {
  content: "YOU"; margin-left: 8px;
  font: 900 8.5px/1 "Nunito", sans-serif; letter-spacing: .16em;
  color: #fff; background: #2e8b7a; padding: 3px 5px; border-radius: 5px;
  vertical-align: middle; letter-spacing: .1em;
}
.lb-gap { padding: 4px 0; text-align: center; color: rgba(20, 52, 60, .35); letter-spacing: .3em; }


/* the two ways out of a signed arcade run, side by side under the board */
.lb-done-actions { display: flex; gap: 10px; justify-content: center; margin-top: 14px; }
.lb-done-actions .lb-go {
  padding: 10px 18px; border: 3px solid var(--ink); border-radius: 12px;
  background: #e8b64c; color: var(--ink);
  font: 900 13px/1 "Fredoka", "Nunito", sans-serif; letter-spacing: .06em;
  cursor: pointer; box-shadow: 0 4px 0 var(--ink-deep);
}
.lb-done-actions .lb-skip { margin-top: 0; }


/* the warm-up prompt: sits above the hands panel, out of the play area */
.ready-note {
  position: fixed; left: 50%; bottom: 118px; transform: translateX(-50%);
  z-index: 30; margin: 0; padding: 9px 18px;
  border: 3px solid var(--ink); border-radius: 999px;
  background: var(--ink); color: #ffd76b;
  font: 900 14px/1 "Fredoka", "Nunito", sans-serif; letter-spacing: .08em;
  box-shadow: 0 5px 0 var(--ink-deep);
  pointer-events: none;
}


/* warm-up: the clock slot carries a state instead of a time, so it is sized and
   coloured as a label rather than shrinking a number to fit */
#bt-clock.bt-clock-free {
  font-size: 15px; letter-spacing: .14em;
  color: #14343c; background: #f2c230;
  padding: 6px 12px; border-radius: 999px;
}

/* ==== touch controls (feature/touch-controls) ============================
   Visible only on touch devices during play. Big, translucent, thumb-sized,
   clear of the notch and the home bar via safe-area insets. */
.touch-ui { position: fixed; inset: 0; z-index: 120; pointer-events: none; }
.touch-ui.hidden { display: none; }
/* The stick floats: the whole left half of the screen is the touch zone and
   the stick appears UNDER the thumb, so nothing sits on the pharmacy while
   idle. It fades in on touch and vanishes on release. */
.touch-zone {
  position: absolute; left: 0; top: 15%; bottom: 0; width: 45%;
  pointer-events: auto; touch-action: none;
}
.touch-stick {
  position: absolute; width: 96px; height: 96px; border-radius: 50%;
  margin: -48px 0 0 -48px;
  background: rgba(20, 52, 60, .22);
  border: 2px solid rgba(253, 246, 228, .35);
  opacity: 0; transition: opacity .12s ease;
  pointer-events: none;
}
.touch-stick.live { opacity: 1; }
.touch-stick-nub {
  position: absolute; left: 50%; top: 50%; width: 42px; height: 42px;
  margin: -21px 0 0 -21px; border-radius: 50%;
  background: rgba(253, 246, 228, .75);
  border: 2px solid rgba(20, 52, 60, .8);
}
.touch-act {
  position: absolute;
  right: calc(18px + env(safe-area-inset-right, 0px));
  bottom: calc(64px + env(safe-area-inset-bottom, 0px));
  width: 66px; height: 66px; border-radius: 50%;
  background: rgba(242, 194, 48, .55); color: rgba(20, 52, 60, .85);
  border: 3px solid rgba(20, 52, 60, .55);
  font: 900 13px "Fredoka", sans-serif; letter-spacing: .05em;
  pointer-events: auto; touch-action: manipulation;
}
.touch-act:active { background: rgba(242, 194, 48, .95); transform: scale(.94); }
.touch-pause {
  position: absolute;
  top: calc(14px + env(safe-area-inset-top, 0px));
  right: calc(14px + env(safe-area-inset-right, 0px));
  width: 46px; height: 46px; border-radius: 12px;
  background: rgba(20, 52, 60, .35); color: rgba(253, 246, 228, .8);
  border: 2px solid rgba(253, 246, 228, .35);
  font: 900 15px "Nunito", sans-serif; letter-spacing: .1em;
  pointer-events: auto; touch-action: manipulation;
}

/* phone-landscape compact HUD: the cards, tray and clock were sized for a
   desktop; on a 390pt-tall screen they ate the pharmacy */
@media (max-width: 920px) and (max-height: 500px) {
  #orders { transform: scale(.62); transform-origin: top left; }
  #inventory-panel { transform: scale(.7); transform-origin: bottom left; }
  #timer-panel { transform: scale(.68); transform-origin: bottom right; }
  #coin-panel { transform: scale(.7); transform-origin: bottom right; }
  .player-guide { transform: scale(.72); transform-origin: top left; }
  .touch-act { width: 60px; height: 60px; font-size: 12px; }
}

/* portrait on a touch device: ask for the turn rather than squeezing */
.rotate-note { display: none; }
@media (orientation: portrait) and (pointer: coarse) {
  .rotate-note {
    position: fixed; inset: 0; z-index: 400;
    display: grid; place-content: center; justify-items: center; gap: 10px;
    background: #14343c; color: #fdf6e4; text-align: center;
  }
  .rotate-note b { font: 700 64px/1 "Fredoka", sans-serif; animation: rotate-nudge 1.6s ease-in-out infinite; }
  .rotate-note span { font: 700 24px "Fredoka", sans-serif; letter-spacing: .04em; }
  .rotate-note small { font: 800 12px "Nunito", sans-serif; color: rgba(253,246,228,.65); letter-spacing: .12em; }
}
@keyframes rotate-nudge { 0%, 100% { transform: rotate(0deg); } 50% { transform: rotate(-90deg); } }
@media (prefers-reduced-motion: reduce) { .rotate-note b { animation: none; } }

/* ==== phone-landscape menu pass ==========================================
   The in-game HUD compacts above; these are the SCREENS - title, mode cards,
   builder, boards, pause - which were desktop-sized and did not fit a 390pt
   phone at all. zoom scales layout and hit targets together and leaves the
   transform-based show/hide transitions alone. */
@media (max-height: 520px) {
  .mode-select { zoom: .58; }
  .entry-hero { zoom: .8; }
  .character-select { min-height: 0; }
  .character-panel { zoom: .68; }
  .controls-panel { zoom: .7; }
  .pause-menu { zoom: .75; }
  #results { zoom: .66; }
  .lb-entry .lb-card { zoom: .6; }
  .bt-setup { zoom: .55; }
}
html, body { overscroll-behavior: none; }

/* ---- menu footer: CONTROLS and SOUND side by side ------------------------
   The sound toggle used to sit on the title screen where there is no music
   playing yet, so pressing it appeared to do nothing. It lives with the
   other setting now, and joins the same cursor ring the cards use. */
.menu-foot { display: flex; gap: 10px; justify-content: center; align-items: stretch; margin-top: 18px; }
.menu-foot .controls-link { margin-top: 0; }
.menu-foot .entry-sound {
  /* the base rule pins it to a screen corner; inside the menu's transformed
     box that corner was the LEADERBOARD card's, so it sat on top of the card
     with its padding crushed. In the footer it is an ordinary flex item. */
  position: static; right: auto; bottom: auto;
  display: inline-flex; align-items: center; gap: 9px;
  margin: 0; padding: 9px 18px 9px 14px; border-radius: 999px;
  border: 2px solid rgba(255,246,229,.4); background: rgba(255,246,229,.06);
  color: #cfe7e2; font: 900 11px "Nunito", sans-serif; letter-spacing: .14em;
  box-shadow: none; animation: none;
}
body:not(.keys-driving) .menu-foot .entry-sound:hover { background: rgba(255,246,229,.14); transform: none; box-shadow: none; }
.entry-sound.active { color: #6fd0bf; outline: 3px solid rgba(111, 208, 191, .55); outline-offset: 4px; }

/* ---- initials: SUBMIT is its own press ---------------------------------- */
.lb-submit {
  display: block; margin: 0 auto 12px; padding: 10px 30px; border-radius: 12px;
  border: 3px solid rgba(253,246,228,.35); background: rgba(253,246,228,.08);
  color: rgba(253,246,228,.55); font: 900 12px "Nunito", sans-serif; letter-spacing: .16em;
  box-shadow: none; transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.lb-submit.ready {
  background: #4fb3a5; border-color: #fdf6e4; color: #0b232a;
  box-shadow: 0 5px 0 #2e8b7a;
}
body:not(.keys-driving) .lb-submit.ready:hover { background: #63c9a0; }

/* The cabinet HUD is drawn for a 1920x1080 screen. On any other size the
   pieces along the bottom scale with the picture (cabinet.js sets --cab-hud
   from the viewport) so they cover the same slice of the room everywhere. */
body.cabinet .bt-inv, body.cabinet .bt-prompt, body.cabinet .bt-hud, body.cabinet .bt-controls,
body.cabinet .interaction-prompt, body.cabinet .next-action, body.cabinet .grab-sticker,
body.cabinet .restock-chip, body.cabinet .waste-chip { zoom: var(--cab-hud, 1); }
/* ==== cabinet mode (feature/cabinet) =======================================
   The booth build. Hides every web-only surface, hides the cursor, and lays
   the attract overlay over the live room. */
body.cabinet, body.cabinet * { cursor: none !important; }
body.cabinet #game-entry, body.cabinet #touch-ui, body.cabinet #rotate-note,
body.cabinet .lb-done-actions, body.cabinet .lb-tabs, body.cabinet #lb-placed-note, body.cabinet #bt-build { display: none !important; }
/* the cabinet has its own panel: no keyboard legends or prompt strips along the bottom, in either mode */
body.cabinet #bt-controls, body.cabinet #player-guide { display: none !important; }
/* nothing developer-facing, and the START calls replace the result buttons */
body.cabinet .opdev-root, body.cabinet #bt-rematch, body.cabinet #bt-exit, body.cabinet #bt-pause { display: none !important; }
/* after a shift the board gets a calm, solid ground so it can be read */
body.cabinet .lb-entry.board-mode { background: rgba(8,24,29,.82); backdrop-filter: blur(3px); }
body.cabinet .lb-entry.board-mode .lb-card { padding-bottom: calc(40px + 9.5vw); }
#cab { position: fixed; inset: 0; z-index: 200; pointer-events: none; font-family: "Nunito", sans-serif; }
#cab .hidden { display: none !important; }
.cab-veil { position: absolute; inset: 0; background: rgba(8, 24, 29, .62); transition: background .5s ease, opacity .5s ease; }
#cab .cab-veil.hidden { display: block !important; opacity: 0; }   /* hidden means faded out, not gone */
/* over the demos: a lighter shade, so the play still reads while the text on top owns the screen */
.cab-veil.demo { background: rgba(8, 24, 29, .42); }
.cab-slide { position: absolute; inset: 0; display: grid; place-content: center; justify-items: center; gap: 14px; text-align: center; padding: 40px; animation: cab-fade .4s ease; }
@keyframes cab-fade { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.cab-brand { width: clamp(150px, 16vw, 320px); height: auto; filter: drop-shadow(0 4px 0 rgba(0,0,0,.35)); }
.cab-presents { font: 900 12px/1 "Nunito", sans-serif; letter-spacing: .32em; color: #63c9a0; }
.cab-wordmark { width: min(720px, 72vw); filter: drop-shadow(0 8px 0 rgba(0,0,0,.35)); }
.cab-line { font: 900 12px/1.6 "Nunito", sans-serif; letter-spacing: .22em; color: rgba(253,246,228,.75); max-width: 720px; }
/* the two START calls are the loudest thing on the screen: readable from the
   far side of a trade-show aisle, one per seat, seat-coloured */
.cab-starts { position: absolute; left: 0; right: 0; bottom: 26px; display: flex; justify-content: center; gap: clamp(20px, 3vw, 56px); font: 700 clamp(34px, 5.2vw, 92px)/1 "Fredoka", sans-serif; letter-spacing: .03em; color: #fdf6e4; flex-wrap: wrap; padding: 0 16px; }
/* during attract the empty inventory tray and the coin counter step aside
   so the prompts own the bottom edge; the clock stays as part of the show */
body.cabinet.attract #inventory-panel, body.cabinet.attract #coin-panel, body.cabinet.attract #player-guide { display: none !important; }
body.cabinet.attract #timer-panel { transform: scale(.8); transform-origin: bottom right; }
.cab-starts > span { display: flex; align-items: center; gap: .3em; padding: .28em .55em; border-radius: 999px; background: rgba(8,24,29,.82); border: .09em solid rgba(253,246,228,.35); box-shadow: 0 .14em 0 rgba(0,0,0,.45); animation: cab-blink 1.1s steps(1, end) infinite; transition: box-shadow .15s ease, border-color .15s ease; text-shadow: 0 .06em 0 rgba(0,0,0,.5); }
.cab-starts > span > span { display: block; text-align: left; white-space: nowrap; }
.cab-starts > span br { display: none; }
.cab-starts small { display: block; font: 900 .3em/1 "Nunito", sans-serif; letter-spacing: .26em; opacity: .8; margin-top: .25em; }
.cab-starts .p1 { border-color: #6fd6a8; } .cab-starts .p2 { border-color: #f2938f; }
.cab-starts i { width: .5em; height: .5em; flex: none; border-radius: 50%; border: .07em solid #0b232a; }
.cab-starts .p1 i { background: #6fd6a8; } .cab-starts .p2 i { background: #f2938f; }
.cab-starts.nudge > span { animation: none; border-color: #f2c230; box-shadow: 0 0 0 .12em rgba(242,194,48,.3); }
@keyframes cab-blink { 50% { opacity: .18; } }
.cab-caption { position: absolute; left: 50%; top: 12%; transform: translateX(-50%); background: #fdf6e4; color: #14343c; border: 3px solid #0b232a; border-radius: 14px; padding: 12px 24px; font: 600 clamp(18px, 2.4vw, 28px)/1.15 "Fredoka", sans-serif; box-shadow: 0 6px 0 #0b232a; max-width: 84vw; text-align: center; animation: cab-fade .25s ease; }
.cab-caption b { color: #b8862a; }
.cab-tag { position: absolute; left: 50%; bottom: calc(40px + 9.5vw); transform: translateX(-50%); max-width: 86vw; text-align: center; line-height: 1.5; font: 900 11px/1 "Nunito", sans-serif; letter-spacing: .24em; color: rgba(253,246,228,.75); background: rgba(8,24,29,.6); padding: 8px 14px; border-radius: 8px; }
.cab-continue { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); text-align: center; background: rgba(8,24,29,.86); border: 4px solid #f2c230; border-radius: 22px; padding: 26px 44px; box-shadow: 0 10px 0 #0b232a; }
.cab-cont-q { font: 900 13px/1 "Nunito", sans-serif; letter-spacing: .3em; color: #63c9a0; }
.cab-cont-n { font: 700 140px/1 "Fredoka", sans-serif; color: #f2c230; text-shadow: 0 8px 0 rgba(0,0,0,.4); }
.cab-cont-h { font: 700 30px/1 "Fredoka", sans-serif; color: #fdf6e4; animation: cab-blink 1.1s steps(1, end) infinite; }
@media (prefers-reduced-motion: reduce) { .cab-starts > span, .cab-cont-h { animation: none; } }


/* GET READY: the handoff card between the pick and the run */
.cab-vs { display: flex; align-items: center; justify-content: center; gap: .5em; flex-wrap: wrap; margin: 18px 0 22px; font: 700 clamp(26px, 3.6vw, 64px)/1 "Fredoka", sans-serif; color: #fdf6e4; text-shadow: 0 .08em 0 rgba(0,0,0,.45); }
.cab-vs em { font-style: normal; color: #f2c230; font-size: .7em; }
.cab-vs-tech { padding: .22em .5em; border-radius: 999px; border: .08em solid var(--outfit, #4fb3a5); background: rgba(8,24,29,.7); white-space: nowrap; }
.cab-vs-tech.p1 { box-shadow: 0 0 0 .12em rgba(111,214,168,.35); } .cab-vs-tech.p2 { box-shadow: 0 0 0 .12em rgba(242,147,143,.35); }

/* the attract board: a marquee title and a ranked list rolling up on a loop */
.cab-board { position: absolute; inset: 0; display: grid; grid-template-rows: auto 1fr; justify-items: center; padding: 3vh 4vw calc(60px + 9.5vw); overflow: hidden; }
.cab-board::before { content: ""; position: absolute; inset: -40%; z-index: -1; background: repeating-linear-gradient(-32deg, transparent 0 46px, rgba(242,194,48,.06) 46px 92px); animation: cab-crawl 9s linear infinite; }
.cab-board-head { text-align: center; display: grid; justify-items: center; gap: .6vh; }
.cab-board-mark { width: clamp(180px, 22vw, 420px); filter: drop-shadow(0 6px 0 rgba(0,0,0,.35)); }
.cab-board-head h2 { margin: 0; font: 700 clamp(44px, 7vw, 110px)/1 "Fredoka", sans-serif; color: #fdf6e4; letter-spacing: .04em; text-shadow: 5px 5px 0 #14343c, 0 12px 0 rgba(0,0,0,.35); animation: cab-breathe 2.4s ease-in-out infinite; }
.cab-board-head h2 em { font-style: normal; color: #f2c230; }
.cab-board-sub { font: 700 clamp(16px, 1.9vw, 30px)/1 "Fredoka", sans-serif; letter-spacing: .12em; color: #63c9a0; text-shadow: 3px 3px 0 #14343c; animation: cab-blink 1.1s steps(1, end) infinite; }
.cab-board-sub b { color: #f2c230; }
/* the roll: the list twice over, translated by half its height, so it never shows a seam */
.cab-board-roll { position: relative; width: min(880px, 70vw); min-height: 0; overflow: hidden; margin-top: 1.5vh;
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 12%, #000 88%, transparent 100%); mask-image: linear-gradient(180deg, transparent 0, #000 12%, #000 88%, transparent 100%); }
.cab-board-roll ol { list-style: none; margin: 0; padding: 14vh 0 0; animation: cab-roll linear infinite; }
@keyframes cab-roll { to { transform: translateY(-50%); } }
.cab-board-roll li { display: grid; grid-template-columns: 2.2em 3.2em 1fr auto; align-items: baseline; gap: .6em; padding: .28em .8em; font: 700 clamp(22px, 2.6vw, 42px)/1.15 "Fredoka", sans-serif; color: #fdf6e4; text-shadow: 3px 3px 0 #14343c; font-variant-numeric: tabular-nums; letter-spacing: .04em; }
.cab-board-roll li:nth-child(even) { background: rgba(253,246,228,.04); border-radius: 12px; }
.cab-board-roll .rk { color: rgba(253,246,228,.55); font-size: .7em; }
.cab-board-roll .rk::before { content: "#"; opacity: .6; }
.cab-board-roll .ini { letter-spacing: .12em; }
.cab-board-roll .sc { text-align: right; color: #f2c230; }
.cab-board-roll .ct { font: 900 .36em/1 "Nunito", sans-serif; letter-spacing: .24em; color: #7fd4b2; min-width: 5.5em; text-align: right; }
.cab-board-roll li.top .ini, .cab-board-roll li.top .sc { font-size: 1.15em; }
.cab-board-roll li.t1 .ini, .cab-board-roll li.t1 .sc, .cab-board-roll li.t1 .rk { color: #ffd76a; text-shadow: 3px 3px 0 #14343c, 0 0 24px rgba(255,215,106,.45); }
.cab-board-roll li.t2 .ini, .cab-board-roll li.t2 .sc, .cab-board-roll li.t2 .rk { color: #e6ecef; }
.cab-board-roll li.t3 .ini, .cab-board-roll li.t3 .sc, .cab-board-roll li.t3 .rk { color: #e0a06a; }
@media (prefers-reduced-motion: reduce) { .cab-board-roll ol { animation: none; } }

/* no blur effects anywhere in the cabinet: cheap on a Mac, a frame-rate hit on integrated graphics */
body.cabinet *, body.cabinet *::before, body.cabinet *::after { backdrop-filter: none !important; -webkit-backdrop-filter: none !important; }
/* F3: the diagnostics readout */
.cab-diag { position: absolute; left: 12px; top: 12px; z-index: 50; max-width: min(900px, 80vw); padding: 10px 14px; border-radius: 10px; background: rgba(8,24,29,.88); color: #cfe3e6; font: 600 12px/1.55 ui-monospace, Menlo, Consolas, monospace; white-space: pre-wrap; word-break: break-word; }
.cab-diag b { color: #f2c230; font-size: 16px; }
/* F8: panel setup */
.cab-setup { position: absolute; inset: 0; display: grid; grid-template-rows: auto 1fr auto; place-items: center; padding: 4vh 5vw; text-align: center; color: #fdf6e4; }
.cab-setup-head { font: 700 clamp(30px, 4.6vw, 64px)/1 "Fredoka", sans-serif; letter-spacing: .03em; text-shadow: 4px 4px 0 #14343c; }
.cab-setup-head em { font-style: normal; color: #f2c230; }
.cab-setup-body { display: grid; gap: 2.4vh; place-items: center; }
.cab-setup-seat { padding: .35em .9em; border-radius: 999px; border: 4px solid #14343c; font: 700 clamp(16px, 1.8vw, 26px)/1 "Fredoka", sans-serif; color: #14343c; background: #6fd6a8; box-shadow: 0 4px 0 #14343c; }
.cab-setup-seat.p2 { background: #f2938f; } .cab-setup-seat.centre { background: #f2c230; }
.cab-setup-prompt { font: 700 clamp(28px, 4vw, 60px)/1.15 "Fredoka", sans-serif; text-shadow: 3px 3px 0 #14343c; max-width: 80vw; }
.cab-setup-prompt b { color: #f2c230; }
.cab-setup-prompt small { display: block; margin-top: .4em; font: 900 clamp(10px, 1vw, 14px)/1 "Nunito", sans-serif; letter-spacing: .24em; color: rgba(253,246,228,.6); }
.cab-setup-flash { min-height: 1.4em; font: 700 clamp(16px, 1.8vw, 26px)/1 "Fredoka", sans-serif; color: #f2938f; text-shadow: 2px 2px 0 #14343c; }
.cab-setup-dots { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; max-width: 70vw; }
.cab-setup-dots i { width: 14px; height: 14px; border-radius: 50%; border: 2px solid #14343c; background: rgba(253,246,228,.2); }
.cab-setup-dots i.done { background: #6fd6a8; } .cab-setup-dots i.now { background: #f2c230; transform: scale(1.3); }
.cab-setup-foot { font: 900 clamp(10px, 1.05vw, 14px)/1.6 "Nunito", sans-serif; letter-spacing: .24em; color: rgba(253,246,228,.6); }
.cab-setup-foot b { color: #fdf6e4; }
.cab-test { display: grid; grid-template-columns: 1fr 1fr; gap: 4vw; width: min(1100px, 86vw); }
.cab-test-seat { border-radius: 22px; border: 4px solid rgba(253,246,228,.15); padding: 2vh 2vw; display: grid; gap: 1.6vh; justify-items: center; }
.cab-test-seat.p1 { border-color: #6fd6a8; } .cab-test-seat.p2 { border-color: #f2938f; }
.cab-test-seat h3 { margin: 0; font: 700 clamp(20px, 2.4vw, 36px)/1 "Fredoka", sans-serif; }
.cab-test-seat small { font: 900 10px/1.4 "Nunito", sans-serif; letter-spacing: .2em; color: rgba(253,246,228,.55); max-width: 36vw; word-break: break-all; }
.cab-test-stick { display: grid; grid-template-columns: repeat(3, 2.6em); grid-template-rows: repeat(3, 2.6em); font-size: clamp(12px, 1.3vw, 20px); }
.cab-test-stick i { display: grid; place-content: center; border-radius: 8px; color: rgba(253,246,228,.35); font-style: normal; font-weight: 900; }
.cab-test-stick i.on { background: #f2c230; color: #14343c; }
.cab-test-btns { display: flex; gap: .6em; flex-wrap: wrap; justify-content: center; }
.cab-test-btns span { padding: .5em .9em; border-radius: 999px; border: 3px solid #14343c; background: rgba(253,246,228,.12); font: 900 clamp(11px, 1.1vw, 16px)/1 "Nunito", sans-serif; letter-spacing: .18em; }
.cab-test-btns span.on { background: #f2c230; color: #14343c; }

/* the pause card over a frozen run */
/* Read from across a room, not from a desk chair: this card is the one thing a
   player looks for when they want out, so it takes real estate. */
.cab-pausecard { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); text-align: center; background: rgba(8,24,29,.94); border: 6px solid #f2c230; border-radius: 30px; padding: clamp(34px, 4vw, 64px) clamp(52px, 6.5vw, 108px); box-shadow: 0 14px 0 #0b232a; min-width: min(46vw, 620px); }
.cab-pausecard .cab-cont-q { font-size: clamp(46px, 6.4vw, 104px); font-family: "Fredoka", sans-serif; font-weight: 700; letter-spacing: .08em; color: #fdf6e4; text-shadow: 4px 4px 0 #14343c; }
.cab-pause-sub { margin-top: 20px; font: 900 clamp(14px, 1.4vw, 22px)/1 "Nunito", sans-serif; letter-spacing: .24em; color: rgba(253,246,228,.62); }
/* who stopped the run, in that seat's colour */
.cab-pause-who { font: 900 clamp(16px, 1.7vw, 27px)/1 "Nunito", sans-serif; letter-spacing: .26em; color: #6fd6a8; margin-bottom: .5em; }
.cab-pause-who.p2 { color: #f2938f; }
/* the "are you sure" step: same card, warmer rim so it reads as a question */
.cab-confirm { border-color: #f2938f; }
.cab-confirm .cab-cont-q { font-size: clamp(34px, 4.6vw, 74px); }
.cab-pause-sub.big { margin-top: 10px; font-size: clamp(15px, 1.5vw, 24px); letter-spacing: .18em; color: rgba(253,246,228,.78); }
/* ---- the count-in ----------------------------------------------------------
   READY over the still floor, then GO as the round is released. Nothing behind
   it: the point is that the players are already looking at the pharmacy. */
.cab-countin { position: absolute; left: 50%; top: 42%; transform: translate(-50%, -50%); pointer-events: none; font-family: "Fredoka", sans-serif; font-weight: 700; letter-spacing: .06em; white-space: nowrap; text-shadow: 6px 6px 0 #14343c, 0 14px 0 rgba(0,0,0,.28); animation: cab-countin-pop .42s cubic-bezier(.2,1.5,.4,1); }
.cab-countin.ready { font-size: clamp(64px, 11vw, 200px); color: #fdf6e4; }
.cab-countin.go { font-size: clamp(88px, 15vw, 270px); color: #f2c230; animation: cab-countin-go .5s cubic-bezier(.2,1.6,.4,1); }
@keyframes cab-countin-pop { from { transform: translate(-50%, -50%) scale(.4); opacity: 0; } 60% { opacity: 1; } to { transform: translate(-50%, -50%) scale(1); opacity: 1; } }
@keyframes cab-countin-go { from { transform: translate(-50%, -50%) scale(2.2); opacity: 0; } 45% { opacity: 1; } to { transform: translate(-50%, -50%) scale(1); opacity: 1; } }

/* ==== cabinet: arcade graphics ============================================= */
/* the title slide: the wordmark breathes, the floor stripes crawl */
.cab-slide::before { content: ""; position: absolute; inset: -40%; z-index: -1; pointer-events: none;
  background: repeating-linear-gradient(-32deg, transparent 0 46px, rgba(242,194,48,.06) 46px 92px);
  animation: cab-crawl 9s linear infinite; }
@keyframes cab-crawl { to { transform: translateX(92px); } }
.cab-wordmark { animation: cab-breathe 2.4s ease-in-out infinite; }
@keyframes cab-breathe { 50% { transform: scale(1.035) rotate(-.6deg); filter: drop-shadow(0 8px 0 rgba(0,0,0,.35)) drop-shadow(0 0 28px rgba(242,194,48,.35)); } }
/* SPLASH: giant call-outs slammed onto the battle demo when weapons fire */
.cab-splash { position: absolute; left: 50%; top: 30%; transform: translate(-50%, -50%); pointer-events: none;
  font: 700 clamp(64px, 11vw, 150px)/1 "Fredoka", sans-serif; letter-spacing: .01em; text-transform: uppercase; color: #fdf6e4; white-space: nowrap;
  text-shadow: 0 0 0 #0b232a, 4px 4px 0 #0b232a, -4px 4px 0 #0b232a, 4px -4px 0 #0b232a, -4px -4px 0 #0b232a, 0 12px 0 #0b232a, 0 0 40px rgba(0,0,0,.5);
  animation: cab-slam 1.15s cubic-bezier(.2, 1.4, .4, 1) forwards; }
/* in play: smaller, quicker, up in the top third so it never covers the table */
.cab-splash.play { top: 22%; font-size: clamp(40px, 6.5vw, 96px); animation-duration: .95s;
  text-shadow: 0 0 0 #0b232a, 3px 3px 0 #0b232a, -3px 3px 0 #0b232a, 3px -3px 0 #0b232a, -3px -3px 0 #0b232a, 0 8px 0 #0b232a, 0 0 30px rgba(0,0,0,.45); }
.cab-splash.hot { color: #f2c230; } .cab-splash.cold { color: #8fe0f3; } .cab-splash.red { color: #ff8a80; } .cab-splash.mint { color: #8ff0bf; }
@keyframes cab-slam { 0% { opacity: 0; transform: translate(-50%, -50%) scale(2.2) rotate(-4deg); } 14% { opacity: 1; transform: translate(-50%, -50%) scale(.96) rotate(1deg); } 22% { transform: translate(-50%, -50%) scale(1.04) rotate(-.5deg); } 78% { opacity: 1; transform: translate(-50%, -50%) scale(1); } 100% { opacity: 0; transform: translate(-50%, -62%) scale(1.06); } }
.cab-headline { position: absolute; left: 50%; bottom: calc(76px + 11vw); transform: translateX(-50%); pointer-events: none;
  font: 700 clamp(26px, 3.4vw, 44px)/1.1 "Fredoka", sans-serif; color: #fdf6e4; text-align: center; letter-spacing: .02em;
  text-shadow: 3px 3px 0 #0b232a, -3px 3px 0 #0b232a, 3px -3px 0 #0b232a, -3px -3px 0 #0b232a, 0 8px 0 #0b232a; animation: cab-head-in .3s ease both; max-width: 90vw; }
/* the fade keeps the centring transform, so the line never jumps sideways while it appears */
@keyframes cab-head-in { from { opacity: 0; transform: translate(-50%, 10px); } to { opacity: 1; transform: translate(-50%, 0); } }
.cab-headline b { color: #f2c230; }
.cab-headline.top { bottom: auto; top: 4vh; }
/* the board during the attract: room for the line above and the START calls below */
body.cabinet.attract .lb-entry.browse { place-items: start center; }
body.cabinet.attract .lb-entry.browse .lb-card { margin-top: calc(6vh + 3.4vw + 20px); max-height: calc(100vh - 6vh - 3.4vw - 20px - 9.5vw - 60px); overflow: hidden; }
body.cabinet.attract .lb-entry.browse .lb-logo { width: min(300px, 40vw); }
body.cabinet.attract .lb-entry.browse .lb-board-title { margin-bottom: 8px; }
/* SELECT YOUR TECH */
.cab-select { position: absolute; inset: 0; background: #0b232a; display: grid; grid-template-rows: auto 1fr auto; align-items: center; justify-items: center; padding: 3vh 4vw; pointer-events: none; overflow: hidden; }
.cab-select::before { content: ""; position: absolute; inset: -40%; background: repeating-linear-gradient(-32deg, transparent 0 46px, rgba(79,179,165,.10) 46px 92px); animation: cab-crawl 9s linear infinite; }
.cab-select-head { position: relative; display: flex; align-items: baseline; gap: 26px; }
.cab-select-head h2 { margin: 0; font: 700 clamp(38px, 5.6vw, 76px)/1 "Fredoka", sans-serif; text-transform: uppercase; color: #fdf6e4; text-shadow: 4px 4px 0 #14343c, 0 10px 0 rgba(0,0,0,.35); }
.cab-select-head h2 em { font-style: normal; color: #f2c230; }
.cab-time { font: 700 clamp(30px, 4vw, 54px)/1 "Fredoka", sans-serif; color: #63c9a0; text-shadow: 3px 3px 0 #14343c; }
.cab-time small { font: 900 12px/1 "Nunito", sans-serif; letter-spacing: .3em; color: rgba(253,246,228,.6); margin-right: 10px; vertical-align: middle; }
.cab-panels { position: relative; display: flex; gap: clamp(8px, 1.4vw, 20px); width: 100%; justify-content: center; align-items: stretch; }
.cab-panel { position: relative; flex: 1 1 0; max-width: 220px; aspect-ratio: 3 / 4.6; border-radius: 16px; border: 5px solid #14343c; background: #3b5560; overflow: hidden;
  filter: grayscale(1) brightness(.55); transform: scale(.94); transition: transform .18s ease, filter .18s ease, border-color .18s ease; box-shadow: 0 8px 0 #06161b; }
.cab-panel.on { filter: none; transform: scale(1.02); border-color: #fdf6e4; box-shadow: 0 8px 0 #06161b, 0 0 0 6px rgba(242,194,48,.35), 0 0 60px rgba(242,194,48,.25); z-index: 2; }
.cab-panel.on.p2 { box-shadow: 0 8px 0 #06161b, 0 0 0 6px rgba(242,147,143,.4), 0 0 60px rgba(242,147,143,.25); }
.cab-panel.locked { filter: none; transform: scale(1); border-color: #63c9a0; }
.cab-panel .bg { position: absolute; inset: 0; background: linear-gradient(180deg, var(--outfit) 0 42%, #dfe7e6 42% 100%); }
.cab-panel .bg::after { content: ""; position: absolute; inset: 0; background: repeating-linear-gradient(135deg, transparent 0 14px, rgba(255,255,255,.08) 14px 28px); }
/* the tech, drawn big: hair, head, scrubs, legs */
.cab-fig { position: absolute; left: 50%; bottom: 14%; width: 62%; height: 74%; transform: translateX(-50%); }
.cab-fig i { position: absolute; left: 50%; transform: translateX(-50%); border: 4px solid #14343c; border-radius: 10px; }
.cab-fig .hair { top: -2%; width: 70%; height: 22%; background: var(--hair); border-radius: 40% 40% 18% 18%; z-index: 2; }
.cab-fig .head { top: 4%; width: 62%; height: 28%; background: var(--skin); border-radius: 22%; }
.cab-fig .eye { top: 15%; width: 7%; height: 7%; border-radius: 50%; background: #14343c; border: 0; z-index: 3; }
.cab-fig .eye.l { left: 39%; } .cab-fig .eye.r { left: 61%; }
.cab-fig .body { top: 30%; width: 84%; height: 44%; background: var(--outfit); border-radius: 18px 18px 8px 8px; }
.cab-fig .badge { top: 40%; left: 62%; width: 14%; height: 10%; background: #fdf6e4; border-radius: 3px; border-width: 3px; z-index: 2; }
.cab-fig .legs { top: 72%; width: 62%; height: 26%; background: #3b4a63; border-radius: 6px 6px 10px 10px; }
.cab-panel .name { position: absolute; left: 0; right: 0; bottom: 0; padding: 10px 6px 12px; background: #14343c; color: #fdf6e4; text-align: center; font: 700 clamp(14px, 1.6vw, 22px)/1 "Fredoka", sans-serif; letter-spacing: .04em; }
.cab-panel .name small { display: block; margin-top: 4px; font: 900 9px/1 "Nunito", sans-serif; letter-spacing: .22em; color: #7fd4b2; }
.cab-up { position: absolute; top: 8px; left: 50%; transform: translateX(-50%); padding: 7px 12px; border-radius: 10px; border: 3px solid #14343c; font: 700 20px/1 "Fredoka", sans-serif; color: #14343c; z-index: 4; animation: cab-bob .7s ease-in-out infinite alternate; box-shadow: 0 4px 0 #14343c; }
.cab-up::after { content: ""; position: absolute; left: 50%; bottom: -10px; transform: translateX(-50%); border: 7px solid transparent; border-top-color: #14343c; }
.cab-up.p1 { background: #6fd6a8; } .cab-up.p2 { background: #f2938f; top: auto; bottom: 62px; animation-direction: alternate-reverse; }
.cab-up.p2::after { bottom: auto; top: -10px; border-top-color: transparent; border-bottom-color: #14343c; }
.cab-up.ready { background: #f2c230; animation: none; }
@keyframes cab-bob { to { transform: translateX(-50%) translateY(-6px); } }
/* the split screen: one half per seat, each a stage with the real tech on it */
.cab-halves { position: relative; display: grid; grid-template-columns: 1fr 1fr; gap: 2.4vw; width: 100%; height: 100%; min-height: 0; align-self: stretch; }
.cab-half { position: relative; min-height: 0; border-radius: 26px; border: 4px solid rgba(253,246,228,.12); background: radial-gradient(ellipse at 50% 70%, rgba(79,179,165,.16), rgba(8,24,29,.3) 70%); padding: 1.2vh 1.4vw 1.4vh; display: grid; grid-template-rows: 1fr auto auto; gap: .9vh; overflow: hidden; animation: cab-half-in .45s cubic-bezier(.2,1.3,.4,1); }
@keyframes cab-half-in { from { transform: scale(.94); opacity: .4; } to { transform: none; opacity: 1; } }
.cab-half.joined.p1 { border-color: #6fd6a8; box-shadow: 0 0 0 4px rgba(111,214,168,.16), inset 0 0 90px rgba(111,214,168,.10); }
.cab-half.joined.p2 { border-color: #f2938f; box-shadow: 0 0 0 4px rgba(242,147,143,.16), inset 0 0 90px rgba(242,147,143,.10); }
.cab-half.locked { border-color: #f2c230; box-shadow: 0 0 0 4px rgba(242,194,48,.22), inset 0 0 90px rgba(242,194,48,.08); }
/* the stage */
.cab-stage { position: relative; min-height: 0; }
.cab-stage::before { content: ""; position: absolute; left: 50%; top: 8%; width: 70%; height: 84%; transform: translateX(-50%); border-radius: 50%; background: radial-gradient(ellipse at 50% 40%, rgba(253,246,228,.14), transparent 68%); pointer-events: none; }
.cab-stage-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; transition: opacity .3s ease, filter .3s ease; }
.cab-half:not(.joined) .cab-stage-canvas { opacity: .42; filter: saturate(0) brightness(.7); }
.cab-half:not(.joined) .cab-plate, .cab-half:not(.joined) .cab-strip, .cab-half:not(.joined) .cab-half-state { visibility: hidden; }
.cab-stamp { position: absolute; left: 50%; top: 42%; transform: translate(-50%, -50%) rotate(-12deg) scale(0); padding: .1em .5em; border: .12em solid #f2c230; border-radius: .25em; color: #f2c230; font: 700 clamp(40px, 5.6vw, 96px)/1 "Fredoka", sans-serif; letter-spacing: .06em; text-shadow: 0 .06em 0 #14343c; background: rgba(8,24,29,.55); pointer-events: none; }
.cab-half.locked .cab-stamp { animation: cab-stamp .5s cubic-bezier(.2,1.5,.4,1) forwards; }
@keyframes cab-stamp { from { transform: translate(-50%, -50%) rotate(-30deg) scale(3); opacity: 0; } 60% { opacity: 1; } to { transform: translate(-50%, -50%) rotate(-12deg) scale(1); opacity: 1; } }
/* the way out of READY, shown only while a seat is locked */
.cab-unready { position: absolute; left: 50%; top: 66%; transform: translateX(-50%); padding: .55em 1.1em; border-radius: 999px; background: rgba(8,24,29,.78); color: #fdf6e4; font: 900 clamp(19px, 1.95vw, 31px)/1 "Nunito", sans-serif; letter-spacing: .16em; white-space: nowrap; opacity: 0; pointer-events: none; transition: opacity .25s ease .35s; }
.cab-half.locked .cab-unready { opacity: .9; }
/* The same pill before a seat is locked, telling a player which cap to hit.
   Nothing on this screen named a button, so a first-timer at the cabinet had
   to guess which of the four colours picked their tech. */
.cab-pick { position: absolute; left: 50%; top: 66%; transform: translateX(-50%); padding: .55em 1.1em; border-radius: 999px; background: rgba(8,24,29,.78); color: #fdf6e4; font: 900 clamp(19px, 1.95vw, 31px)/1 "Nunito", sans-serif; letter-spacing: .16em; white-space: nowrap; opacity: 0; pointer-events: none; transition: opacity .25s ease; }
.cab-half.joined:not(.locked) .cab-pick { opacity: .9; }
/* The panel's caps, drawn as the buttons themselves. A player is looking down
   at four coloured discs, so a disc is the thing to put on screen - the word
   "YELLOW" is both slower to read and wide enough to foul the art behind it. */
.cab-btn { display: inline-block; width: 1.45em; height: 1.45em; border-radius: 50%; border: .14em solid #14343c; vertical-align: -.32em; box-shadow: inset 0 -.2em 0 rgba(0,0,0,.22), inset 0 .17em 0 rgba(255,255,255,.5), 0 .18em 0 #14343c; }
/* These are the PANEL's colours, not the game's. Everything else on screen is
   muted - amber #f2c230, coral #f2938f - but the caps under the player's hand
   are primary plastic, and a washed-out disc beside a bright yellow button
   reads as a different button. Matched to the hardware on purpose. */
.cab-btn.y { background: #ffd400; }
.cab-btn.b { background: #1273e8; }
.cab-btn.w { background: #fcfcfa; }
.cab-btn.r { background: #e5202c; }
/* the pause card's three ways out */
.cab-pause-opts { display: flex; flex-direction: column; gap: .55em; margin: 1.1em 0 .3em; align-items: stretch; }
.cab-pause-opt { display: flex; align-items: center; justify-content: space-between; gap: 1.8em; padding: .6em 1em; border-radius: 16px; background: rgba(8,24,29,.5); border: 4px solid #14343c; }
.cab-pause-opt .cab-btn { font-size: clamp(22px, 2.3vw, 38px); }
.cab-pause-opt span { color: #fdf6e4; font: 700 clamp(22px, 2.3vw, 38px)/1 "Fredoka", sans-serif; letter-spacing: .1em; }
/* the name plate slams in whenever the pick changes */
.cab-plate { display: flex; align-items: baseline; gap: .55em; color: #fdf6e4; font: 700 clamp(24px, 3.2vw, 52px)/1 "Fredoka", sans-serif; text-shadow: 3px 3px 0 #14343c, 0 8px 0 rgba(0,0,0,.3); animation: cab-plate-in .32s cubic-bezier(.2,1.4,.4,1); }
@keyframes cab-plate-in { from { transform: translateY(14px) scale(.92); opacity: 0; } to { transform: none; opacity: 1; } }
.cab-plate small { font: 900 clamp(9px, .95vw, 14px)/1 "Nunito", sans-serif; letter-spacing: .26em; color: #7fd4b2; }
.cab-up-tag { padding: .22em .5em; border-radius: 8px; border: 3px solid #14343c; font-size: .58em; color: #14343c; background: #6fd6a8; box-shadow: 0 3px 0 #14343c; }
.cab-half.p2 .cab-up-tag { background: #f2938f; }
.cab-half.locked .cab-up-tag { background: #f2c230; }
/* the roster strip: six tiles, the cursor rides the chosen one */
.cab-strip { display: grid; grid-template-columns: repeat(6, 1fr); gap: clamp(6px, .7vw, 12px); }
.cab-tile { position: relative; aspect-ratio: 1 / 1; border-radius: 12px; border: 3px solid #14343c; background: linear-gradient(180deg, var(--outfit) 0 62%, #dfe7e6 62%); opacity: .5; transform: translateY(0) scale(1); transition: transform .18s cubic-bezier(.2,1.4,.4,1), opacity .18s ease, box-shadow .18s ease; overflow: hidden; }
.cab-tile i { position: absolute; left: 50%; top: 16%; width: 42%; aspect-ratio: 1; transform: translateX(-50%); border-radius: 30%; background: var(--skin); border: 3px solid #14343c; }
.cab-tile i::before { content: ""; position: absolute; left: -6%; right: -6%; top: -18%; height: 44%; border-radius: 40% 40% 12% 12%; background: var(--hair); border: 3px solid #14343c; }
.cab-tile span { position: absolute; left: 0; right: 0; bottom: 0; padding: 4px 1px 5px; background: #14343c; color: #fdf6e4; text-align: center; font: 700 clamp(8px, .7vw, 12px)/1 "Fredoka", sans-serif; letter-spacing: .02em; white-space: nowrap; overflow: hidden; }
.cab-tile.on { opacity: 1; transform: translateY(-8px) scale(1.08); border-color: #fdf6e4; box-shadow: 0 6px 0 #06161b, 0 0 0 4px rgba(242,194,48,.4), 0 0 30px rgba(242,194,48,.35); z-index: 2; }
.cab-half.p2 .cab-tile.on { box-shadow: 0 6px 0 #06161b, 0 0 0 4px rgba(242,147,143,.45), 0 0 30px rgba(242,147,143,.35); }
.cab-half.locked .cab-tile:not(.on) { opacity: .25; }
/* the other seat's locked tech: greyed, stamped, and it stays that way even under the cursor */
.cab-tile.taken { opacity: .22 !important; filter: grayscale(1); }
.cab-tile.taken.on { opacity: .45 !important; box-shadow: 0 6px 0 #06161b, 0 0 0 4px rgba(242,147,143,.35); }
.cab-tile.taken::after { content: "TAKEN"; position: absolute; inset: 0; display: grid; place-items: center; padding-bottom: 22%; color: #fdf6e4; font: 900 clamp(8px, .75vw, 13px)/1 "Nunito", sans-serif; letter-spacing: .14em; text-shadow: 0 2px 0 #06161b; transform: rotate(-16deg); }
.cab-plate-tag.taken { color: #f2938f; }
/* ---- the VS card: shown over the launch veil while the arena builds ------- */
.cab-vscard { position: absolute; inset: 0; z-index: 40; display: flex; align-items: center; justify-content: center; gap: clamp(20px, 3.5vw, 70px); pointer-events: none;
  background: repeating-linear-gradient(135deg, rgba(8,24,29,.92) 0 28px, rgba(14,44,52,.92) 28px 56px); animation: cab-vscard-in .35s ease both; }
.cab-vscard.leaving { animation: cab-vscard-out .45s ease both; }
@keyframes cab-vscard-in { from { opacity: 0; } }
@keyframes cab-vscard-out { to { opacity: 0; } }
.cab-vs-seat { width: clamp(220px, 26vw, 460px); aspect-ratio: 1 / 1; border-radius: 30px; border: .5vw solid #6fd6a8; background: linear-gradient(180deg, var(--outfit) 0 64%, #dfe7e6 64%); box-shadow: 0 .9vw 0 #06161b, 0 0 60px rgba(111,214,168,.3); display: grid; grid-template-rows: 1fr auto; overflow: hidden; position: relative; animation: cab-vs-seat-in .5s cubic-bezier(.2,1.5,.4,1) both; }
.cab-vs-seat.p1 { animation-delay: .05s; }
.cab-vs-seat.p2 { border-color: #f2938f; box-shadow: 0 .9vw 0 #06161b, 0 0 60px rgba(242,147,143,.3); animation-delay: .25s; }
@keyframes cab-vs-seat-in { from { transform: translateY(40px) scale(.8); opacity: 0; } }
.cab-vs-face { position: relative; }
.cab-vs-face i { position: absolute; left: 50%; top: 22%; width: 42%; aspect-ratio: 1; transform: translateX(-50%); border-radius: 30%; background: var(--skin); border: .35vw solid #14343c; }
.cab-vs-face i::before { content: ""; position: absolute; left: -6%; right: -6%; top: -18%; height: 44%; border-radius: 40% 40% 12% 12%; background: var(--hair); border: .35vw solid #14343c; }
.cab-vs-plate { display: grid; grid-template-columns: auto 1fr; grid-template-rows: auto auto; column-gap: .8vw; align-items: center; padding: 1vw 1.2vw 1.1vw; background: #14343c; color: #fdf6e4; text-align: left; }
.cab-vs-plate .cab-up-tag { grid-row: 1 / 3; }
.cab-vs-plate b { font: 700 clamp(22px, 2.6vw, 44px)/1 "Fredoka", sans-serif; letter-spacing: .02em; white-space: nowrap; }
.cab-vs-plate small { font: 900 clamp(9px, .85vw, 14px)/1 "Nunito", sans-serif; letter-spacing: .22em; color: #7fd4b2; margin-top: .4em; }
.cab-vs-seat.p2 .cab-vs-plate small { color: #f2938f; }
.cab-vs-mid { font: 700 clamp(70px, 10vw, 190px)/1 "Fredoka", sans-serif; color: #f2c230; text-shadow: .06em .06em 0 #14343c, 0 .14em 0 rgba(0,0,0,.4); transform: rotate(-8deg); animation: cab-vs-in .45s cubic-bezier(.2,1.6,.4,1) .45s both; }
.cab-half-state { text-align: center; font: 900 clamp(10px, 1.05vw, 14px)/1.4 "Nunito", sans-serif; letter-spacing: .22em; color: rgba(253,246,228,.7); }
.cab-half-state b { color: #f2c230; }
.cab-half.locked .cab-half-state { visibility: hidden; }
/* the empty seat: a ghost on the podium and the join call over it */
.cab-join { position: absolute; inset: 0; display: grid; place-content: center; text-align: center; gap: 1.4vh; color: rgba(253,246,228,.85); pointer-events: none; }
.cab-half.joined .cab-join { display: none; }
.cab-join-n { font: 700 clamp(70px, 11vw, 190px)/1 "Fredoka", sans-serif; color: rgba(253,246,228,.14); text-shadow: 0 6px 0 rgba(0,0,0,.25); }
.cab-half.p2 .cab-join-n { color: rgba(242,147,143,.26); } .cab-half.p1 .cab-join-n { color: rgba(111,214,168,.26); }
.cab-join-t { font: 700 clamp(20px, 2.4vw, 38px)/1.15 "Fredoka", sans-serif; text-shadow: 3px 3px 0 #14343c; animation: cab-blink 1.1s steps(1, end) infinite; }
.cab-join-t b { color: #f2c230; }
.cab-join-s { font: 900 clamp(11px, 1.1vw, 18px)/1 "Nunito", sans-serif; letter-spacing: .26em; color: rgba(253,246,228,.7); }
/* the empty seat as the countdown: PLAYER 2, JOIN NOW over a number you can
   read from across the room, a draining bar, and what happens at zero */
.cab-join.counting { gap: .8vh; }
.cab-join-k { font: 700 clamp(22px, 2.8vw, 46px)/1.1 "Fredoka", sans-serif; color: #f2c230; text-shadow: 3px 3px 0 #14343c; animation: cab-blink 1.1s steps(1, end) infinite; }
.cab-join-count { font: 700 clamp(120px, 17vw, 300px)/1 "Fredoka", sans-serif; color: #fdf6e4; text-shadow: 0 .05em 0 #06161b, 0 0 .2em rgba(242,194,48,.35); animation: cab-count-pop .5s cubic-bezier(.2,1.6,.4,1); }
@keyframes cab-count-pop { from { transform: scale(1.35); opacity: .4; } }
.cab-join-bar { width: min(62%, 460px); height: clamp(8px, .9vw, 14px); margin: 0 auto; border-radius: 999px; background: rgba(253,246,228,.16); border: 2px solid rgba(253,246,228,.35); overflow: hidden; }
.cab-join-bar i { display: block; height: 100%; background: #f2c230; transition: width .95s linear; }
.cab-join.counting .cab-join-t { animation: none; font-size: clamp(16px, 1.8vw, 28px); }
.cab-join.counting .cab-join-s { color: #7fd4b2; }
.cab-select-head h2.battle em { color: #f2938f; }
.cab-vs-badge.count { width: clamp(120px, 13vw, 230px); font-size: clamp(44px, 5vw, 92px); }
/* VS, once both seats are on */
.cab-vs-badge { position: absolute; left: 50%; top: 40%; transform: translate(-50%, -50%) scale(0); width: clamp(64px, 7vw, 120px); aspect-ratio: 1; border-radius: 50%; display: grid; place-content: center; background: #f2c230; color: #14343c; border: .08em solid #14343c; box-shadow: 0 .12em 0 #14343c, 0 0 40px rgba(242,194,48,.45); font: 700 clamp(28px, 3.2vw, 56px)/1 "Fredoka", sans-serif; z-index: 3; pointer-events: none; transition: transform .35s cubic-bezier(.2,1.6,.4,1); }
.cab-vs-badge.on { transform: translate(-50%, -50%) scale(1) rotate(-8deg); animation: cab-vs-in .4s cubic-bezier(.2,1.6,.4,1); }
@keyframes cab-vs-in { from { transform: translate(-50%, -50%) scale(2.4) rotate(20deg); opacity: 0; } }
/* the same medallion counts down to a solo shift until a second seat turns it into VS */
.cab-vs-badge.count { width: clamp(84px, 9vw, 160px); background: #14343c; color: #fdf6e4; border-color: #6fd6a8; box-shadow: 0 .12em 0 #06161b, 0 0 40px rgba(111,214,168,.35); transform: translate(-50%, -50%) scale(1); animation: none; display: grid; grid-template-rows: auto auto; place-items: center; gap: 0; }
.cab-vs-badge.count small { font: 900 clamp(8px, .75vw, 11px)/1 "Nunito", sans-serif; letter-spacing: .24em; color: #7fd4b2; margin-top: .3em; }
.cab-vs-badge.count.hurry { border-color: #f2938f; color: #f2938f; animation: none; }
/* the demos keep their bottom edge clear: no hand strips or prompts under the START calls */
body.cabinet.attract .bt-inv, body.cabinet.attract .bt-prompt { display: none !important; }
.cab-time.hurry { color: #f2938f; animation: cab-hurry .5s ease-in-out infinite alternate; }
@keyframes cab-hurry { to { transform: scale(1.12); } }
.cab-select-foot { position: relative; font: 900 clamp(11px, 1.2vw, 14px)/1.6 "Nunito", sans-serif; letter-spacing: .22em; color: rgba(253,246,228,.7); text-align: center; }
.cab-select-foot b { color: #f2c230; }

/* ==== battle: the winner's wall ============================================
   The result card rebuilt as a full-screen finish: the winner's colour wipes
   in from their side, their tech rises on a podium beside the giant WINS, the
   score and tally chips pop in one after another. --wall is set per match. */
.bt-result.final { display: none; place-items: initial; background: rgba(5, 22, 27, .58); overflow: hidden; }
.bt-result.final.on { display: block; }
.bt-result.final .bw-wall { position: absolute; inset: 0; background: var(--wall, #2e8b7a); clip-path: polygon(0 0, 58% 0, 44% 100%, 0 100%); animation: bw-wipe .55s cubic-bezier(.2, .9, .2, 1) both; }
.bt-result.final .bw-wall::after { content: ""; position: absolute; inset: 0; background: repeating-linear-gradient(-32deg, transparent 0 3vw, rgba(255, 255, 255, .06) 3vw 6vw); }
.bt-result.final .bw-stack { position: absolute; left: 4vw; top: 7vh; z-index: 2; color: var(--cream); line-height: .86; font-family: "Fredoka", sans-serif; font-weight: 700; text-shadow: .6vw .6vw 0 var(--ink-deep); animation: bw-pop .5s cubic-bezier(.2, 1.5, .4, 1) .25s both; }
.bt-result.final .bw-stack .p { display: block; font-size: clamp(28px, 7vw, 120px); letter-spacing: .04em; color: var(--gold, #f2c230); }
.bt-result.final .bw-stack .w { display: block; font-size: clamp(64px, 15vw, 260px); letter-spacing: -.01em; }
.bt-result.final.tie .bw-stack .p { color: var(--cream); }
.bt-result.final .bw-stage { position: absolute; left: 29vw; bottom: 4vh; width: 20vw; height: 42vw; max-height: 78vh; z-index: 1; animation: bw-rise .5s cubic-bezier(.2, 1.5, .4, 1) .4s both; }
.bt-result.final .bw-score { position: absolute; right: 8vw; top: 10vh; display: inline-flex; align-items: center; gap: .8vw; padding: 1.2vw 2.2vw; border: .35vw solid var(--ink); border-radius: 1.4vw; background: var(--cream); color: var(--ink); box-shadow: 0 .6vw 0 var(--ink-deep); font: 700 clamp(28px, 5vw, 80px)/1 "Fredoka", sans-serif; animation: bw-pop .5s cubic-bezier(.2, 1.5, .4, 1) .9s both; }
.bt-result.final .bw-score b { font-weight: 700; font-size: inherit; color: var(--ink); display: inline; }
.bt-result.final .bw-score em { font-style: normal; color: #5d7078; font-size: .6em; margin: 0 .2vw; }
.bt-result.final .bw-seat { display: inline-grid; place-items: center; padding: .5vw .8vw; border-radius: .7vw; font: 900 clamp(10px, 1.3vw, 20px)/1 "Nunito", sans-serif; letter-spacing: .12em; color: #fff; }
.bt-result.final .bw-seat.p1 { background: #2e8b7a; }
.bt-result.final .bw-seat.p2 { background: #8e3b4a; }
.bt-result.final .bw-tally { position: absolute; right: 8vw; top: 30vh; width: 30vw; display: grid; gap: .8vw; }
.bt-result.final .bw-tally div { display: flex; justify-content: space-between; align-items: baseline; padding: .8vw 1.4vw; background: rgba(253, 246, 228, .94); border: .3vw solid var(--ink); border-radius: 1vw; color: var(--ink); font: 900 clamp(11px, 1.5vw, 24px)/1 "Nunito", sans-serif; letter-spacing: .14em; animation: bw-pop .5s cubic-bezier(.2, 1.5, .4, 1) both; animation-delay: calc(var(--t, 0) * 1ms); }
.bt-result.final .bw-tally div b { display: inline; font: 700 clamp(20px, 3vw, 48px)/1 "Fredoka", sans-serif; letter-spacing: 0; color: var(--wall, #2e8b7a); }
.bt-result.final .bw-tally div.mvp { background: var(--gold, #f2c230); }
.bt-result.final .bw-tally div.mvp b { color: var(--ink); font-size: clamp(14px, 2vw, 32px); }
.bt-result.final .bw-foot { position: absolute; right: 8vw; bottom: 8vh; display: flex; gap: 12px; animation: bw-pop .5s cubic-bezier(.2, 1.5, .4, 1) 2.2s both; }
.bt-result.final button { margin: 0; }
body.cabinet .bt-result.final .bw-foot { display: none; }
/* the cabinet's START bar sits along the bottom: the podium lifts clear of it */
body.cabinet .bt-result.final .bw-stage { bottom: 17vh; max-height: 66vh; }
@keyframes bw-wipe { from { transform: translateX(-100%); } to { transform: none; } }
@keyframes bw-pop { from { opacity: 0; transform: scale(.5); } 70% { opacity: 1; } to { opacity: 1; transform: none; } }
@keyframes bw-rise { from { opacity: 0; transform: translateY(30%) scale(.8); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .bt-result.final * { animation: none !important; } }

/* ==== arcade: READY / GO! ================================================ */
/* Two words, one after the other, over a room held still. Same treatment as
   the cabinet's count-in: big Fredoka, ink drop-shadow, a pop on each word. */
.arcade-countin { position: fixed; left: 50%; top: 42%; z-index: 60; transform: translate(-50%, -50%); pointer-events: none; font-family: "Fredoka", sans-serif; font-weight: 700; letter-spacing: .06em; white-space: nowrap; text-shadow: 6px 6px 0 #14343c, 0 14px 0 rgba(0,0,0,.28); animation: arcade-countin-pop .42s cubic-bezier(.2,1.5,.4,1); }
.arcade-countin.hidden { display: none; }
.arcade-countin.ready { font-size: clamp(64px, 11vw, 200px); color: #fdf6e4; }
.arcade-countin.go { font-size: clamp(88px, 15vw, 270px); color: #f2c230; animation: arcade-countin-go .5s cubic-bezier(.2,1.6,.4,1); }
@keyframes arcade-countin-pop { from { transform: translate(-50%, -50%) scale(.4); opacity: 0; } 60% { opacity: 1; } to { transform: translate(-50%, -50%) scale(1); opacity: 1; } }
@keyframes arcade-countin-go { from { transform: translate(-50%, -50%) scale(2.2); opacity: 0; } 45% { opacity: 1; } to { transform: translate(-50%, -50%) scale(1); opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .arcade-countin, .arcade-countin.go { animation: none; } }

