/* ==========================================================================
   Aurora Runner - HUD + menu styling (agent A6).

   Builds on styles-base.css, which already defines the brand custom properties,
   the fixed .ar-ui-root overlay and the pointer-events opt-in rule. Nothing here
   redefines those.

   Two constraints shape this file:
     - It sits on top of a bright, bloom-heavy WebGL render, so panels are really
       dark plates with a thin light sheen, not low-opacity glass. Every piece of
       text also carries its own shadow so it survives a white bloom bursting
       behind it.
     - Only transform / opacity are animated, so the compositor does the work and
       the 60fps render loop never competes with layout.
   ========================================================================== */

.ar-ui-root {
  --ar-safe-t: max(12px, env(safe-area-inset-top));
  --ar-safe-r: max(12px, env(safe-area-inset-right));
  --ar-safe-b: max(12px, env(safe-area-inset-bottom));
  --ar-safe-l: max(12px, env(safe-area-inset-left));
  --ar-beat: 132px;
  --ar-ink: #eaf9fb;
  /* Contrast note: every "dim" value below is measured against the panel plate, not against
     the tunnel. The plate is a near-opaque dark sheet precisely so those ratios hold even
     when the bloom behind it goes white - a translucent panel is where HUD contrast dies. */
  --ar-dim: rgba(210, 240, 244, 0.82);
  --ar-plate: linear-gradient(160deg, rgba(7, 11, 24, 0.93) 0%, rgba(3, 5, 12, 0.88) 100%);
  --ar-glow-c: 0 0 18px rgba(92, 225, 230, 0.45);
  --ar-shadow-txt: 0 1px 3px rgba(0, 0, 0, 0.95), 0 0 14px rgba(0, 0, 0, 0.7);
  --ar-edge: rgba(92, 225, 230, 0.42);
}

/* --------------------------------------------------------------- primitives */

.ar-panel {
  position: relative;
  background: var(--ar-plate);
  border: 1px solid var(--oao-line);
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, 0.55),
    0 10px 34px rgba(0, 0, 0, 0.55),
    inset 0 1px 0 rgba(255, 255, 255, 0.06);
  -webkit-backdrop-filter: blur(9px) saturate(1.15);
  backdrop-filter: blur(9px) saturate(1.15);
}

/* subtle scanline texture, panel-local so it never becomes a full-screen layer */
.ar-panel::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: repeating-linear-gradient(
    180deg,
    rgba(0, 0, 0, 0.22) 0 1px,
    rgba(255, 255, 255, 0.012) 1px 3px
  );
  opacity: 0.55;
  z-index: 0;
}
.ar-panel > * { position: relative; z-index: 1; }

.ar-label {
  display: block;
  font-family: var(--ar-mono);
  font-size: 9.5px;
  line-height: 1.2;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ar-dim);
  text-shadow: var(--ar-shadow-txt);
}

.ar-unit {
  font-family: var(--ar-mono);
  font-size: 9px;
  letter-spacing: 0.16em;
  color: rgba(206, 238, 242, 0.72);
  text-shadow: var(--ar-shadow-txt);
}

.ar-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* corner brackets ---------------------------------------------------------- */
.ar-brackets { position: absolute; inset: 0; pointer-events: none; z-index: 2; }
.ar-br {
  position: absolute;
  width: 14px;
  height: 14px;
  border: 0 solid var(--oao-cyan);
  opacity: 0.85;
}
.ar-br--tl { top: -1px; left: -1px; border-top-width: 2px; border-left-width: 2px; }
.ar-br--tr { top: -1px; right: -1px; border-top-width: 2px; border-right-width: 2px; }
.ar-br--bl { bottom: -1px; left: -1px; border-bottom-width: 2px; border-left-width: 2px; }
.ar-br--br { bottom: -1px; right: -1px; border-bottom-width: 2px; border-right-width: 2px; }

/* ================================================================= THE HUD = */

.ar-hud {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.28s ease, visibility 0.28s ease;
}
.ar-hud.is-on { opacity: 1; visibility: visible; }

.ar-hud-corner { position: absolute; display: flex; flex-direction: column; gap: 8px; }
.ar-hud-tl { top: var(--ar-safe-t); left: var(--ar-safe-l); align-items: flex-start; }
.ar-hud-tr { top: var(--ar-safe-t); right: var(--ar-safe-r); align-items: flex-end; }

/* --- score / multiplier / combo ------------------------------------------- */
.ar-score-panel { padding: 8px 14px 10px; min-width: 168px; }

.ar-score-row { display: flex; align-items: baseline; gap: 10px; }

.ar-score {
  font-family: var(--ar-mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  font-size: clamp(30px, 6.2vw, 46px);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: 0.01em;
  color: #fff;
  text-shadow: 0 2px 6px rgba(0, 0, 0, 0.95), 0 0 22px rgba(92, 225, 230, 0.5);
}

.ar-mult {
  font-family: var(--ar-mono);
  font-size: clamp(15px, 2.6vw, 20px);
  font-weight: 700;
  line-height: 1;
  padding: 3px 7px 4px;
  color: #10060a;
  background: linear-gradient(160deg, var(--oao-orange-2), var(--oao-orange));
  border-radius: 3px;
  box-shadow: 0 0 16px rgba(255, 107, 53, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.5);
  transform-origin: 50% 60%;
  will-change: transform;
}

.ar-combo { margin-top: 8px; display: flex; align-items: center; gap: 8px; }
.ar-combo-track {
  position: relative;
  flex: 1 1 auto;
  height: 3px;
  min-width: 88px;
  background: rgba(92, 225, 230, 0.14);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.5);
  overflow: hidden;
}
.ar-combo-fill {
  display: block;
  width: 100%;
  height: 100%;
  transform: scaleX(0);
  transform-origin: 0 50%;
  background: linear-gradient(90deg, var(--oao-cyan-2), var(--oao-cyan));
  box-shadow: 0 0 12px rgba(92, 225, 230, 0.75);
  will-change: transform;
}
.ar-combo-label {
  font-family: var(--ar-mono);
  font-size: 8.5px;
  letter-spacing: 0.2em;
  color: rgba(206, 238, 242, 0.72);
  text-shadow: var(--ar-shadow-txt);
}

/* --- shields --------------------------------------------------------------- */
.ar-shield-panel { padding: 7px 12px 9px; }
.ar-shields { display: flex; gap: 6px; margin-top: 5px; }

.ar-chev { width: 26px; height: 20px; transform-origin: 50% 60%; }
.ar-chev svg { display: block; width: 100%; height: 100%; overflow: visible; }
.ar-chev-core {
  fill: var(--oao-cyan);
  filter: drop-shadow(0 0 6px rgba(92, 225, 230, 0.8));
  transition: fill 0.25s ease, filter 0.25s ease;
}
.ar-chev.is-lost .ar-chev-core { fill: rgba(255, 255, 255, 0.1); filter: none; }
.ar-shard {
  opacity: 0;
  fill: var(--oao-danger);
  transform-box: fill-box;
  transform-origin: center;
}
.ar-shard--l { --sx: -8px; --sy: -5px; --sr: -38deg; }
.ar-shard--c { --sx: 0px;  --sy: -10px; --sr: 18deg; }
.ar-shard--r { --sx: 8px;  --sy: -5px; --sr: 38deg; }

/* --- distance / speed ------------------------------------------------------ */
.ar-stat-panel { padding: 7px 12px 8px; display: flex; flex-direction: column; gap: 3px; }
.ar-stat { display: flex; align-items: baseline; justify-content: flex-end; gap: 6px; }
.ar-stat .ar-label { display: inline-block; min-width: 30px; text-align: right; }
.ar-stat-v {
  font-family: var(--ar-mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  font-size: 15px;
  font-weight: 600;
  color: var(--ar-ink);
  min-width: 54px;
  text-align: right;
  text-shadow: var(--ar-shadow-txt);
}

/* ====================================================== THE BEAT TELEGRAPH = */
/* Bottom centre: visible in peripheral vision while the player watches the
   vanishing point, and clear of both thumbs in one-handed portrait play. */

.ar-beat-cluster {
  position: absolute;
  left: 50%;
  bottom: calc(var(--ar-safe-b) + 6px);
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
  pointer-events: none;
}

.ar-beat { position: relative; width: var(--ar-beat); height: var(--ar-beat); }

/* soft dark disc so the telegraph keeps its contrast when the bloom goes white */
.ar-beat::before {
  content: "";
  position: absolute;
  inset: -22%;
  border-radius: 50%;
  pointer-events: none;
  background: radial-gradient(
    circle,
    rgba(2, 4, 10, 0.68) 0%,
    rgba(2, 4, 10, 0.5) 46%,
    rgba(2, 4, 10, 0) 72%
  );
}

.ar-beat-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.ar-arc-track {
  fill: none;
  stroke: rgba(6, 12, 24, 0.85);
  stroke-width: 5.5;
}
.ar-arc-fill {
  fill: none;
  stroke: url(#ar-boost-grad);
  stroke-width: 4;
  stroke-linecap: round;
  transform-box: fill-box;
  transform-origin: center;
  transform: rotate(-90deg);
  filter: drop-shadow(0 0 7px rgba(255, 107, 53, 0.75));
}

/* the converging cue - JS drives scale from state.audio.beatPhase every frame */
.ar-beat-ring,
.ar-beat-flash {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 72.7%;
  height: 72.7%;
  border-radius: 50%;
  will-change: transform, opacity;
  pointer-events: none;
}
/* the dark 1px halo either side of the stroke is what keeps a thin cyan ring readable
   on top of a white bloom bursting out of the tunnel */
.ar-beat-ring {
  border: 2px solid var(--oao-cyan);
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, 0.75),
    inset 0 0 0 1px rgba(0, 0, 0, 0.6),
    0 0 22px rgba(92, 225, 230, 0.6),
    inset 0 0 16px rgba(92, 225, 230, 0.2);
  opacity: 0;
}
.ar-beat-ring.is-window {
  border-color: #ffffff;
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, 0.75),
    inset 0 0 0 1px rgba(0, 0, 0, 0.6),
    0 0 28px rgba(255, 255, 255, 0.65),
    inset 0 0 18px rgba(92, 225, 230, 0.35);
}
.ar-beat-flash {
  border: 2px solid #ffffff;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.55), 0 0 30px rgba(255, 255, 255, 0.6);
  opacity: 0;
}

.ar-beat-core {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 47%;
  height: 47%;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background:
    radial-gradient(circle at 50% 38%, rgba(92, 225, 230, 0.22), rgba(4, 6, 14, 0.9) 72%);
  border: 1px solid rgba(92, 225, 230, 0.45);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.7), inset 0 0 14px rgba(92, 225, 230, 0.18);
  transform-origin: 50% 50%;
  will-change: transform;
  transition: border-color 0.09s linear, opacity 0.2s ease;
}
.ar-beat-core.is-window {
  border-color: #ffffff;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.7), 0 0 24px rgba(255, 255, 255, 0.3),
    inset 0 0 16px rgba(255, 255, 255, 0.14);
}
.ar-beat-core.is-empty { opacity: 0.42; }

.ar-beat-icon { width: 46%; height: 46%; display: block; }
.ar-beat-icon svg {
  display: block;
  width: 100%;
  height: 100%;
  fill: var(--oao-cyan);
  filter: drop-shadow(0 0 8px rgba(92, 225, 230, 0.85));
  transition: fill 0.09s linear;
}
.ar-beat-core.is-window .ar-beat-icon svg {
  fill: var(--oao-orange-2);
  filter: drop-shadow(0 0 10px rgba(255, 133, 0, 0.9));
}

.ar-beat-hint {
  font-family: var(--ar-mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.26em;
  text-indent: 0.26em;
  text-transform: uppercase;
  color: #ffffff;
  padding: 3px 10px 4px;
  background: rgba(4, 6, 14, 0.72);
  border: 1px solid rgba(255, 107, 53, 0.55);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.95), 0 0 16px rgba(255, 107, 53, 0.65);
  animation: ar-hint-breathe 1.6s ease-in-out infinite;
  will-change: opacity;
}
.ar-beat-hint.is-learned {
  color: var(--ar-dim);
  border-color: var(--oao-line);
  background: rgba(4, 6, 14, 0.55);
  text-shadow: var(--ar-shadow-txt);
  animation: none;
}

.ar-beat-key {
  font-family: var(--ar-mono);
  font-size: 8.5px;
  letter-spacing: 0.2em;
  color: rgba(206, 238, 242, 0.66);
  text-shadow: var(--ar-shadow-txt);
}

@keyframes ar-hint-breathe {
  0%, 100% { opacity: 0.7; }
  50% { opacity: 1; }
}

/* ------------------------------------------------- floating combat text ---- */

.ar-float-layer {
  position: absolute;
  left: 50%;
  bottom: calc(var(--ar-safe-b) + var(--ar-beat) + 58px);
  width: 0;
  height: 0;
  pointer-events: none;
}

.ar-float {
  position: absolute;
  left: 0;
  bottom: 0;
  opacity: 0;
  white-space: nowrap;
  font-family: var(--ar-mono);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.14em;
  will-change: transform, opacity;
  transform: translate(calc(-50% + var(--ar-lane, 0px)), 0);
}
.ar-float--sync { color: var(--oao-cyan); text-shadow: 0 2px 5px rgba(0,0,0,.9), 0 0 18px rgba(92,225,230,.9); }
.ar-float--perfect { color: #fff; font-size: 19px; text-shadow: 0 2px 5px rgba(0,0,0,.9), 0 0 22px rgba(255,133,0,.95); }
.ar-float--orb { color: var(--oao-orange-2); text-shadow: 0 2px 5px rgba(0,0,0,.9), 0 0 18px rgba(255,133,0,.85); }
.ar-float--shield { color: var(--oao-danger); text-shadow: 0 2px 5px rgba(0,0,0,.9), 0 0 18px rgba(255,45,85,.9); }

/* Two identical animations under different names: re-applying the class is how a
   pooled node restarts its animation without a forced reflow read. */
@keyframes ar-fl-a {
  0%   { opacity: 0; transform: translate(calc(-50% + var(--ar-lane, 0px)), calc(14px + var(--ar-row, 0px))) scale(0.78); }
  12%  { opacity: 1; transform: translate(calc(-50% + var(--ar-lane, 0px)), calc(0px + var(--ar-row, 0px))) scale(1.14); }
  26%  { opacity: 1; transform: translate(calc(-50% + var(--ar-lane, 0px)), calc(-8px + var(--ar-row, 0px))) scale(1); }
  100% { opacity: 0; transform: translate(calc(-50% + var(--ar-lane, 0px)), calc(-78px + var(--ar-row, 0px))) scale(0.94); }
}
@keyframes ar-fl-b {
  0%   { opacity: 0; transform: translate(calc(-50% + var(--ar-lane, 0px)), calc(14px + var(--ar-row, 0px))) scale(0.78); }
  12%  { opacity: 1; transform: translate(calc(-50% + var(--ar-lane, 0px)), calc(0px + var(--ar-row, 0px))) scale(1.14); }
  26%  { opacity: 1; transform: translate(calc(-50% + var(--ar-lane, 0px)), calc(-8px + var(--ar-row, 0px))) scale(1); }
  100% { opacity: 0; transform: translate(calc(-50% + var(--ar-lane, 0px)), calc(-78px + var(--ar-row, 0px))) scale(0.94); }
}
.ar-float.ar-anim-a { animation: ar-fl-a 1.15s cubic-bezier(0.16, 0.9, 0.3, 1) forwards; }
.ar-float.ar-anim-b { animation: ar-fl-b 1.15s cubic-bezier(0.16, 0.9, 0.3, 1) forwards; }

@keyframes ar-pop-a {
  0% { transform: scale(1); }
  32% { transform: scale(1.42); }
  100% { transform: scale(1); }
}
@keyframes ar-pop-b {
  0% { transform: scale(1); }
  32% { transform: scale(1.42); }
  100% { transform: scale(1); }
}
.ar-mult.ar-anim-a { animation: ar-pop-a 0.4s cubic-bezier(0.2, 1.4, 0.4, 1); }
.ar-mult.ar-anim-b { animation: ar-pop-b 0.4s cubic-bezier(0.2, 1.4, 0.4, 1); }

@keyframes ar-shard-a {
  0% { opacity: 1; transform: translate(0, 0) rotate(0deg); }
  100% { opacity: 0; transform: translate(var(--sx), var(--sy)) rotate(var(--sr)); }
}
@keyframes ar-shard-b {
  0% { opacity: 1; transform: translate(0, 0) rotate(0deg); }
  100% { opacity: 0; transform: translate(var(--sx), var(--sy)) rotate(var(--sr)); }
}
.ar-chev.is-lost.ar-anim-a .ar-shard { animation: ar-shard-a 0.62s ease-out forwards; }
.ar-chev.is-lost.ar-anim-b .ar-shard { animation: ar-shard-b 0.62s ease-out forwards; }

@keyframes ar-gain-a {
  0% { transform: scale(0.5); }
  55% { transform: scale(1.3); }
  100% { transform: scale(1); }
}
@keyframes ar-gain-b {
  0% { transform: scale(0.5); }
  55% { transform: scale(1.3); }
  100% { transform: scale(1); }
}
.ar-chev.is-gain.ar-anim-a { animation: ar-gain-a 0.45s ease-out; }
.ar-chev.is-gain.ar-anim-b { animation: ar-gain-b 0.45s ease-out; }

/* =================================================================== MENUS = */

.ar-menu-layer { position: absolute; inset: 0; pointer-events: none; }

.ar-screen {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: calc(var(--ar-safe-t) + 4px) calc(var(--ar-safe-r) + 4px)
           calc(var(--ar-safe-b) + 4px) calc(var(--ar-safe-l) + 4px);
  overflow-y: auto;
  background:
    radial-gradient(ellipse at 50% 45%, rgba(5, 8, 22, 0.78) 0%, rgba(1, 2, 7, 0.94) 78%);
  opacity: 0;
  visibility: hidden;
  /* visibility flips instantly on open and is held back until the fade-out finishes on
     close - an element inside a visibility:hidden subtree cannot take focus, and the
     opening screen needs to be focusable on the very next frame */
  transition: opacity 0.3s ease, visibility 0s linear 0.3s;
}
.ar-screen.is-open {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.3s ease, visibility 0s linear 0s;
}

.ar-panel--menu {
  width: min(560px, 100%);
  padding: 26px 26px 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  text-align: center;
}
.ar-panel--compact { width: min(430px, 100%); gap: 12px; }

/* --- wordmark -------------------------------------------------------------- */
.ar-logo {
  margin: 0;
  font-family: var(--ar-mono);
  font-size: clamp(26px, 8vw, 50px);
  font-weight: 700;
  line-height: 1.02;
  letter-spacing: 0.16em;
  text-indent: 0.16em;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.ar-logo-a { color: var(--oao-cyan); text-shadow: 0 0 26px rgba(92, 225, 230, 0.55); }
.ar-logo-b {
  color: var(--oao-orange);
  text-shadow: 0 0 26px rgba(255, 107, 53, 0.5);
  border-top: 1px solid var(--oao-line);
  padding-top: 4px;
}

.ar-pitch {
  margin: 0;
  max-width: 44ch;
  font-size: 14px;
  line-height: 1.55;
  color: var(--ar-ink);
  text-shadow: var(--ar-shadow-txt);
}

/* --- how to play ----------------------------------------------------------- */
.ar-howto {
  list-style: none;
  margin: 2px 0 0;
  padding: 12px 14px;
  width: 100%;
  text-align: left;
  border: 1px solid var(--oao-line);
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.ar-howto-row { display: flex; gap: 10px; align-items: baseline; font-size: 13px; line-height: 1.45; }
.ar-howto-k {
  flex: 0 0 auto;
  min-width: 58px;
  font-family: var(--ar-mono);
  font-size: 10.5px;
  letter-spacing: 0.18em;
  color: var(--oao-orange-2);
  text-shadow: 0 0 12px rgba(255, 133, 0, 0.5);
}
.ar-howto-v { color: rgba(240, 252, 253, 0.96); }
.ar-howto-v--touch { display: none; }
html.ar-touch-mode .ar-howto-v--key { display: none; }
html.ar-touch-mode .ar-howto-v--touch { display: inline; }

/* --- buttons --------------------------------------------------------------- */
.ar-btn {
  position: relative;
  appearance: none;
  -webkit-appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin: 0;
  padding: 11px 22px;
  min-height: 44px;
  font-family: var(--ar-mono);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-indent: 0.22em;
  color: var(--ar-ink);
  background: rgba(6, 10, 22, 0.82);
  border: 1px solid var(--ar-edge);
  border-radius: 2px;
  cursor: pointer;
  text-shadow: var(--ar-shadow-txt);
  transition: background 0.16s ease, border-color 0.16s ease, transform 0.1s ease,
    color 0.16s ease, box-shadow 0.16s ease;
}
.ar-btn:hover { background: rgba(92, 225, 230, 0.18); border-color: var(--oao-cyan); }
.ar-btn:active { transform: translateY(1px); }

.ar-cta {
  margin-top: 4px;
  min-width: min(280px, 100%);
  padding: 15px 30px;
  font-size: 15px;
  color: #12060a;
  background: linear-gradient(150deg, var(--oao-orange-2) 0%, var(--oao-orange) 62%, #e4491d 100%);
  border-color: rgba(255, 190, 140, 0.7);
  box-shadow: 0 0 28px rgba(255, 107, 53, 0.45), inset 0 1px 0 rgba(255, 255, 255, 0.5);
  text-shadow: none;
}
.ar-cta:hover {
  background: linear-gradient(150deg, #ffa030 0%, var(--oao-orange-2) 62%, var(--oao-orange) 100%);
  border-color: #fff;
  color: #12060a;
  box-shadow: 0 0 38px rgba(255, 133, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.6);
}

.ar-ui-root :focus { outline: none; }
.ar-ui-root :focus-visible {
  outline: 2px solid var(--oao-cyan);
  outline-offset: 3px;
  box-shadow: 0 0 0 5px rgba(92, 225, 230, 0.22), var(--ar-glow-c);
}

/* --- options row ----------------------------------------------------------- */
.ar-best {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-family: var(--ar-mono);
}
.ar-best-v {
  font-size: 16px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--oao-cyan);
  text-shadow: 0 0 16px rgba(92, 225, 230, 0.6), var(--ar-shadow-txt);
}

.ar-options {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  padding-top: 12px;
  border-top: 1px solid var(--oao-line);
}
.ar-options--center { justify-content: center; }

.ar-btn--icon { padding: 9px 14px; font-size: 10.5px; letter-spacing: 0.18em; min-height: 40px; }
.ar-btn-ico { width: 16px; height: 16px; display: block; flex: 0 0 auto; }
.ar-btn-ico svg { display: block; width: 100%; height: 100%; fill: var(--oao-cyan); stroke: none; }
.ar-btn-ico .ar-wave { fill: none; stroke: var(--oao-cyan); stroke-width: 1.7; stroke-linecap: round; }
.ar-mute.is-muted .ar-btn-ico svg { fill: var(--oao-danger); }
.ar-mute.is-muted .ar-btn-ico .ar-wave { stroke: var(--oao-danger); }
.ar-mute.is-muted { border-color: rgba(255, 45, 85, 0.5); }

.ar-quality { display: flex; align-items: center; gap: 8px; }
.ar-select {
  appearance: none;
  -webkit-appearance: none;
  padding: 9px 30px 9px 12px;
  min-height: 40px;
  font-family: var(--ar-mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  color: var(--ar-ink);
  background-color: rgba(4, 6, 14, 0.9);
  background-image: linear-gradient(45deg, transparent 50%, var(--oao-cyan) 50%),
    linear-gradient(135deg, var(--oao-cyan) 50%, transparent 50%);
  background-position: calc(100% - 16px) 50%, calc(100% - 11px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  border: 1px solid var(--ar-edge);
  border-radius: 2px;
  cursor: pointer;
}
.ar-select option { background: #04040a; color: #eaf9fb; }

.ar-attrib {
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
  margin-top: 2px;
  font-family: var(--ar-mono);
  font-size: 9.5px;
  letter-spacing: 0.2em;
  text-decoration: none;
  color: rgba(206, 238, 242, 0.76);
  transition: color 0.16s ease;
}
.ar-attrib-v { color: var(--oao-orange); }
.ar-attrib:hover { color: var(--ar-ink); }
.ar-attrib:hover .ar-attrib-v { color: var(--oao-orange-2); text-shadow: 0 0 14px rgba(255, 133, 0, 0.7); }

/* --- pause / game over ----------------------------------------------------- */
.ar-eyebrow {
  font-family: var(--ar-mono);
  font-size: 9.5px;
  letter-spacing: 0.32em;
  text-indent: 0.32em;
  text-transform: uppercase;
  color: var(--oao-cyan);
  text-shadow: 0 0 16px rgba(92, 225, 230, 0.6);
}
.ar-heading {
  margin: 0;
  font-family: var(--ar-mono);
  font-size: clamp(24px, 7vw, 38px);
  font-weight: 700;
  letter-spacing: 0.2em;
  text-indent: 0.2em;
  color: #fff;
  text-shadow: 0 0 26px rgba(92, 225, 230, 0.45);
}

.ar-actions { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; width: 100%; }
.ar-actions .ar-cta { min-width: 200px; }

.ar-newbest {
  display: none;
  padding: 4px 12px 5px;
  font-family: var(--ar-mono);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.26em;
  text-indent: 0.26em;
  color: #12060a;
  background: linear-gradient(150deg, var(--oao-orange-2), var(--oao-orange));
  box-shadow: 0 0 22px rgba(255, 133, 0, 0.6);
}
.ar-screen--over.is-newbest .ar-newbest { display: block; }

.ar-final { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.ar-final-v {
  font-family: var(--ar-mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  font-size: clamp(38px, 12vw, 62px);
  font-weight: 700;
  line-height: 1.04;
  color: #fff;
  text-shadow: 0 0 30px rgba(92, 225, 230, 0.55), 0 2px 6px rgba(0, 0, 0, 0.9);
}

.ar-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  width: 100%;
  background: var(--oao-line);
  border: 1px solid var(--oao-line);
}
.ar-grid-cell {
  padding: 9px 12px;
  background: rgba(4, 6, 14, 0.86);
  display: flex;
  flex-direction: column;
  gap: 3px;
  align-items: flex-start;
}
.ar-grid-row { display: flex; align-items: baseline; gap: 5px; }
.ar-grid-v {
  font-family: var(--ar-mono);
  font-variant-numeric: tabular-nums;
  font-size: 17px;
  font-weight: 700;
  color: var(--ar-ink);
}
.ar-screen--over.is-newbest .ar-grid-cell:nth-child(2) .ar-grid-v { color: var(--oao-orange-2); }

/* --- leaderboard ----------------------------------------------------------- */
/* Built by Menus.js and hidden until it has rows. The endpoint is PHP and only exists in
   production, so on a dev server none of this is ever shown - which is why every block
   here starts from [hidden] rather than being faded in. */
.ar-board {
  width: 100%;
  padding: 10px 12px 11px;
  border: 1px solid var(--oao-line);
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  flex-direction: column;
  gap: 7px;
  text-align: left;
}
.ar-board[hidden] { display: none; }

.ar-board-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.ar-board-row {
  display: grid;
  /* fixed rank and score rails so the names cannot shove the numbers out of alignment */
  grid-template-columns: 2.2em minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 10px;
  padding: 4px 6px;
  font-family: var(--ar-mono);
  font-size: 12.5px;
  background: rgba(4, 6, 14, 0.5);
}
.ar-board-row:nth-child(odd) { background: rgba(8, 14, 30, 0.55); }
.ar-board-rank { color: rgba(206, 238, 242, 0.55); font-size: 10.5px; letter-spacing: 0.1em; }
.ar-board-name {
  color: var(--ar-ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ar-board-score {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  font-weight: 700;
  color: var(--oao-cyan);
}
.ar-board-row:first-child .ar-board-score { color: var(--oao-orange-2); }
.ar-board-row.is-you { box-shadow: inset 2px 0 0 var(--oao-orange); }
.ar-board-row.is-you .ar-board-name { color: var(--oao-orange-2); }

.ar-board-empty {
  margin: 0;
  font-family: var(--ar-mono);
  font-size: 10.5px;
  letter-spacing: 0.16em;
  color: rgba(206, 238, 242, 0.5);
}
.ar-board-empty[hidden] { display: none; }

/* --- score submission ------------------------------------------------------ */
.ar-submit {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  width: 100%;
  margin: 0;
}
.ar-submit[hidden] { display: none; }
.ar-submit-label { text-align: center; }

/* Arcade initials pad. A 3x3 grid - up chevrons, glyph slots, down chevrons - with the real
   <input> laid across the whole of row 2, on top of the slots.
   Every cell is placed explicitly. Auto-placement is not an option here: the field fills
   row 2, so the slots it is supposed to be sitting on would find that row occupied and drop
   into a fourth row underneath it. */
.ar-initials {
  position: relative;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: center;
  justify-items: center;
  gap: 2px 8px;
  width: min(268px, 100%);
}
.ar-initials-arrow--up { grid-row: 1; }
.ar-initials-slot { grid-row: 2; }
.ar-initials-arrow--down { grid-row: 3; }
.ar-initials-col-1 { grid-column: 1; }
.ar-initials-col-2 { grid-column: 2; }
.ar-initials-col-3 { grid-column: 3; }

.ar-initials-slot {
  display: block;
  width: 100%;
  min-height: 58px;
  line-height: 58px;
  text-align: center;
  font-family: var(--ar-mono);
  font-size: clamp(28px, 8.5vw, 38px);
  font-weight: 700;
  color: var(--oao-cyan);
  text-shadow: 0 0 18px rgba(92, 225, 230, 0.45);
  background: rgba(4, 6, 14, 0.9);
  border: 1px solid var(--ar-edge);
  border-radius: 2px;
  /* The field lies over this whole row and owns every pointer that lands in it, so the slots
     must not swallow the tap that is meant to place the caret. */
  pointer-events: none;
}
/* An empty slot still has to look like a slot waiting for a letter. Three blank boxes read
   as a field that failed to render rather than as an invitation to type. */
.ar-initials-slot.is-empty::after {
  content: '_';
  color: rgba(206, 238, 242, 0.32);
  text-shadow: none;
}
.ar-initials-slot.is-active {
  border-color: var(--oao-cyan);
  box-shadow: inset 0 -4px 0 var(--oao-orange), 0 0 22px rgba(92, 225, 230, 0.25);
  animation: ar-initials-blink 1.05s steps(1, end) infinite;
}
/* Ends on the lit frame on purpose: the global reduced-motion rule collapses every animation
   to one 0.001ms pass, so whatever 100% says is what a player who asked for less motion is
   left looking at. That has to be the caret being visible. */
@keyframes ar-initials-blink {
  0%, 49% { box-shadow: inset 0 -4px 0 var(--oao-orange), 0 0 22px rgba(92, 225, 230, 0.25); }
  50%, 99% { box-shadow: inset 0 -4px 0 rgba(255, 107, 53, 0.15); }
  100% { box-shadow: inset 0 -4px 0 var(--oao-orange), 0 0 22px rgba(92, 225, 230, 0.25); }
}

/* The real control. Transparent and stretched across the slots, so the browser does all the
   text editing while the glyphs underneath do all the drawing. -webkit-text-fill-color is
   not redundant: Safari ignores `color` on an input's own text. */
.ar-initials-field {
  grid-row: 2;
  grid-column: 1 / -1;
  /* Stretched rather than centred, so the hit area is the slot row exactly - a field that
     sat a couple of pixels inside it would leave a dead border a thumb can land on. */
  align-self: stretch;
  justify-self: stretch;
  z-index: 1;
  width: 100%;
  margin: 0;
  padding: 0;
  font-family: var(--ar-mono);
  font-size: clamp(28px, 8.5vw, 38px);
  text-align: center;
  color: transparent;
  -webkit-text-fill-color: transparent;
  caret-color: transparent;
  background: none;
  border: 0;
  border-radius: 2px;
}
.ar-initials-field::selection { background: transparent; }
/* No text is visible in the field, so the usual focus ring would frame nothing. Ring the pad
   instead - the blinking slot says which letter is live, this says the pad has the keyboard. */
.ar-initials-field:focus { outline: none; }
.ar-initials-field:focus-visible { outline: 2px solid var(--oao-cyan); outline-offset: 5px; }
.ar-initials-field:disabled { opacity: 0.55; }

.ar-initials-arrow {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 32px;
  padding: 0;
  color: var(--oao-cyan);
  background: none;
  border: 0;
  cursor: pointer;
  opacity: 0.6;
  transition: opacity 0.15s ease, transform 0.12s ease;
}
.ar-initials-arrow svg {
  width: 26px;
  height: 26px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.ar-initials-arrow:hover { opacity: 1; }
.ar-initials-arrow:active { opacity: 1; transform: scale(0.86); }
.ar-initials-arrow:disabled { opacity: 0.22; cursor: default; }
/* On touch these stop being a shortcut and become the only way in - the keyboard is not
   opened on this screen - so they get a thumb-sized target. */
html.ar-touch-mode .ar-initials-arrow { min-height: 44px; }
html.ar-touch-mode .ar-initials-arrow svg { width: 30px; height: 30px; }

.ar-submit-btn { align-self: center; padding: 11px 20px; letter-spacing: 0.16em; text-indent: 0.16em; }
.ar-submit-btn:disabled { opacity: 0.55; cursor: default; }

.ar-submit-msg {
  min-height: 1em;
  font-family: var(--ar-mono);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-indent: 0.2em;
  color: var(--oao-orange-2);
  text-shadow: 0 0 16px rgba(255, 133, 0, 0.5);
}
.ar-submit-msg:empty { display: none; }
.ar-submit-msg.is-error { color: var(--oao-danger); text-shadow: none; }

/* ======================================================= TOUCH CONTROLS ==== */
/* Built by src/core/Input.js, which also owns the hit test. Everything here is
   pointer-events: none except the pause button - the pads are painted affordances
   and the real geometry is the cached rect of these very elements, so the picture
   and the hitbox cannot drift apart.

   Two controls, deliberately. Steering this game is one rotational axis, so the
   left thumb gets an ABSOLUTE rail (thumb position = axis, therefore holding still
   holds a turn) and the right thumb gets the beat telegraph itself, ringed as a
   BOOST button - the cue you must watch and the button you must hit become the
   same object instead of two things competing for one pair of eyes. */

.ar-touch {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.22s ease, visibility 0.22s ease;
  --ar-knob: clamp(38px, 11vw, 50px);
  --ar-rail-w: clamp(148px, 46vw, 300px);
  --ar-rail-h: max(70px, calc(var(--ar-beat) * 0.62));
  z-index: 1;
}
.ar-touch.is-on { opacity: 1; visibility: visible; }

/* --- steer rail (bottom left) ---------------------------------------------- */
.ar-touch-rail {
  position: absolute;
  left: var(--ar-safe-l);
  bottom: calc(var(--ar-safe-b) + 6px);
  width: var(--ar-rail-w);
  height: var(--ar-rail-h);
  border: 1px solid rgba(92, 225, 230, 0.28);
  background: linear-gradient(180deg, rgba(6, 10, 22, 0.5) 0%, rgba(3, 5, 12, 0.68) 100%);
  box-shadow: inset 0 0 22px rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(0, 0, 0, 0.5);
  overflow: hidden;
}

.ar-touch-br {
  position: absolute;
  width: 11px;
  height: 11px;
  border: 0 solid var(--oao-cyan);
  opacity: 0.7;
}
.ar-touch-br--tl { top: 0; left: 0; border-top-width: 2px; border-left-width: 2px; }
.ar-touch-br--tr { top: 0; right: 0; border-top-width: 2px; border-right-width: 2px; }
.ar-touch-br--bl { bottom: 0; left: 0; border-bottom-width: 2px; border-left-width: 2px; }
.ar-touch-br--br { bottom: 0; right: 0; border-bottom-width: 2px; border-right-width: 2px; }

/* centre detent mark - tells the player where "straight" is without a live readout */
.ar-touch-tick {
  position: absolute;
  left: 50%;
  top: 20%;
  bottom: 20%;
  width: 1px;
  margin-left: -0.5px;
  background: linear-gradient(180deg, rgba(92, 225, 230, 0), rgba(92, 225, 230, 0.6), rgba(92, 225, 230, 0));
}

.ar-touch-chev {
  position: absolute;
  top: 50%;
  width: 14px;
  height: 20px;
  margin-top: -10px;
  opacity: 0.34;
  transition: opacity 0.12s linear;
}
.ar-touch-chev--l { left: 9px; }
.ar-touch-chev--r { right: 9px; }
.ar-touch-chev svg { display: block; width: 100%; height: 100%; }
.ar-touch-chev svg path {
  fill: none;
  stroke: var(--oao-cyan);
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.ar-touch-rail.is-left .ar-touch-chev--l,
.ar-touch-rail.is-right .ar-touch-chev--r { opacity: 1; }
.ar-touch-rail.is-left .ar-touch-chev--l svg path,
.ar-touch-rail.is-right .ar-touch-chev--r svg path { stroke: var(--oao-orange-2); }

.ar-touch-track {
  position: absolute;
  inset: 0;
  will-change: transform;
  transform: translateX(0);
}
.ar-touch-knob {
  position: absolute;
  left: 50%;
  top: 50%;
  width: var(--ar-knob);
  height: var(--ar-knob);
  margin: calc(var(--ar-knob) / -2) 0 0 calc(var(--ar-knob) / -2);
  border-radius: 11px;
  background: radial-gradient(circle at 50% 36%, rgba(92, 225, 230, 0.32), rgba(4, 6, 14, 0.94) 72%);
  border: 1px solid var(--oao-cyan);
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, 0.75),
    0 0 18px rgba(92, 225, 230, 0.45),
    inset 0 0 12px rgba(92, 225, 230, 0.2);
}
.ar-touch-rail.is-left .ar-touch-knob,
.ar-touch-rail.is-right .ar-touch-knob {
  border-color: var(--oao-orange-2);
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, 0.75),
    0 0 22px rgba(255, 133, 0, 0.5),
    inset 0 0 12px rgba(255, 133, 0, 0.22);
}

.ar-touch-cap {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 4px;
  font-family: var(--ar-mono);
  font-size: 8px;
  font-style: normal;
  letter-spacing: 0.24em;
  text-indent: 0.24em;
  text-align: center;
  color: rgba(206, 238, 242, 0.62);
  text-shadow: var(--ar-shadow-txt);
}

/* --- boost ring (bottom right, concentric with the beat telegraph) ---------- */
.ar-touch-boost {
  position: absolute;
  right: var(--ar-safe-r);
  bottom: calc(var(--ar-safe-b) + 6px);
  width: calc(var(--ar-beat) + 24px);
  height: calc(var(--ar-beat) + 24px);
  border-radius: 50%;
}
.ar-touch-boost-ring {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1px dashed rgba(255, 133, 0, 0.55);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.5), inset 0 0 26px rgba(255, 107, 53, 0.1);
  transition: border-color 0.12s linear, box-shadow 0.12s linear, transform 0.12s ease;
}
.ar-touch-boost.is-press .ar-touch-boost-ring {
  border-style: solid;
  border-color: var(--oao-orange-2);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.5), 0 0 28px rgba(255, 133, 0, 0.55),
    inset 0 0 30px rgba(255, 107, 53, 0.22);
  transform: scale(1.04);
}
/* a small bolt on the rim - the telegraph fills the middle, so the button marks
   itself where nothing else is competing for the pixels */
.ar-touch-boost-ico {
  position: absolute;
  right: 5%;
  top: 7%;
  width: 15px;
  height: 15px;
  opacity: 0.8;
}
.ar-touch-boost-ico svg {
  display: block;
  width: 100%;
  height: 100%;
  fill: var(--oao-orange-2);
  filter: drop-shadow(0 0 6px rgba(255, 133, 0, 0.85));
}
.ar-touch-boost.is-press .ar-touch-boost-ico { opacity: 1; }
.ar-touch-cap--boost { bottom: -14px; color: rgba(255, 176, 112, 0.85); }

/* --- pause ------------------------------------------------------------------ */
.ar-touch-pause {
  position: absolute;
  top: var(--ar-safe-t);
  left: 50%;
  transform: translateX(-50%);
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  margin: 0;
  appearance: none;
  -webkit-appearance: none;
  border: 1px solid rgba(92, 225, 230, 0.34);
  border-radius: 2px;
  background: rgba(4, 6, 14, 0.72);
  cursor: pointer;
}
.ar-touch-pause svg { display: block; width: 18px; height: 18px; }
.ar-touch-pause svg rect { fill: var(--oao-cyan); }
.ar-touch-pause:active { background: rgba(92, 225, 230, 0.18); }

/* --- what changes elsewhere when touch is driving --------------------------- */
/* The telegraph relocates under the right thumb and becomes the boost button. The
   hint has to leave the flow to do that: as a flex child it would set the cluster's
   width and the ring would stop being concentric with the dial it rings. */
html.ar-touch-mode .ar-beat-cluster {
  display: block;
  left: auto;
  right: calc(var(--ar-safe-r) + 12px);
  bottom: calc(var(--ar-safe-b) + 18px);
  width: var(--ar-beat);
  transform: none;
}
html.ar-touch-mode .ar-beat-hint {
  position: absolute;
  right: 0;
  bottom: calc(100% + 12px);
  white-space: nowrap;
}
html.ar-touch-mode .ar-beat-key { display: none; }
/* combat text clears the rail and the ring instead of stacking on top of them */
html.ar-touch-mode .ar-float-layer {
  bottom: calc(var(--ar-safe-b) + var(--ar-beat) + 78px);
}
html.ar-touch-mode .ar-debug { bottom: calc(var(--ar-safe-b) + 88px); }

/* --- debug overlay (created by main.js, styled here) ------------------------ */
.ar-debug {
  position: absolute;
  left: var(--ar-safe-l);
  bottom: var(--ar-safe-b);
  max-width: calc(100% - 24px);
  padding: 5px 8px;
  font-family: var(--ar-mono);
  font-size: 10px;
  line-height: 1.5;
  color: #9dffcf;
  background: rgba(0, 0, 0, 0.7);
  border: 1px solid rgba(157, 255, 207, 0.3);
  pointer-events: none;
  z-index: 20;
}

/* ============================================================== RESPONSIVE = */
/* Verified from 320x568 up to 2560x1080, portrait and landscape. The hard case is
   a portrait phone: a 78-degree FOV tunnel in a tall viewport leaves the top and
   bottom bands as the only safe places to put anything, and touch then wants the
   bottom band back. So the HUD shrinks by tier and the telegraph moves rather than
   anything ever being allowed to overlap the score or the boost meter. */

/* --- large / ultrawide ------------------------------------------------------ */
/* Corner clusters that keep drifting apart on a 2560px display stop reading as one
   instrument. Past this width the HUD is pinned to a centred band instead. */
@media (min-width: 1500px) {
  .ar-hud-tl { left: max(var(--ar-safe-l), calc(50vw - 720px)); }
  .ar-hud-tr { right: max(var(--ar-safe-r), calc(50vw - 720px)); }
}

@media (min-width: 900px) and (min-height: 720px) {
  .ar-ui-root { --ar-beat: 144px; }
}

/* --- tablet / small laptop -------------------------------------------------- */
@media (max-width: 620px) {
  .ar-panel--menu { padding: 20px 16px 16px; gap: 11px; }
  .ar-pitch { font-size: 13px; }
  .ar-howto-row { font-size: 12px; gap: 8px; }
  .ar-howto-k { min-width: 50px; font-size: 9.5px; }
  .ar-options { justify-content: center; }
}

/* --- phone portrait --------------------------------------------------------- */
@media (max-width: 480px) {
  .ar-ui-root { --ar-beat: 112px; }
  .ar-score-panel { min-width: 0; padding: 6px 11px 8px; }
  .ar-combo-track { min-width: 68px; }
  .ar-stat-v { font-size: 13px; min-width: 46px; }
  .ar-chev { width: 22px; height: 17px; }
  /* the layer is a zero-size anchor point, so scaling it compresses the lane spread and
     the type together - keeps wide labels inside a 360px viewport */
  .ar-float-layer { transform: scale(0.74); }
  .ar-float { font-size: 15px; }
  .ar-float--perfect { font-size: 19px; }
  .ar-beat-hint { font-size: 10px; letter-spacing: 0.2em; text-indent: 0.2em; }
  .ar-actions .ar-cta { min-width: 100%; }
  .ar-grid-v { font-size: 15px; }
  .ar-screen { padding-left: calc(var(--ar-safe-l) + 2px); padding-right: calc(var(--ar-safe-r) + 2px); }
}

/* --- 320-380px: the floor we support ---------------------------------------- */
@media (max-width: 380px) {
  .ar-ui-root { --ar-beat: 98px; --ar-safe-t: max(8px, env(safe-area-inset-top)); }
  .ar-howto { padding: 10px; }
  .ar-howto-row { flex-direction: column; gap: 1px; }
  .ar-howto-k { min-width: 0; }
  .ar-options { flex-direction: column; align-items: stretch; }
  .ar-quality { justify-content: space-between; }
  .ar-btn { letter-spacing: 0.16em; text-indent: 0.16em; }
  .ar-panel--menu { gap: 9px; }
  .ar-logo { letter-spacing: 0.1em; text-indent: 0.1em; }
  .ar-score { font-size: 28px; }
  .ar-score-panel { padding: 5px 9px 7px; }
  .ar-shield-panel, .ar-stat-panel { padding: 5px 9px 7px; }
  .ar-stat-v { font-size: 12px; min-width: 40px; }
  .ar-chev { width: 19px; height: 15px; }
  .ar-touch { --ar-knob: 40px; }
  /* the pause button sits between the two top clusters; below this width it moves
     under the score rather than colliding with it */
  .ar-touch-pause { width: 40px; height: 40px; }
}

/* --- landscape phones: short viewport, wide tunnel -------------------------- */
@media (max-height: 480px) {
  .ar-ui-root { --ar-beat: 96px; }
  .ar-beat-key { display: none; }
  .ar-screen { align-items: flex-start; }
  .ar-panel--menu { padding: 14px 16px 12px; gap: 8px; }
  .ar-logo { font-size: clamp(20px, 5vw, 30px); }
  .ar-pitch { display: none; }
  .ar-cta { padding: 12px 24px; }
  .ar-float-layer { bottom: calc(var(--ar-safe-b) + var(--ar-beat) + 34px); }
  .ar-touch { --ar-rail-h: 66px; --ar-knob: 40px; }
  html.ar-touch-mode .ar-float-layer { bottom: calc(var(--ar-safe-b) + var(--ar-beat) + 46px); }
}

/* Very short: the menus become a scrolling column instead of a squeezed panel. */
@media (max-height: 400px) {
  .ar-ui-root { --ar-beat: 84px; }
  .ar-screen { padding-top: calc(var(--ar-safe-t) + 2px); padding-bottom: calc(var(--ar-safe-b) + 2px); }
  .ar-panel--menu { gap: 7px; padding: 11px 14px 10px; }
  .ar-howto { padding: 8px 10px; gap: 5px; }
  .ar-howto-row { font-size: 11.5px; }
  .ar-btn { min-height: 40px; padding: 9px 18px; }
  .ar-cta { padding: 10px 20px; font-size: 14px; }
  .ar-final-v { font-size: clamp(30px, 9vw, 42px); }
  .ar-beat-hint { font-size: 9px; padding: 2px 8px 3px; }
  .ar-touch { --ar-rail-h: 58px; --ar-knob: 36px; }
  .ar-touch-cap { font-size: 7.5px; }
}

/* Landscape phones put both thumbs at the far edges; widen the rail's reach so the
   grip does not have to travel inward, and keep the top clusters compact. */
@media (orientation: landscape) and (max-height: 480px) {
  .ar-touch { --ar-rail-w: clamp(180px, 34vw, 320px); }
  .ar-hud-corner { gap: 5px; }
}

/* A pointer-driven small window is not a phone; only the real touch layout gives up
   the bottom band, so keep the desktop telegraph centred when it is not in play. */
@media (max-width: 340px) {
  html.ar-touch-mode .ar-beat-hint { font-size: 9px; letter-spacing: 0.16em; text-indent: 0.16em; }
}

/* ======================================================= REDUCED MOTION ==== */
/* The beat telegraph is information, not decoration, so HUD.js swaps it to an
   opacity-only cue rather than removing it. Everything decorative stops. */

/* motion-free replacements: combat text still has to appear and clear itself */
@keyframes ar-fl-rm-a {
  0% { opacity: 0; }
  10%, 68% { opacity: 1; }
  100% { opacity: 0; }
}
@keyframes ar-fl-rm-b {
  0% { opacity: 0; }
  10%, 68% { opacity: 1; }
  100% { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .ar-ui-root *,
  .ar-ui-root *::before,
  .ar-ui-root *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .ar-float { transform: translate(calc(-50% + var(--ar-lane, 0px)), calc(-22px + var(--ar-row, 0px))); }
  .ar-float.ar-anim-a { animation: ar-fl-rm-a 1.1s linear forwards !important; }
  .ar-float.ar-anim-b { animation: ar-fl-rm-b 1.1s linear forwards !important; }
  .ar-beat-hint { animation: none !important; opacity: 1; }
  /* Belt and braces over the blanket rule above: the live slot is the only thing telling the
     player where their next keystroke lands, so it must stay lit rather than depend on which
     frame a collapsed animation happened to stop on. */
  .ar-initials-slot.is-active { animation: none !important; }
  .ar-chev.is-lost .ar-shard { opacity: 0; }
}

@media (prefers-contrast: more) {
  .ar-panel { background: rgba(2, 3, 8, 0.94); border-color: var(--oao-cyan); }
  .ar-label, .ar-unit, .ar-combo-label, .ar-beat-key { color: #d8f6f9; }
  .ar-howto-v { color: #fff; }
  .ar-attrib { color: #cfe9ec; }
}
