/* ==========================================================================
   Font Asset Loading & Preload Configuration
   ========================================================================== */
@font-face {
  font-family: 'Helvetica';
  /* TODO: Drop specific font file here if the exact asset is pending delivery (e.g. url('assets/fonts/Helvetica.woff2') format('woff2')) */
  src: local('Helvetica'), local('Helvetica Neue'), local('Arial');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  --color-brand-red: #FF1E27;
  --color-white: #FFFFFF;
  --color-black: #111111;
  --color-gold: #FFD700;
  --color-glass-bg: rgba(255, 255, 255, 0.60);
  --color-glass-border: rgba(255, 255, 255, 0.40);
  --color-glass-hover: rgba(255, 255, 255, 0.78);
  
  --font-main: "Helvetica", "Inter", Arial, sans-serif;
  --font-body: "Helvetica", "Inter", Arial, sans-serif;
  --font-display: "Helvetica", "Inter", Arial, sans-serif;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}

html, body {
  width: 100%;
  height: 100%;
  overflow: hidden;
  background-color: var(--color-brand-red);
  color: var(--color-white);
  font-family: var(--font-main);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  touch-action: none;
}

#game-container {
  position: relative;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  background-color: var(--color-brand-red);
}

canvas#gameCanvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: block;
  z-index: 1;
  touch-action: none;
}

/* Visibility Utilities */

/* ==========================================================================
   Top-Left Brand Poster Header & Altitude Meter
   ========================================================================== */
.poster-brand {
  position: absolute;
  top: 2rem;
  left: 2.5rem;
  z-index: 10;
  pointer-events: none;
}

/* Sits under the mark, not over it. The lockup already ends in the wordmark, so the date
   reads as a caption to it; it also puts the mark itself at the top of the block, where the
   HUD pills are closest and the date used to get crowded. */
.brand-sub {
  font-family: var(--font-body);
  font-size: 0.85rem;
  font-weight: 800;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.88);
  margin-top: 0.5rem;
}

.brand-title {
  /* The wordmark is supplied as artwork, so the heading is only a container now. Its own
     type styling is gone; the accessible name lives on the link's aria-label. */
  margin: 0;
  line-height: 0;
  color: var(--color-white);
}

/* Inlined rather than referenced as a CSS mask, which is how the Trashstock marks are done.
   A mask clips painting but not hit testing, so a masked span hands the link the whole
   224x281 rectangle — including the empty red to the right of the cube — and swallows taps
   meant for the cubes underneath. Real SVG geometry hit tests per painted glyph, so the link
   claims exactly the artwork and nothing else. An inline viewBox also carries its own
   intrinsic ratio, so height needs no 'aspect-ratio' support to come out right. */
.brand-lockup {
  display: block;
  --lockup-w: 14rem;
  width: var(--lockup-w);
  height: auto;
  /* The same translucent white the readout pills use, so the mark sits in the game rather
     than on top of it. No backdrop-filter to go with it: the pills blur what is behind them,
     but behind the mark is either flat red or a flat white cube face, and blurring a flat
     colour returns the same flat colour. */
  fill: var(--color-glass-bg);
  transition: opacity 0.18s ease;
}

/* Only the cube mark is the link - the wordmark beneath it is not. A rect over the cube's
   region of the artwork stands in as the target and paints nothing; the glyphs themselves take
   no pointer events at all. Everything else stays click-through, so the canvas below still
   receives taps even where the artwork overlaps the tower. */
.brand-lockup path { pointer-events: none; }
.brand-hit { fill: none; pointer-events: fill; }

/* The run's one readout, with the menu button tucked beneath it, both right-aligned. */
.stats-stack {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.4rem;
}

/* ==========================================================================
   Top-Right HUD & Controls
   ========================================================================== */
.hud-controls {
  position: absolute;
  top: 2rem;
  right: 2.5rem;
  z-index: 10;
  display: flex;
  /* Top aligned, not centred. The streak is a single pill and the stats are a column of two,
     so centring hung the streak against the middle of the taller stack and dropped it half a
     row below SCORE. They are meant to read as one row. */
  align-items: flex-start;
  flex-wrap: nowrap;
  gap: 0.9rem;
}

/* M-D-W Streak Container */
.streak-container {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  flex-shrink: 0;
  white-space: nowrap;
  gap: 0.65rem;
  background: var(--color-glass-bg);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid var(--color-glass-border);
  color: var(--color-brand-red);
  padding: 0.35rem 0.75rem 0.35rem 0.45rem;
  border-radius: 999px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
  transition: background 0.3s ease, box-shadow 0.3s ease, transform 0.3s ease;
}

.streak-container.flash-white {
  animation: streakContainerFlash 0.65s cubic-bezier(0.2, 0.8, 0.2, 1);
}

@keyframes streakContainerFlash {
  0% {
    background: #FFFFFF;
    border-color: #FFFFFF;
    box-shadow: 0 0 26px rgba(255, 255, 255, 1), 0 4px 18px rgba(0, 0, 0, 0.2);
    transform: scale(1.08);
  }
  50% {
    background: rgba(255, 255, 255, 0.95);
    border-color: rgba(255, 255, 255, 0.9);
    box-shadow: 0 0 16px rgba(255, 255, 255, 0.7), 0 4px 14px rgba(0, 0, 0, 0.15);
    transform: scale(1.03);
  }
  100% {
    background: var(--color-glass-bg);
    border-color: var(--color-glass-border);
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
    transform: scale(1);
  }
}

.letter-badges {
  display: flex;
  gap: 0.35rem;
}

.letter-badge {
  width: 2rem;
  height: 2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 900;
  font-size: 0.95rem;
  color: rgba(255, 30, 39, 0.45);
  background: rgba(255, 30, 39, 0.10);
  border: 1px solid rgba(255, 30, 39, 0.22);
  border-radius: 50%;
  transition: all 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.letter-badge.active {
  color: var(--color-white);
  background: var(--color-brand-red);
  border-color: var(--color-brand-red);
  box-shadow: 0 2px 10px rgba(255, 30, 39, 0.5);
  transform: scale(1.15);
}

.letter-badge.flash-pop {
  animation: badgeFlashPop 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
}

@keyframes badgeFlashPop {
  0% {
    background: #FFFFFF;
    color: var(--color-brand-red);
    border-color: #FFFFFF;
    box-shadow: 0 0 20px rgba(255, 255, 255, 1);
    transform: scale(1.4);
  }
  100% {
    transform: scale(1.15);
  }
}

.streak-pill {
  display: flex;
  flex-direction: row;
  align-items: baseline;
  flex-wrap: nowrap;
  gap: 0.3rem;
  white-space: nowrap;
  padding-right: 0.4rem;
}

.streak-lbl {
  font-family: var(--font-body);
  font-size: 0.65rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  line-height: 1;
  color: rgba(255, 30, 39, 0.7);
}

.streak-val {
  font-size: 1.15rem;
  font-weight: 900;
  color: var(--color-brand-red);
  line-height: 1;
  font-variant-numeric: tabular-nums;
  transition: transform 0.2s ease, color 0.2s ease;
}

.streak-val.flash-val,
.stat-val.flash-val {
  animation: streakValFlash 0.65s cubic-bezier(0.2, 0.8, 0.2, 1);
}

@keyframes streakValFlash {
  0% {
    color: #FFFFFF;
    text-shadow: 0 0 14px rgba(255, 255, 255, 1);
    transform: scale(1.35);
  }
  100% {
    color: var(--color-brand-red);
    text-shadow: none;
    transform: scale(1);
  }
}

/* Stats Pill (Score / Best) */
.stats-pill {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  background: var(--color-glass-bg);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid var(--color-glass-border);
  color: var(--color-brand-red);
  padding: 0.45rem 1.15rem;
  border-radius: 999px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
}

.stat-col {
  display: flex;
  flex-direction: column;
}

.stat-lbl {
  font-family: var(--font-body);
  font-size: 0.65rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  color: rgba(255, 30, 39, 0.7);
}

.stat-val {
  font-size: 1.1rem;
  font-weight: 900;
  color: var(--color-brand-red);
  line-height: 1;
}

.stat-divider {
  color: rgba(255, 30, 39, 0.3);
}

.btn-svg-icon {
  display: block;
  color: var(--color-brand-red);
  pointer-events: none;
  flex-shrink: 0;
}

/* ==========================================================================
   Mobile Responsive Adjustments
   ========================================================================== */
@media (max-width: 768px), (orientation: portrait) {

  .poster-brand {
    top: calc(1rem + env(safe-area-inset-top, 0px));
    left: 1.2rem;
  }

  .brand-lockup {
    --lockup-w: 7.4rem;
  }

  .brand-sub {
    font-size: 0.7rem;
  }

  .hud-controls {
    top: calc(1rem + env(safe-area-inset-top, 0px));
    right: 1.2rem;
    gap: 0.5rem;
    flex-direction: column;
    align-items: flex-end;
  }

  .streak-container {
    padding: 0.25rem 0.5rem 0.25rem 0.35rem;
    gap: 0.45rem;
  }

  /* Stays one row on a phone by shrinking, never by wrapping. */
  .streak-pill {
    gap: 0.22rem;
    padding-right: 0.2rem;
  }

  .streak-lbl {
    font-size: 0.55rem;
    letter-spacing: 0.04em;
  }

  .streak-val {
    font-size: 0.95rem;
  }

  .letter-badge {
    width: 1.7rem;
    height: 1.7rem;
    font-size: 0.8rem;
  }

  .stats-pill {
    padding: 0.35rem 0.8rem;
  }

  .stat-val {
    font-size: 0.9rem;
  }

  

  
}

/* =========================================================================
   Best-streak readout, rotation hint, and the ?dev=1 tuning panel
   ========================================================================= */

.streak-sep {
  color: var(--color-brand-red);
  opacity: 0.4;
  font-weight: 700;
  padding: 0 1px;
}

.streak-best {
  opacity: 0.72;
}

/* The planner marks the rotate button when the current view has no route onward. */

/* The planner marks the rotate button when the current view has no route onward. */
.dock-rotate.suggests-rotation {
  box-shadow: 0 0 0 2px var(--color-brand-red), 0 0 14px rgba(255, 30, 39, 0.45);
}
@media (prefers-reduced-motion: no-preference) {
  .dock-rotate.suggests-rotation { animation: rotate-nudge 1.4s ease-in-out infinite; }
}

@keyframes rotate-nudge {
  0%, 100% { box-shadow: 0 0 0 2px var(--color-brand-red), 0 0 10px rgba(255, 30, 39, 0.30); }
  50%      { box-shadow: 0 0 0 2px var(--color-brand-red), 0 0 20px rgba(255, 30, 39, 0.65); }
}

/* Narrow desktops and landscape tablets: the top-right HUD and the top-left brand block
   compete for the same band. Tighten the HUD rather than letting the streak wrap. */
@media (min-width: 769px) and (max-width: 1100px) {
  .hud-controls {
    right: 1.5rem;
    gap: 0.6rem;
  }

  .streak-container {
    gap: 0.45rem;
    padding: 0.3rem 0.55rem 0.3rem 0.35rem;
  }

  .streak-pill {
    gap: 0.22rem;
    padding-right: 0.2rem;
  }

  .streak-lbl {
    font-size: 0.58rem;
    letter-spacing: 0.04em;
  }

  .streak-val {
    font-size: 1rem;
  }

  .letter-badge {
    width: 1.75rem;
    height: 1.75rem;
    font-size: 0.85rem;
  }

  .stats-pill {
    padding: 0.35rem 0.85rem;
  }
}

/* ---- developer tuning panel ---- */

.dev-panel {
  position: fixed;
  top: 50%;
  left: 16px;
  transform: translateY(-50%);
  z-index: 40;
  width: 264px;
  max-height: 86vh;
  display: flex;
  flex-direction: column;
  background: rgba(255, 255, 255, 0.92);
  border: 1px solid var(--color-glass-border);
  border-radius: 10px;
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.22);
  color: var(--color-brand-red);
  font-family: var(--font-body);
  font-size: 12px;
}

.dev-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 10px 12px;
  border-bottom: 1px solid rgba(255, 30, 39, 0.18);
}

.dev-head h2 {
  margin: 0;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.dev-collapse {
  width: 22px;
  height: 22px;
  border: 1px solid rgba(255, 30, 39, 0.35);
  border-radius: 5px;
  background: transparent;
  color: var(--color-brand-red);
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
}

.dev-panel.collapsed .dev-body { display: none; }

.dev-body {
  padding: 12px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.dev-row {
  display: grid;
  grid-template-columns: 88px 1fr;
  align-items: center;
  gap: 8px;
}

.dev-row label {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  opacity: 0.75;
}

.dev-row select,
.dev-row input {
  width: 100%;
  padding: 5px 7px;
  border: 1px solid rgba(255, 30, 39, 0.3);
  border-radius: 5px;
  background: rgba(255, 255, 255, 0.85);
  color: var(--color-brand-red);
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 600;
}

.dev-sliders {
  display: flex;
  flex-direction: column;
  gap: 9px;
  padding-top: 4px;
  border-top: 1px solid rgba(255, 30, 39, 0.15);
}

.dev-slider label {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  opacity: 0.75;
  margin-bottom: 3px;
}

.dev-slider output {
  font-variant-numeric: tabular-nums;
  opacity: 1;
}

.dev-slider input[type="range"] {
  width: 100%;
  accent-color: var(--color-brand-red);
}

.dev-actions {
  display: flex;
  gap: 8px;
}

.dev-actions button {
  flex: 1;
  padding: 7px 8px;
  border: 1px solid var(--color-brand-red);
  border-radius: 6px;
  background: var(--color-brand-red);
  color: var(--color-white);
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  cursor: pointer;
}

.dev-actions button:hover { filter: brightness(1.08); }

.dev-stats {
  margin: 0;
  padding-top: 8px;
  border-top: 1px solid rgba(255, 30, 39, 0.15);
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.dev-stats > div {
  display: flex;
  justify-content: space-between;
  gap: 10px;
}

.dev-stats dt {
  font-size: 10.5px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  opacity: 0.68;
}

.dev-stats dd {
  margin: 0;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.dev-warn dt, .dev-warn dd {
  color: #A8000A;
  opacity: 1;
}

.dev-panel :focus-visible {
  outline: 2px solid var(--color-brand-red);
  outline-offset: 2px;
}

@media (max-width: 768px) {
  .dev-panel {
    top: 8px;
    left: 8px;
    right: 8px;
    width: auto;
    transform: none;
    max-height: 60vh;
  }
}

/* Music volume sits with the sliders but applies live rather than rebuilding the tower. */
.dev-music {
  padding-top: 8px;
  border-top: 1px solid rgba(255, 30, 39, 0.15);
}

/* =========================================================================
   Spin-out notice — shown when rotate-spam throws the character off the tower
   ========================================================================= */

/* =========================================================================
   Control dock — rotate, and nothing else; everything else is behind the gear
   ========================================================================= */

.control-dock {
  position: absolute;
  left: 50%;
  bottom: calc(1.4rem + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  z-index: 20;
  display: flex;
  align-items: flex-end;
  gap: 0.75rem;
  max-width: calc(100vw - 1.6rem);
}

.dock-rotate {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  border: 1px solid var(--color-glass-border);
  background: var(--color-glass-bg);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  color: var(--color-brand-red);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.14);
  cursor: pointer;
  transition: background 0.2s ease, transform 0.15s ease;
}

.dock-rotate {
  height: 3rem;
  padding: 0 1.6rem;
  border-radius: 999px;
  font-family: var(--font-body);
  font-size: 0.82rem;
  font-weight: 900;
  letter-spacing: 0.12em;
  white-space: nowrap;
}

.dock-rotate-text { white-space: nowrap; }

.dock-rotate:hover { background: var(--color-glass-hover); }
.dock-rotate:active { transform: translateY(1px); }
.dock-rotate:focus-visible { outline: 2px solid var(--color-white); outline-offset: 3px; }

/* A muted channel reads as switched off rather than merely styled differently. */

/* Vertical slider, so the popover stays as narrow as the button it belongs to. */

/* ---- credits ---- */

.credits-lockup {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.7rem;
  margin: 0 0 1.1rem;
  color: var(--color-brand-red);
}

/* The horizontal Trashstock logo from the logo pack, drawn in the panel's red through a mask.
   Sized by width; the ratio is the artwork's own. flex: none because a masked span has no
   content, so its automatic minimum size is zero and it would shrink away to nothing. */
.credits-logo {
  display: block;
  flex: none;
  width: min(16rem, 100%);
  aspect-ratio: 284.46 / 54.91;
  background-color: currentColor;
  -webkit-mask: url("assets/trashstock-horizontal.svg") no-repeat center / contain;
  mask: url("assets/trashstock-horizontal.svg") no-repeat center / contain;
}

.credits-list { margin: 0; display: flex; flex-direction: column; gap: 0.85rem; }
.credits-list > div { display: flex; flex-direction: column; gap: 0.1rem; }

.credits-list dt {
  font-family: var(--font-body);
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--color-panel-ink);
}

.credits-list dd {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.02rem;
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--color-panel-ink);
}

.credits-list a { color: inherit; text-underline-offset: 3px; }
.credits-list a:hover { opacity: 0.75; }

.credits-aside {
  color: var(--color-panel-ink);
  display: block;
  font-family: var(--font-body);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: none;
}

.brand-title a {
  color: inherit;
  text-decoration: none;
  display: inline-block;
  pointer-events: none;
}
.brand-title a:hover .brand-lockup { opacity: 0.78; }
.brand-title a:focus-visible { outline: 2px solid var(--color-white); outline-offset: 6px; }

@media (max-width: 768px), (orientation: portrait) {
  .dock-rotate { height: 2.7rem; padding: 0 1rem; font-size: 0.7rem; letter-spacing: 0.08em; }
  .credits-list dd { font-size: 0.92rem; }
}

/* =========================================================================
   Menu: the gear under the readout, its tabbed panel, and the first-run nudge
   ========================================================================= */

/* Android reports env(safe-area-inset-bottom) as 0 even with viewport-fit=cover, so the
   dock lands underneath the system navigation bar. A floor value clears it; max() stops
   iOS stacking that floor on top of a home-indicator inset it already reports correctly. */
@media (max-width: 768px), (orientation: portrait) {
  .control-dock {
    bottom: max(calc(1rem + env(safe-area-inset-bottom, 0px)), 3.5rem);
    /* On a phone the one button takes the whole width of the bottom edge, thumb-sized from
       either hand. Desktop keeps it centred and only as wide as its label. */
    left: 0.9rem;
    right: 0.9rem;
    transform: none;
    max-width: none;
  }
  .dock-rotate { width: 100%; }
}

/* Pause and menu share a row under the readout, right-aligned like the pills above them. */
.hud-buttons {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.help-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.9rem;
  height: 1.9rem;
  padding: 0;
  border-radius: 999px;
  border: 1px solid var(--color-glass-border);
  background: var(--color-glass-bg);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
  color: var(--color-brand-red);
  cursor: pointer;
  transition: background 0.2s ease, transform 0.15s ease;
}

.help-btn svg {
  width: 62%;
  height: 62%;
  display: block;
}

.help-btn:hover { background: var(--color-glass-hover); }
.help-btn:active { transform: translateY(1px); }
.help-btn:focus-visible { outline: 2px solid var(--color-white); outline-offset: 3px; }

/* ---- pause ---- */

/* Sits under the menu (z 55) so Options can open on top of it, and over everything else. */
.pause-screen {
  position: absolute;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  background: rgba(255, 30, 39, 0.55);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  opacity: 0;
  transition: opacity 0.26s ease;
}

.pause-screen[hidden] { display: none; }
.pause-screen.visible { opacity: 1; }

.pause-panel {
  width: min(360px, 100%);
  padding: 2rem 1.8rem 1.9rem;
  border-radius: 1.4rem;
  background: rgba(255, 255, 255, 0.9);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  border: 1px solid var(--color-glass-border);
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.26);
  color: var(--color-brand-red);
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.1rem;
}

.pause-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.1rem;
  font-weight: 900;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.pause-score { display: flex; flex-direction: column; gap: 0.25rem; }

.pause-score-lbl,
.pause-stats dt {
  font-family: var(--font-body);
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--color-panel-ink);
}

.pause-score-val {
  font-size: 2.6rem;
  font-weight: 900;
  line-height: 1;
}

.pause-stats { margin: 0; display: flex; gap: 1.8rem; }
.pause-stats > div { display: flex; flex-direction: column; gap: 0.15rem; }
.pause-stats dd { margin: 0; font-size: 1.1rem; font-weight: 900; line-height: 1; }

.pause-actions { display: flex; gap: 0.5rem; flex-wrap: wrap; justify-content: center; }

.pause-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 2.4rem;
  padding: 0 1.3rem;
  border-radius: 999px;
  border: 1.5px solid rgba(255, 30, 39, 0.35);
  background: transparent;
  color: var(--color-brand-red);
  font-family: var(--font-body);
  font-size: 0.7rem;
  font-weight: 900;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.18s ease, opacity 0.18s ease;
}

.pause-btn:hover { background: rgba(255, 30, 39, 0.08); }
.pause-btn.primary {
  background: var(--color-brand-red);
  border-color: var(--color-brand-red);
  color: var(--color-white);
}
.pause-btn.primary:hover { opacity: 0.9; }
.pause-btn:focus-visible { outline: 2px solid var(--color-brand-red); outline-offset: 2px; }

/* ---- first-run nudge ---- */

.howto-nudge {
  position: absolute;
  z-index: 25;
  display: none;
  align-items: center;
  gap: 0.5rem;
  color: rgba(255, 255, 255, 0.92);
  pointer-events: none;
}

.howto-nudge.showing { display: flex; }

.howto-text {
  font-family: var(--font-body);
  font-size: 0.72rem;
  font-weight: 900;
  letter-spacing: 0.14em;
  white-space: nowrap;
}

.howto-arrow { width: 3.4rem; height: 1.1rem; flex: none; }

@media (prefers-reduced-motion: no-preference) {
  .howto-nudge.showing { animation: howtoPulse 1.15s ease-in-out infinite; }
}

@keyframes howtoPulse {
  0%, 100% { opacity: 0.45; transform: translateX(-4px); }
  50%      { opacity: 1;    transform: translateX(0); }
}

/* ---- menu panel ---- */

.menu-screen {
  position: absolute;
  inset: 0;
  z-index: 55;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  background: rgba(255, 30, 39, 0.86);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  opacity: 0;
  transition: opacity 0.26s ease;
}

.menu-screen[hidden] { display: none; }
.menu-screen.visible { opacity: 1; }

.menu-panel {
  position: relative;
  display: flex;
  flex-direction: column;
  width: min(520px, 100%);
  /* One height for every tab, so switching between them never resizes or re-centres the
     panel: it used to follow its content, and Options is two rows while Credits runs off the
     screen. Sized to hold How to play in full at both widths (616px on desktop, 684px on a
     phone, measured); Credits scroll inside it; Options sit at the top of the same box. The
     overlay's padding caps it on short screens. */
  height: min(43rem, 100%);
  overflow: hidden;
  padding: 2.2rem 1.9rem 2rem;
  border-radius: 1.4rem;
  /* Same reasoning as the credits panel: body copy needs a whiter ground than the HUD. */
  background: rgba(255, 255, 255, 0.9);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  border: 1px solid var(--color-glass-border);
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.26);
  color: var(--color-brand-red);
}

/* The head is one row: three tabs and the close button, all the same height and the same
   1.5px outline, so it reads as one set of controls rather than tabs plus a stray X. The
   active tab is filled; the rest are outlined. The tabs stay put while the section scrolls. */
.menu-head {
  flex: none;
  display: flex;
  align-items: flex-start;
  gap: 0.4rem;
  margin: 0 0 1.5rem;
}

.menu-tabs {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  gap: 0.4rem;
  flex-wrap: wrap;
}

.menu-tab,
.menu-close,
.lang-choice {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 2rem;
  border-radius: 999px;
  border: 1.5px solid rgba(255, 30, 39, 0.35);
  background: transparent;
  color: var(--color-brand-red);
  font-family: var(--font-body);
  font-size: 0.66rem;
  font-weight: 900;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
  transition: background 0.18s ease, color 0.18s ease, border-color 0.18s ease;
}

.menu-tab { flex: 1 1 auto; padding: 0 0.9rem; }
.menu-close { flex: none; width: 2rem; padding: 0; }
.menu-close svg { width: 0.85rem; height: 0.85rem; }
.lang-choice { padding: 0 0.9rem; }

.menu-tab:hover,
.menu-close:hover,
.lang-choice:hover { background: rgba(255, 30, 39, 0.08); }

.menu-tab.active,
.menu-tab[aria-selected="true"],
.lang-choice[aria-pressed="true"] {
  background: var(--color-brand-red);
  border-color: var(--color-brand-red);
  color: var(--color-white);
}

.menu-tab:focus-visible,
.menu-close:focus-visible,
.lang-choice:focus-visible { outline: 2px solid var(--color-brand-red); outline-offset: 2px; }

/* Language: a decorative globe keeps the column of the rows above; the choice is two pills. */
.option-icon {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.7rem;
  height: 2.7rem;
  border-radius: 999px;
  border: 1.5px solid rgba(255, 30, 39, 0.35);
  color: var(--color-brand-red);
}
.option-icon .btn-svg-icon { width: 1.3rem; height: 1.3rem; }

.lang-switch {
  display: inline-flex;
  gap: 0.35rem;
}

/* The section is the scroll container now, so a long Credits list scrolls under the tabs
   rather than carrying them off the top. */
.menu-section {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
}

.menu-section[hidden] { display: none; }

/* Credits keep their own centring inside the shared panel. */
#sec-credits { text-align: center; }
#sec-credits .credits-lockup { margin-bottom: 1.4rem; }

/* ---- options: one row per audio channel ---- */

.options-list {
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
}

.option-row {
  display: flex;
  align-items: center;
  gap: 0.9rem;
}

/* A muted channel reads as switched off, slider included. */
.option-row.muted .option-body { opacity: 0.45; }

.option-toggle {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.7rem;
  height: 2.7rem;
  padding: 0;
  border-radius: 999px;
  border: 1.5px solid rgba(255, 30, 39, 0.35);
  background: transparent;
  color: var(--color-brand-red);
  cursor: pointer;
  transition: background 0.18s ease;
}

.option-toggle:hover { background: rgba(255, 30, 39, 0.08); }
.option-toggle:focus-visible { outline: 2px solid var(--color-brand-red); outline-offset: 2px; }
.option-toggle .btn-svg-icon { width: 1.3rem; height: 1.3rem; }

.option-body {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  min-width: 0;
  transition: opacity 0.2s ease;
}

.option-lbl {
  font-family: var(--font-body);
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--color-panel-ink);
}

.option-body input[type="range"] {
  width: 100%;
  margin: 0;
  accent-color: var(--color-brand-red);
  cursor: pointer;
}

.help-list { margin: 0; display: flex; flex-direction: column; gap: 1rem; }
.help-list > div { display: flex; flex-direction: column; gap: 0.2rem; }

.help-list dt {
  font-family: var(--font-body);
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--color-panel-ink);
  /* Underline only as wide as the words, not the column, so it reads as a heading rule
     rather than a divider. */
  align-self: flex-start;
  border-bottom: 1.5px solid currentColor;
  padding-bottom: 0.15rem;
  margin-bottom: 0.15rem;
}

.help-list dd {
  margin: 0;
  font-family: var(--font-body);
  font-size: 0.92rem;
  font-weight: 500;
  line-height: 1.5;
  color: var(--color-panel-ink);
}

.help-list strong { font-weight: 900; }

@media (max-width: 768px), (orientation: portrait) {
  .help-btn { width: 1.7rem; height: 1.7rem; }
  .pause-panel { padding: 1.6rem 1.2rem 1.5rem; }
  .pause-score-val { font-size: 2.2rem; }
  .menu-panel { padding: 1.8rem 1.1rem 1.5rem; border-radius: 1.1rem; }
  .menu-head { gap: 0.3rem; }
  .menu-tabs { gap: 0.3rem; }
  .menu-tab, .menu-close, .lang-choice { height: 1.85rem; font-size: 0.6rem; letter-spacing: 0.08em; }
  .menu-tab { padding: 0 0.6rem; }
  .menu-close { width: 1.85rem; }
  .lang-choice { padding: 0 0.75rem; }
  .help-list dd { font-size: 0.86rem; }
  .howto-text { font-size: 0.64rem; letter-spacing: 0.1em; }
  .howto-arrow { width: 2.6rem; }
}

/* Deeper red for panel body copy. Cardinal Red measures 3.3:1 against the panel, which is
   fine for the large headings and the lockup but tiring for running text; this measures
   4.8:1 and still reads as the same family. */
:root { --color-panel-ink: #CC1A22; }

/* The overlays sit inside a viewport that extends under the Android system bars, and
   Android reports a zero safe-area inset, so the bottom of a scrolled panel ends up behind
   the navigation buttons and cannot be reached. Same floor value as the control dock, and
   max() so a device that does report an inset is not padded twice. */

/* Android reports env(safe-area-inset-bottom) as 0 even with viewport-fit=cover, so an
   overlay laid out edge to edge puts its last lines under the system navigation bar. A floor
   value clears it; max() so a device that does report an inset is not padded twice. */
@media (max-width: 768px), (orientation: portrait) {
  .menu-screen {
    padding-top: max(1rem, env(safe-area-inset-top, 0px));
    padding-bottom: max(calc(1rem + env(safe-area-inset-bottom, 0px)), 4rem);
  }
}

/* A little breathing room after the last entry, so the final line never sits flush against
   the panel edge when scrolled to the end. */
.credits-list,
.help-list { padding-bottom: 0.4rem; }

/* Short viewports, landscape phones above all. The mark is portrait - 218x273 with the cube
   sitting over the wordmark - so on a squat screen it is height that runs out first, and none
   of the width breakpoints see the problem: an 844x390 phone in landscape matches neither
   max-width: 768px nor orientation: portrait, so it was taking the full desktop size and
   reaching down into the control dock. Cap it against the height actually available instead,
   leaving room for the date above it and the dock below.
   The 16.5rem reserve is the sum of what sits above and below the mark and cannot be given
   up: the block's own top offset (up to 4rem), the date line beneath it, and the dock stack,
   which is taller than the button row because the Trashstock logo sits above it. The 5rem
   floor stops the mark shrinking into illegibility on the shortest landscape phones, where it
   is better to come close to the dock than to become unreadable. It is 4rem rather than 5rem
   because below 768px the dock's own bottom offset grows to 3.5rem, about 2.1rem more than
   this reserve is derived for; at 5rem the floor overshot that and the dock's logo button
   painted over the tail of the date.
   dvh second so browsers that have it use the real, toolbar-adjusted height. */
@media (max-height: 620px) {
  .brand-lockup {
    width: clamp(4rem, calc((100vh - 16.5rem) * 218 / 273), var(--lockup-w));
    width: clamp(4rem, calc((100dvh - 16.5rem) * 218 / 273), var(--lockup-w));
  }
}

/* Vertical mode: the brand sits in the top left corner, at the top.
   It used to be pushed down 4rem to clear the streak row, which grows leftward from the right
   edge. That was measured against the bounding box, and the box is misleading here: in the
   band the streak occupies, y 16-53, the only ink is the cube, which is 112 of the artwork's
   218 units and renders about 57px wide. The full-width wordmark does not start until y 125,
   well below the streak. At the widths a phone actually has, the two do not meet: at 390px a
   best of x999 only brings the streak's left edge in to x=105, and the cube ends at x=80.
   Narrower than about 335px they do meet, which is what the max-width rule further down is
   for. */
@media (orientation: portrait) {
  .poster-brand {
    top: calc(1rem + env(safe-area-inset-top, 0px));
    left: 1.2rem;
    right: auto;
    display: block;
    text-align: left;
  }
}

/* Very narrow screens: the HUD column is right-aligned and the brand is left-aligned, and
   both start at the same height. The streak row grows leftward as BEST climbs, and on a small
   enough screen it reaches the mark. Drop the brand beneath it there.
   This used to fire at 520px, sized against the old two-line text and its bounding box. The
   artwork needs far less room, because the only ink level with the streak is the cube - 112 of
   the artwork's 218 units. Measured against the cube's real right edge rather than the box:
   at 390px the streak stays clear even stretched to x999, at 375px it clears by 44px, at 360px
   by 29px, and only at about 335px and below do the two actually meet. 359px is the last
   width that needs the push. Width decides this, not orientation - a narrow landscape phone
   collides exactly as a portrait one does.
   Keeping the threshold low also matters vertically: this push costs 3rem, and on a short
   viewport that was enough to drive the date line underneath the dock's logo button. */
@media (max-width: 359px) {
  .poster-brand {
    top: calc(4rem + env(safe-area-inset-top, 0px));
  }
}
/* Last on purpose: it has to beat the portrait rule above, which puts the brand in the
   corner at every portrait width. Equal specificity, so source order decides. */
