/* =========================================================================
   DVDL DASH - layout & UI chrome
   The canvas renders the world; the HUD/overlays are DOM so buttons stay
   crisp and reliably tappable. Everything inside #stage is sized with the
   --u custom property, where 1u == 1 logical game pixel (1920x1080 space).
   ========================================================================= */

* { margin: 0; padding: 0; box-sizing: border-box; }

html, body {
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: #07152b;
  overscroll-behavior: none;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}

body {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  /* viewport-fit=cover lets the page draw under the notch and the home
     indicator, so keep the stage clear of both. Zero on everything else. */
  padding:
    env(safe-area-inset-top) env(safe-area-inset-right)
    env(safe-area-inset-bottom) env(safe-area-inset-left);
  font-family: "Arial Black", "Arial Bold", Impact, "Helvetica Neue", system-ui, sans-serif;
}

/* ---------- Stage ---------- */

#stage {
  --u: 0.5px;                 /* set by JS on resize: viewportWidth / 1920 */
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: #0b2545;
  touch-action: none;
}

#game {
  display: block;
  width: 100%;
  height: 100%;
}

/* ---------- Arcade lettering ---------- */

.arcade {
  font-family: inherit;
  font-weight: 900;
  font-style: italic;
  letter-spacing: 0.02em;
  color: #fff;
  text-transform: uppercase;
  -webkit-text-stroke: calc(var(--u) * 4) #0a2038;
  paint-order: stroke fill;
  text-shadow:
    0 calc(var(--u) * 3) 0 rgba(6, 20, 38, 0.65),
    0 calc(var(--u) * 8) calc(var(--u) * 14) rgba(0, 0, 0, 0.45);
  white-space: nowrap;
}

/* ---------- HUD ---------- */

#hud {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
#hud.hidden { display: none; }

#hud-left {
  position: absolute;
  top: calc(var(--u) * 26);
  left: calc(var(--u) * 30);
  display: flex;
  flex-direction: column;
  gap: calc(var(--u) * 4);
}

#hud-distance { font-size: calc(var(--u) * 62); line-height: 1.05; }
#hud-best     { font-size: calc(var(--u) * 32); line-height: 1.15; opacity: 0.92; }

#hud-coins {
  display: flex;
  align-items: center;
  gap: calc(var(--u) * 10);
  font-size: calc(var(--u) * 38);
  line-height: 1.15;
  margin-top: calc(var(--u) * 2);
}

.coin-icon {
  display: inline-block;
  width: calc(var(--u) * 34);
  height: calc(var(--u) * 34);
  border-radius: 50%;
  background:
    radial-gradient(circle at 34% 30%, #fff6c2 0%, #ffd757 38%, #f0a92b 72%, #b96f12 100%);
  box-shadow:
    0 0 0 calc(var(--u) * 3) #7a4708,
    0 calc(var(--u) * 3) calc(var(--u) * 6) rgba(0, 0, 0, 0.5);
  flex: none;
}

/* Two life pools. Whichever one you are controlling stays full size; the
   other shrinks back but stays visible, so you can always see what is
   waiting for you without losing track of what is at risk right now. */
.life-row {
  display: flex;
  align-items: flex-end;
  gap: calc(var(--u) * 6);
  margin-top: calc(var(--u) * 8);
  transform-origin: left center;
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.life-row.dim { opacity: 0.42; transform: scale(0.62); margin-top: calc(var(--u) * 2); }
.life-row.empty { display: none; }

.life {
  /* A hard dark rim so the icons read against the busy office artwork. */
  filter:
    drop-shadow(0 0 calc(var(--u) * 2) rgba(6, 20, 38, 0.95))
    drop-shadow(0 0 calc(var(--u) * 4) rgba(6, 20, 38, 0.8))
    drop-shadow(0 calc(var(--u) * 3) calc(var(--u) * 4) rgba(0, 0, 0, 0.6));
  transition: opacity 0.18s ease, transform 0.18s ease;
  background-repeat: no-repeat;
}
/* The car sheet is body + flame stacked, so crop to just the body. */
.life.car {
  width: calc(var(--u) * 78);
  height: calc(var(--u) * 34);
  background-image: url("../assets/car.png?v=cb7f812a49");
  background-position: top left;
  background-size: 100% auto;
}
.life.jason {
  width: calc(var(--u) * 50);
  height: calc(var(--u) * 58);
  background-image: url("../assets/jason-head.png?v=886cc8d2e3");
  background-position: center;
  background-size: contain;
}
.life.spent { opacity: 0.22; transform: scale(0.82); filter: grayscale(1); }

/* ---------- Document tray ---------- */
/* The 118 / 16 / 26 below MUST match PROP_TRAY_SLOT / _GAP / _Y in
   js/config.js - the canvas flyer lands on these slots using those numbers. */
#prop-tray {
  position: absolute;
  top: calc(var(--u) * 26);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: calc(var(--u) * 16);
  pointer-events: none;
}
.prop-slot {
  width: calc(var(--u) * 118);
  height: calc(var(--u) * 118);
  border: calc(var(--u) * 5) solid rgba(255, 255, 255, 0.7);
  border-radius: calc(var(--u) * 22);
  background-color: rgba(7, 21, 43, 0.78);
  background-repeat: no-repeat;
  background-position: center;
  background-size: 76% auto;
  box-shadow: 0 calc(var(--u) * 4) calc(var(--u) * 10) rgba(0, 0, 0, 0.5);
  /* Empty slots show the document greyed out, so you can see what you are
     hunting for without mistaking it for one you already have. */
  filter: grayscale(1) brightness(0.55);
  opacity: 0.75;
  transition: opacity 0.25s ease, transform 0.25s ease,
              border-color 0.25s ease, filter 0.25s ease;
}
.prop-slot.filled {
  opacity: 1;
  filter: none;
  border-color: rgba(255, 215, 87, 0.95);
  background-color: rgba(10, 32, 56, 0.72);
  transform: scale(1.06);
  box-shadow: 0 0 calc(var(--u) * 24) rgba(255, 215, 87, 0.55),
              0 calc(var(--u) * 4) calc(var(--u) * 10) rgba(0, 0, 0, 0.5);
}
#prop-voter    { background-image: url("../assets/prop-voter.png?v=b3b8ec174e"); }
#prop-ack      { background-image: url("../assets/prop-ack.png?v=3bd75765da"); }
#prop-status   { background-image: url("../assets/prop-status.png?v=2fda4edbda"); }
#prop-passport { background-image: url("../assets/prop-passport.png?v=9a42026ced"); }

/* ---------- Pause button ---------- */

#pause-btn {
  position: absolute;
  top: calc(var(--u) * 26);
  right: calc(var(--u) * 30);
  width: calc(var(--u) * 84);
  height: calc(var(--u) * 84);
  border: calc(var(--u) * 4) solid rgba(255, 255, 255, 0.85);
  border-radius: calc(var(--u) * 20);
  background: rgba(10, 32, 56, 0.55);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: calc(var(--u) * 9);
  cursor: pointer;
  pointer-events: auto;
  touch-action: manipulation;
}
#pause-btn .bar {
  width: calc(var(--u) * 11);
  height: calc(var(--u) * 36);
  border-radius: calc(var(--u) * 3);
  background: #fff;
}
#pause-btn:active { transform: scale(0.93); }
#pause-btn.hidden { display: none; }

/* ---------- Overlays ---------- */

.overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(6, 19, 38, 0.72);
  -webkit-backdrop-filter: blur(calc(var(--u) * 5));
  backdrop-filter: blur(calc(var(--u) * 5));
  z-index: 5;
  pointer-events: auto;
}
.overlay.hidden { display: none; }

/* The painted title plate is the screen. Nothing is dimmed or blurred over
   it: the instruction banner and the play button are laid on top, and the
   button covers the pill the artwork was painted with exactly, so the two
   never show as a double. The numbers below are fractions of the 1920x1080
   plate measured off that pill. */
#ov-start {
  background: #0b2545 url("../assets/start-bg.png?v=0aa02b1359") center / 100% 100% no-repeat;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

/* Deliberately not .arcade: the plate's lettering is upright and mixed-case,
   and .arcade is italic, uppercase, outlined and nowrap. */
.start-how {
  position: absolute;
  font-family: inherit;
  font-weight: 700;
  font-style: normal;
  white-space: normal;
  text-transform: none;
  -webkit-text-stroke: 0;
  /* Centred right of middle, so it starts clear of Jason's face. */
  left: calc(var(--u) * 1215);
  transform: translateX(-50%);
  /* Sized to its text and lifted clear of the floor: in this title art the
     hoop, the coins and Jason's stride all sit low in the frame, and a
     full-width banner at the old height hid exactly the imagery it describes. */
  top: calc(var(--u) * 628);
  width: max-content;
  max-width: calc(var(--u) * 1320);
  box-sizing: border-box;
  padding: calc(var(--u) * 16) calc(var(--u) * 40);
  font-size: calc(var(--u) * 30);
  line-height: 1.24;
  text-align: center;
  color: #ffffff;
  /* Opaque: the plate has this same banner painted into it, and a
     translucent one on top shows the painted text as a faint ghost. */
  background: rgb(8, 30, 63);
  border: calc(var(--u) * 3) solid rgba(110, 180, 255, 0.85);
  border-radius: calc(var(--u) * 54);
  box-shadow: 0 calc(var(--u) * 6) calc(var(--u) * 18) rgba(0, 0, 0, 0.45);
  pointer-events: none;
}

.start-play {
  position: absolute;
  white-space: nowrap;
  text-transform: none;
  left: calc(var(--u) * 577);
  top: calc(var(--u) * 876);
  width: calc(var(--u) * 761);
  height: calc(var(--u) * 155);
  font-family: inherit;
  font-weight: 900;
  font-style: normal;
  font-size: calc(var(--u) * 54);
  letter-spacing: 0.005em;
  color: #123a8a;
  -webkit-text-stroke: 0;
  text-shadow: 0 calc(var(--u) * 2) 0 rgba(255, 255, 255, 0.45);
  border: calc(var(--u) * 4) solid #d18b18;
  border-radius: calc(var(--u) * 46);
  background: linear-gradient(#ffdf6b, #f0a91d);
  box-shadow:
    inset 0 calc(var(--u) * 4) calc(var(--u) * 10) rgba(255, 255, 255, 0.65),
    inset 0 calc(var(--u) * -8) calc(var(--u) * 14) rgba(184, 110, 12, 0.5),
    0 0 calc(var(--u) * 26) rgba(255, 210, 90, 0.45);
  cursor: pointer;
  pointer-events: auto;
  touch-action: manipulation;
  animation: playglow 1.6s ease-in-out infinite;
}
.start-play:active { transform: scale(0.975); }
@keyframes playglow {
  0%, 100% { box-shadow:
      inset 0 calc(var(--u) * 4) calc(var(--u) * 10) rgba(255, 255, 255, 0.65),
      inset 0 calc(var(--u) * -8) calc(var(--u) * 14) rgba(184, 110, 12, 0.5),
      0 0 calc(var(--u) * 22) rgba(255, 210, 90, 0.35); }
  50% { box-shadow:
      inset 0 calc(var(--u) * 4) calc(var(--u) * 10) rgba(255, 255, 255, 0.65),
      inset 0 calc(var(--u) * -8) calc(var(--u) * 14) rgba(184, 110, 12, 0.5),
      0 0 calc(var(--u) * 40) rgba(255, 220, 110, 0.7); }
}

#ov-start .gear {
  position: absolute;
  right: calc(var(--u) * 34);
  bottom: calc(var(--u) * 34);
  margin-top: 0;
}

/* Sits beside the gear, same shape and weight. Two corner brackets drawn in
   CSS so there is no extra asset. */
.expand {
  position: absolute;
  right: calc(var(--u) * 130);
  bottom: calc(var(--u) * 34);
  width: calc(var(--u) * 78);
  height: calc(var(--u) * 78);
  border: calc(var(--u) * 4) solid rgba(255, 255, 255, 0.8);
  border-radius: 50%;
  background: rgba(10, 32, 56, 0.55);
  cursor: pointer;
  pointer-events: auto;
  touch-action: manipulation;
}
.expand.hidden { display: none; }
.expand:active { transform: scale(0.93); }
.expand::before,
.expand::after {
  content: "";
  position: absolute;
  width: calc(var(--u) * 17);
  height: calc(var(--u) * 17);
  border: calc(var(--u) * 5) solid #fff;
}
.expand::before {
  top: calc(var(--u) * 19);
  left: calc(var(--u) * 19);
  border-right: 0;
  border-bottom: 0;
}
.expand::after {
  right: calc(var(--u) * 19);
  bottom: calc(var(--u) * 19);
  border-left: 0;
  border-top: 0;
}

.panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--u) * 14);
  padding: calc(var(--u) * 40) calc(var(--u) * 62);
  text-align: center;
}

.title {
  font-size: calc(var(--u) * 132);
  line-height: 1;
  color: #ffd757;
  -webkit-text-stroke: calc(var(--u) * 8) #0a2038;
  letter-spacing: 0.01em;
}
.title.small-title { font-size: calc(var(--u) * 96); color: #fff; }

.sub { font-size: calc(var(--u) * 34); opacity: 0.95; }

/* The parody disclaimer on the loading screen. Quiet, but legible on a phone:
   the panel is only ~700u wide at a landscape phone size, so it wraps to three
   or four lines rather than sprawling. */
.disclaimer {
  font-family: inherit;
  font-weight: 700;
  font-style: normal;
  text-transform: none;
  -webkit-text-stroke: 0;
  max-width: calc(var(--u) * 900);
  margin-top: calc(var(--u) * 6);
  font-size: calc(var(--u) * 24);
  line-height: 1.35;
  color: rgba(255, 255, 255, 0.72);
  text-align: center;
}
.sub.small { font-size: calc(var(--u) * 26); opacity: 0.8; }

.tap {
  font-size: calc(var(--u) * 46);
  margin-top: calc(var(--u) * 10);
  color: #8ee3ff;
  animation: pulse 1.05s ease-in-out infinite;
}
@keyframes pulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.55; transform: scale(0.96); } }

.stats {
  display: flex;
  gap: calc(var(--u) * 40);
  margin: calc(var(--u) * 6) 0 calc(var(--u) * 4);
}
.stat { display: flex; flex-direction: column; gap: calc(var(--u) * 4); }
.label { font-size: calc(var(--u) * 26); opacity: 0.78; font-style: normal; }
.value { font-size: calc(var(--u) * 52); color: #ffd757; }

.newbest {
  font-size: calc(var(--u) * 34);
  color: #8ee3ff;
  animation: pulse 0.9s ease-in-out infinite;
}
.newbest.hidden { display: none; }

/* ---------- Buttons ---------- */

.btn {
  font-family: inherit;
  font-weight: 900;
  font-style: italic;
  text-transform: uppercase;
  font-size: calc(var(--u) * 42);
  color: #0a2038;
  -webkit-text-stroke: 0;
  text-shadow: none;
  padding: calc(var(--u) * 16) calc(var(--u) * 52);
  border: calc(var(--u) * 5) solid #0a2038;
  border-radius: calc(var(--u) * 18);
  background: linear-gradient(#ffe27a, #f5b62c);
  box-shadow: 0 calc(var(--u) * 7) 0 #9a6410, 0 calc(var(--u) * 12) calc(var(--u) * 20) rgba(0, 0, 0, 0.45);
  cursor: pointer;
  touch-action: manipulation;
  margin-top: calc(var(--u) * 10);
}
.btn:active { transform: translateY(calc(var(--u) * 5)); box-shadow: 0 calc(var(--u) * 2) 0 #9a6410; }

.btn.ghost {
  font-size: calc(var(--u) * 28);
  padding: calc(var(--u) * 11) calc(var(--u) * 34);
  color: #fff;
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.7);
  box-shadow: none;
}
.btn.ghost:active { transform: translateY(calc(var(--u) * 3)); }

/* ---------- Loading bar ---------- */

.loadbar {
  width: calc(var(--u) * 520);
  height: calc(var(--u) * 22);
  border: calc(var(--u) * 4) solid rgba(255, 255, 255, 0.85);
  border-radius: calc(var(--u) * 11);
  overflow: hidden;
  background: rgba(0, 0, 0, 0.35);
}
#load-fill {
  width: 0%;
  height: 100%;
  background: linear-gradient(90deg, #8ee3ff, #ffd757);
  transition: width 0.15s linear;
}

/* ---------- Volume ---------- */

.volume {
  display: flex;
  align-items: center;
  gap: calc(var(--u) * 16);
  margin-top: calc(var(--u) * 10);
  padding: calc(var(--u) * 12) calc(var(--u) * 24);
  border: calc(var(--u) * 3) solid rgba(255, 255, 255, 0.45);
  border-radius: calc(var(--u) * 16);
  background: rgba(7, 21, 43, 0.5);
  pointer-events: auto;
  touch-action: manipulation;
}
.vol-label {
  font-size: calc(var(--u) * 26);
  min-width: calc(var(--u) * 130);
  text-align: left;
}
.vol-value {
  font-size: calc(var(--u) * 26);
  min-width: calc(var(--u) * 54);
  text-align: right;
}

.vol-slider {
  -webkit-appearance: none;
  appearance: none;
  width: calc(var(--u) * 340);
  height: calc(var(--u) * 20);
  border-radius: calc(var(--u) * 10);
  background: linear-gradient(90deg, #8ee3ff, #ffd757);
  border: calc(var(--u) * 3) solid rgba(10, 32, 56, 0.9);
  outline: none;
  cursor: pointer;
}
.vol-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: calc(var(--u) * 40);
  height: calc(var(--u) * 40);
  border-radius: 50%;
  background: #fff;
  border: calc(var(--u) * 4) solid #0a2038;
  box-shadow: 0 calc(var(--u) * 3) calc(var(--u) * 6) rgba(0, 0, 0, 0.5);
}
.vol-slider::-moz-range-thumb {
  width: calc(var(--u) * 40);
  height: calc(var(--u) * 40);
  border-radius: 50%;
  background: #fff;
  border: calc(var(--u) * 4) solid #0a2038;
}

/* ---------- Miss Megs end screen ---------- */
/* She fills the frame; a scrim across the lower half carries the tally so her
   face stays clear. */

#ov-gameover { background: #05101f; backdrop-filter: none; -webkit-backdrop-filter: none; }

.megs-card {
  position: absolute;
  inset: 0;
  background: url("../assets/missmegs.png?v=e590bfc4b5") no-repeat center / cover;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

.megs-scrim {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--u) * 12);
  padding: calc(var(--u) * 26) calc(var(--u) * 40) calc(var(--u) * 30);
  background: linear-gradient(to bottom,
              rgba(5, 16, 31, 0) 0%,
              rgba(5, 16, 31, 0.72) 22%,
              rgba(5, 16, 31, 0.92) 55%);
}

.megs-title {
  font-size: calc(var(--u) * 62);
  color: #ffd757;
  -webkit-text-stroke: calc(var(--u) * 6) #0a2038;
  line-height: 1;
}

.megs-docs {
  display: flex;
  gap: calc(var(--u) * 18);
  margin-top: calc(var(--u) * 4);
}
.megs-doc {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--u) * 7);
  width: calc(var(--u) * 196);
}
.megs-doc i {
  width: calc(var(--u) * 120);
  height: calc(var(--u) * 120);
  border: calc(var(--u) * 5) dashed rgba(255, 255, 255, 0.45);
  border-radius: calc(var(--u) * 18);
  background: rgba(255, 255, 255, 0.06) no-repeat center / 76% auto;
  /* Empty slots stay as dashed outlines, so what is MISSING reads as loudly
     as what was collected - that is the point of the screen. */
}
.megs-doc span {
  font-size: calc(var(--u) * 22);
  opacity: 0.62;
  white-space: nowrap;
}
.megs-doc.got i {
  border: calc(var(--u) * 5) solid rgba(255, 215, 87, 0.95);
  background-color: rgba(10, 32, 56, 0.72);
  box-shadow: 0 0 calc(var(--u) * 20) rgba(255, 215, 87, 0.5);
}
.megs-doc.got span { opacity: 1; color: #ffd757; }

.megs-doc[data-doc="voter"] i    { background-image: url("../assets/prop-voter.png?v=b3b8ec174e"); }
.megs-doc[data-doc="ack"] i      { background-image: url("../assets/prop-ack.png?v=3bd75765da"); }
.megs-doc[data-doc="status"] i   { background-image: url("../assets/prop-status.png?v=2fda4edbda"); }
.megs-doc[data-doc="passport"] i { background-image: url("../assets/prop-passport.png?v=9a42026ced"); }
.megs-doc:not(.got) i { filter: grayscale(1) brightness(0.5); }

#ov-gameover .stats { gap: calc(var(--u) * 46); margin: calc(var(--u) * 2) 0 0; }
#ov-gameover .value { font-size: calc(var(--u) * 44); }
#ov-gameover .btn { margin-top: calc(var(--u) * 6); }

/* ---------- Settings gear ---------- */

.gear {
  width: calc(var(--u) * 78);
  height: calc(var(--u) * 78);
  margin-top: calc(var(--u) * 14);
  border: calc(var(--u) * 4) solid rgba(255, 255, 255, 0.8);
  border-radius: 50%;
  background: rgba(10, 32, 56, 0.55);
  cursor: pointer;
  pointer-events: auto;
  touch-action: manipulation;
  position: relative;
}
.gear:active { transform: scale(0.93); }
/* An inline SVG cog: it is the one shape CSS borders cannot fake convincingly,
   and as a vector it stays sharp at every --u. */
.gear svg {
  position: absolute;
  inset: calc(var(--u) * 13);
  width: calc(100% - var(--u) * 26);
  height: calc(100% - var(--u) * 26);
  fill: #fff;
  display: block;
}

#ov-settings .panel { gap: calc(var(--u) * 10); }
#ov-settings .volume { min-width: calc(var(--u) * 620); }

/* ---------- Victory end screen + license form ---------- */

#ov-gameover.victory .megs-card { background-image: url("../assets/missmegs-happy.png?v=68db385f62"); }
#ov-gameover.victory .megs-title { color: #8ee3ff; }

/* Top-left of the lobby, clear of Miss Megs and of the title. */
.btn.learn {
  position: absolute;
  top: calc(var(--u) * 26);
  left: calc(var(--u) * 30);
  margin-top: 0;
  font-size: calc(var(--u) * 26);
  padding: calc(var(--u) * 11) calc(var(--u) * 22);
  background: linear-gradient(#9ee8ff, #35a9d8);
  z-index: 2;
}

.megs-buttons {
  display: flex;
  gap: calc(var(--u) * 20);
  align-items: center;
}
.btn.license { background: linear-gradient(#9ee8ff, #35a9d8); }
.btn.hidden, .lic-result.hidden, .lic-form.hidden, .lic-file.hidden { display: none; }

.license-panel {
  padding: calc(var(--u) * 30) calc(var(--u) * 48);
  max-height: 96%;
}

.lic-form {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--u) * 8);
}

/* The live license. Sized so the whole form still clears the panel on a
   short landscape phone; the canvas keeps the card's own 1.586 ratio. */
.lic-live {
  width: calc(var(--u) * 640);
  height: auto;
  border-radius: calc(var(--u) * 10);
}

.lic-fields {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: calc(var(--u) * 18);
  flex-wrap: wrap;
}
.lic-col {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--u) * 10);
}
.lic-photo-btns { display: flex; gap: calc(var(--u) * 8); }
.btn.tiny {
  font-size: calc(var(--u) * 24);
  padding: calc(var(--u) * 10) calc(var(--u) * 18);
  margin-top: 0;
  border-width: calc(var(--u) * 3);
}

/* The selfie camera, over the form while it is open. */
.lic-camera {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--u) * 14);
}
.lic-camera.hidden { display: none; }
#lic-video {
  width: calc(var(--u) * 520);
  height: calc(var(--u) * 390);
  object-fit: cover;
  border-radius: calc(var(--u) * 14);
  border: calc(var(--u) * 4) solid rgba(255, 255, 255, 0.6);
  background: #06182f;
  transform: scaleX(-1);          /* a mirror is what people expect of a selfie */
}

.lic-label { font-size: calc(var(--u) * 24); line-height: 1; }
.lic-label span { opacity: 0.6; }
.lic-input {
  font-family: inherit;
  font-weight: 900;
  font-size: calc(var(--u) * 32);
  width: calc(var(--u) * 300);
  padding: calc(var(--u) * 12) calc(var(--u) * 18);
  border: calc(var(--u) * 4) solid rgba(255, 255, 255, 0.7);
  border-radius: calc(var(--u) * 14);
  background: rgba(7, 21, 43, 0.75);
  color: #fff;
  text-align: center;
}
.lic-file {
  font-family: inherit;
  font-size: calc(var(--u) * 22);
  color: #fff;
  max-width: calc(var(--u) * 560);
}
.lic-note {
  font-family: inherit;
  font-size: calc(var(--u) * 20);
  color: rgba(255, 255, 255, 0.7);
  margin-top: calc(var(--u) * 2);
  text-align: center;
  max-width: calc(var(--u) * 620);
}
.lic-note.error { color: #ffb0a6; }

.lic-result {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--u) * 12);
}
#lic-preview {
  height: calc(var(--u) * 520);
  width: auto;
  border-radius: calc(var(--u) * 14);
  border: calc(var(--u) * 4) solid rgba(255, 255, 255, 0.5);
}
.lic-share {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: calc(var(--u) * 14);
}
.lic-share .btn { font-size: calc(var(--u) * 28); padding: calc(var(--u) * 11) calc(var(--u) * 26); margin-top: 0; }
a.btn { text-decoration: none; display: inline-block; }

/* ---------- Rules screen ---------- */
/* Everything is calc(var(--u) * N), so one layout is correct at every size -
   no breakpoints, because --u IS the breakpoint. */

.rules-panel {
  gap: calc(var(--u) * 10);
  padding: calc(var(--u) * 20) calc(var(--u) * 40);
}
.rules-line {
  font-family: inherit;
  font-weight: 900;
  font-size: calc(var(--u) * 36);
  color: #ffd757;
  text-align: center;
}
.rules-group { display: flex; flex-direction: column; align-items: center; gap: calc(var(--u) * 5); }
.rules-head {
  font-size: calc(var(--u) * 22);
  opacity: 0.72;
  -webkit-text-stroke: 0;
}
.rules-strip {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: calc(var(--u) * 20);
}
.rules-item {
  width: calc(var(--u) * 148);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--u) * 4);
}
.rules-item img {
  width: 100%;
  height: calc(var(--u) * 82);
  object-fit: contain;
  filter: drop-shadow(0 calc(var(--u) * 3) calc(var(--u) * 5) rgba(0, 0, 0, 0.55));
}
.rules-item span {
  font-size: calc(var(--u) * 17);
  line-height: 1.15;
  text-align: center;
  -webkit-text-stroke: 0;
  opacity: 0.9;
  /* .arcade is nowrap, which runs the longer labels into each other. */
  white-space: normal;
}
.rules-tap {
  font-size: calc(var(--u) * 32);
  color: #8ee3ff;
  margin-top: calc(var(--u) * 4);
  animation: pulse 1.05s ease-in-out infinite;
}
/* The loading screen carries the disclaimer but now advances on its own, so
   this is the one place a player can read it at their own pace. */
.rules-fine {
  font-family: inherit;
  font-weight: 700;
  font-style: normal;
  text-transform: none;
  -webkit-text-stroke: 0;
  font-size: calc(var(--u) * 17);
  color: rgba(255, 255, 255, 0.45);
  text-align: center;
}

/* ---------- Leaderboard ---------- */

.lb-panel { gap: calc(var(--u) * 12); min-width: calc(var(--u) * 760); }
.lb-rows {
  list-style: none;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: calc(var(--u) * 6);
}
.lb-row {
  display: flex;
  align-items: center;
  gap: calc(var(--u) * 16);
  padding: calc(var(--u) * 8) calc(var(--u) * 20);
  border-radius: calc(var(--u) * 12);
  background: rgba(255, 255, 255, 0.06);
  font-size: calc(var(--u) * 28);
}
.lb-row .lb-rank { width: calc(var(--u) * 60); color: #ffd757; }
.lb-row .lb-name { flex: 1; text-align: left; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lb-row .lb-score { color: #8ee3ff; }
.lb-row.mine { background: rgba(255, 215, 87, 0.16); }
.lb-note {
  font-family: inherit;
  font-weight: 700;
  font-style: normal;
  text-transform: none;
  -webkit-text-stroke: 0;
  font-size: calc(var(--u) * 22);
  color: rgba(255, 255, 255, 0.7);
  text-align: center;
}

/* Bottom-left of the title plate, mirroring the gear at bottom-right. */
#ov-start .lb-open {
  position: absolute;
  left: calc(var(--u) * 34);
  bottom: calc(var(--u) * 40);
  margin-top: 0;
  font-size: calc(var(--u) * 30);
  padding: calc(var(--u) * 12) calc(var(--u) * 26);
}

/* ---------- Portrait hint ---------- */
/* No JS: the media query is the whole mechanism, so it cannot get out of sync
   with the real orientation. It must never touch #stage - hiding the stage is
   what made the old rotate prompt render nothing at all. */

#rotate-hint { display: none; }

/* pointer: coarse keeps it to phones and tablets - a desktop window that
   happens to be taller than wide has nothing to rotate. */
@media (orientation: portrait) and (pointer: coarse) {
  #rotate-hint {
    display: flex;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    /* Just under the centred strip. In portrait the 16:9 box is always
       width-constrained, so its half-height is 100vw * 9/16 / 2. */
    top: calc(50% + 28.125vw);
    align-items: center;
    justify-content: center;
    padding: 0 7vw;
    text-align: center;
    color: #cfe4ff;
    font-weight: 700;
    font-size: 4.2vw;
    line-height: 1.35;
    z-index: 50;
    pointer-events: none;
  }
}

/* ---------- Score submit, on the end screen ---------- */

.score-submit {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: calc(var(--u) * 12);
  margin-top: calc(var(--u) * 4);
}
.score-submit.hidden { display: none; }
.sc-input {
  width: calc(var(--u) * 300);
  font-size: calc(var(--u) * 26);
  padding: calc(var(--u) * 9) calc(var(--u) * 14);
}
.sc-note {
  font-family: inherit;
  font-weight: 700;
  font-style: normal;
  text-transform: none;
  -webkit-text-stroke: 0;
  max-width: calc(var(--u) * 820);
  font-size: calc(var(--u) * 18);
  line-height: 1.3;
  color: rgba(255, 255, 255, 0.55);
  text-align: center;
}
.sc-note.hidden { display: none; }
.sc-note.error { color: #ffb0a6; }
.sc-note.good { color: #8ee3ff; }
