/* Pickle Arcade: the arena page.
 *
 * arcade.css carries the site register (chrome, hall, wallet, fair). This
 * sheet carries everything the arena page alone asks for: the stage wrap and
 * canvas, the overlay and HUD, the death card and the latency instrument. Every
 * class here is prefixed arc- and every one used by the markup must exist here
 * or in arcade.css (tests/design-language.test.mjs walks both).
 *
 * TOKENS. This sheet declares none: the --arc-* values are declared on
 * body[data-app="minigame"] in arcade.css. Every read of a token that arcade.css
 * did not carry before this redesign is written var(--name, value) with the
 * value the spec gives it, so the page renders complete while the two sheets
 * land in parallel. Once arcade.css declares them the fallbacks are dead
 * weight and may be trimmed; they are never a second source of truth. */

/* ================================================================= the band */

/* The stage is the page: full bleed under the live bar, the cabinet's 2px tube
   as its top edge (.arc-tube, arcade.css), the deck after the picture. Isolated
   so nothing inside can reach the bar's z-index. */
.arc-band {
  position: relative;
  isolation: isolate;
  width: 100%;
  background: var(--arc-glass, #050506);
}

/* The screen. It sits under the sticky bar and the ribbon, never over them: a
   fixed or taller element would paint across the nav and fail the pinned-bar
   test. 100dvh rather than 100vh, because on a phone vh is the viewport WITHOUT
   the browser chrome and the stage would be taller than the screen. */
.arc-arena-wrap {
  position: relative;
  isolation: isolate;
  width: 100%;
  height: var(--arc-stage);
  min-height: 22rem;
  /* clip, never hidden: hidden makes a scroll container. */
  overflow: clip;
  /* Without this a touch drag scrolls the page instead of steering, and the
     pointermove handler never sees the second event. */
  touch-action: none;
}

/* The element's size is the stylesheet's; the renderer only writes the drawing
   buffer, so no device pixel ratio can make it wider than this column. */
.arc-stage {
  position: relative;
  z-index: 0;
  display: block;
  width: 100%;
  height: 100%;
}

/* ============================================================= the banners */

/* Top centre, over the picture: the chain's third state and the wrong-device
   warning. Read-only, so they take no pointer events and steering passes
   through them. */
.arc-banners {
  position: absolute;
  top: var(--pickle-space-4);
  left: 50%;
  transform: translateX(-50%);
  z-index: 3;
  width: min(40rem, calc(100% - 2 * var(--pickle-space-4)));
  display: grid;
  gap: var(--pickle-space-2);
  pointer-events: none;
}

.arc-banners .ex-banner {
  margin: 0;
  background: var(--arc-plate-hard, rgb(5 5 6 / 88%));
  font-size: var(--pickle-text-sm);
}

/* The stage has stopped drawing. It sits over the canvas AND the plates,
   because a frozen picture with an explanation somewhere else is still a
   frozen picture that looks live. */
.arc-stage-lost {
  position: absolute;
  inset: 0;
  z-index: 4;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--pickle-space-5);
  text-align: center;
  color: var(--pickle-amber);
  font-size: var(--pickle-text-xs);
  /* It covers the stage, and the overlay's controls stay reachable through it:
     a player whose session is stuck still needs the Leave button under here. */
  pointer-events: none;
  /* Literal rather than a token through color-mix: no other stylesheet in this
     estate uses color-mix, and this is the one message that must render even
     where it is not supported. #050506 is --pickle-bg-deep. */
  background: rgb(5 5 6 / 86%);
}

/* ============================================================== the console */

/* Bottom left, one plate. The class name is load-bearing: the steering filter
   in arena.jsx ignores pointer events raised inside `.arc-overlay`. */
.arc-overlay {
  position: absolute;
  left: var(--arc-inset, max(var(--pickle-gutter), calc((100vw - var(--pickle-content)) / 2)));
  bottom: var(--pickle-space-4);
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--pickle-space-2);
  max-width: min(26rem, calc(100% - 2 * var(--pickle-space-4)));
  padding: var(--pickle-space-3) var(--pickle-space-4);
  background: var(--arc-plate, rgb(5 5 6 / 74%));
  border: 1px solid var(--pickle-line);
  border-radius: var(--pickle-radius);
  font-family: var(--pickle-font-mono);
  font-size: var(--pickle-text-xs);
  color: var(--pickle-muted);
  /* ONLY THE BUTTONS MAY EAT A POINTER EVENT. Steering ignores anything raised
     inside this overlay, so every line of text in it used to carve a dead zone
     out of the stage, and a notice appearing mid-game widened that zone over
     the corner a player is most likely steering across. The text needs no
     pointer events at all; the buttons take theirs back below. */
  pointer-events: none;
}

.arc-overlay .ex-btn { pointer-events: auto; }

.arc-players,
.arc-you,
.arc-pending {
  margin: 0;
  display: inline-flex;
  align-items: center;
  gap: var(--pickle-space-2);
}

/* The link line, three answers: live is white with the estate's mint pulse,
   asking is muted with a still white dot, down is amber with a still amber
   dot. A dead link must not keep a confident dot beating beside the words
   saying it is not there. */
.arc-players .ex-dot { margin: 0; background: currentColor; flex: none; }
.arc-players.live { color: var(--pickle-text); }
.arc-players.live .ex-dot { background: var(--pickle-mint); }
.arc-players.asking .ex-dot { background: rgb(255 255 255 / 40%); animation: none; }
.arc-players.down { color: var(--pickle-amber); }
.arc-players.down .ex-dot { background: var(--pickle-amber); animation: none; }

.arc-you { color: var(--pickle-text); font-variant-numeric: tabular-nums; }

.arc-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--pickle-space-2);
}

/* The in-flight lamp: white at 55%, never amber and never mint, because on
   this estate mint means confirmed and amber means warn, and a move that is
   out is neither. It pulses while the send is out (motion, below). */
.arc-lamp {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--arc-pending, rgb(255 255 255 / 55%));
  flex: none;
}

.arc-overlay .ex-out { max-width: 100%; }

/* ================================================================= the deck */

/* Bottom right, the instrument. Nothing in it is a control, so steering passes
   through it at desktop; on a phone it is in flow under the stage and takes
   its pointer events back like any page. */
.arc-deck {
  position: absolute;
  right: var(--arc-inset, max(var(--pickle-gutter), calc((100vw - var(--pickle-content)) / 2)));
  bottom: var(--pickle-space-4);
  z-index: 3;
  width: min(22rem, calc(100% - 2 * var(--pickle-space-4)));
  padding: var(--pickle-space-3) var(--pickle-space-4);
  background: var(--arc-plate, rgb(5 5 6 / 74%));
  border: 1px solid var(--pickle-line);
  border-radius: var(--pickle-radius);
  display: grid;
  gap: var(--pickle-space-2);
  pointer-events: none;
}

.arc-deck-fig {
  margin: 0;
  display: flex;
  align-items: baseline;
  gap: var(--pickle-space-2);
}

.arc-deck-ms { font-size: var(--arc-figure, clamp(1.5rem, 2.4vw, 2rem)); }
.arc-deck-fig span { color: var(--pickle-muted); font-size: var(--pickle-text-sm); }

.arc-deck-meta,
.arc-hist-x,
.arc-hist-legend {
  margin: 0;
  font-size: var(--pickle-text-2xs);
  color: var(--pickle-subtle);
  font-variant-numeric: tabular-nums;
}

.arc-hist-x { display: flex; justify-content: space-between; }

/* The histogram: the SVG carries the geometry, this sheet the colours. */
.arc-hist { height: 64px; }
.arc-hist-svg { display: block; width: 100%; height: 100%; }

.arc-bar { fill: var(--arc-bar, rgb(0 231 136 / 70%)); }
.arc-bar-last { fill: var(--arc-bar-last, #7dffbf); }
/* A refusal is an error outcome, so its outline is rose; a receipt that never
   came back is a warning, so its outline is amber and dashed. Both hollow: a
   round trip that was not a move must not read as one. */
.arc-bar-refused { fill: none; stroke: var(--arc-refused, rgb(255 92 92 / 70%)); stroke-width: 1; }
.arc-bar-unknown { fill: none; stroke: var(--arc-unknown, rgb(244 163 0 / 70%)); stroke-width: 1; stroke-dasharray: 2 2; }
/* White because the median is a fact about the data, not a verdict on it. */
.arc-hist-median { stroke: var(--arc-median, #ffffff); stroke-width: 1; }
.arc-hist-target { stroke: var(--arc-target, rgb(0 231 136 / 35%)); stroke-width: 1; }
.arc-hist-axis,
.arc-hist-tick { stroke: var(--arc-grid-strong, rgb(255 255 255 / 9%)); stroke-width: 1; }

.arc-hud-idle,
.arc-hud-note {
  margin: 0;
  color: var(--pickle-subtle);
  font-size: var(--pickle-text-xs);
  max-width: 46rem;
}

/* The one line under the stage. <main> keeps the estate's editorial padding,
   which is a page's worth of air around a single sentence here; the notes pull
   themselves up to sit under the band and let the footer follow. */
.arc-notes {
  display: grid;
  gap: var(--pickle-space-2);
  margin-top: calc(var(--pickle-space-5) - var(--pickle-section-sm));
  margin-bottom: calc(var(--pickle-space-6) - var(--pickle-section));
}

/* =========================================================== the death card */

/* AFTER .arc-overlay, on purpose: the card carries both classes so its buttons
   pass the steering filter, and its position, width, ground and border win
   over the console's by order alone. Amber for the life of the card: "You
   died" is warn, and only the settled line is the good news. */
.arc-death {
  /* Centred by auto margins inside inset 0, not by a transform: the landing
     animation (ex-in-sm) ends on `transform: none` and, with fill both, would
     keep it there, so a transform-centred card would land off centre. */
  inset: 0;
  margin: auto;
  height: fit-content;
  max-height: calc(100% - 2rem);
  overflow: auto;
  width: min(26rem, calc(100% - 2rem));
  max-width: none;
  padding: var(--pickle-space-5);
  background: var(--arc-plate-hard, rgb(5 5 6 / 88%));
  border-color: var(--pickle-amber-line);
  gap: var(--pickle-space-3);
  /* Steering is unbound while dead, so the card may take the pointer: the
     hash is there to be selected and copied. */
  pointer-events: auto;
}

.arc-death-score { font-size: var(--arc-read, clamp(2.2rem, 4vw, 3.4rem)); }

.arc-death-cause {
  margin: 0;
  font-family: var(--pickle-font);
  font-size: var(--pickle-text-sm);
  color: var(--pickle-muted);
  line-height: 1.5;
}

.arc-death-settle {
  margin: 0;
  display: inline-flex;
  align-items: center;
  gap: var(--pickle-space-2);
  color: var(--pickle-muted);
}
.arc-death-settle.ok { color: var(--pickle-accent-text); }
.arc-death-settle.warn { color: var(--pickle-amber); }

.arc-death-hash { margin: 0; }

.arc-death-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--pickle-space-2);
}

/* ================================================================ the phone */

/* One plate over the picture. The stage gives up a third of the screen so the
   deck, the figure and the scheduling-target sentence are on the first screen
   while playing, in flow, on the band's ground rather than on a plate. */
@media (max-width: 1023px) {
  .arc-arena-wrap { height: var(--arc-stage-phone, min(var(--arc-stage), 66dvh)); }
  .arc-deck {
    position: static;
    width: auto;
    background: transparent;
    border: 0;
    border-top: 1px solid var(--pickle-line);
    border-radius: 0;
    padding: var(--pickle-space-4) var(--pickle-gutter);
    pointer-events: auto;
  }
  .arc-hist { height: 56px; }
}

@media (max-width: 639px) {
  .arc-overlay {
    left: var(--pickle-space-4);
    right: var(--pickle-space-4);
    max-width: none;
  }
  .arc-death { inset: 0; }
}

/* =================================================================== motion */

/* Load: the tube strikes at 200 ms, the screen turns on at 480 ms, the console
   and the deck appear together as one move at 700 ms. The card lands with the
   estate's small rise whenever it mounts; without its own rule the shared
   .arc-overlay entrance would hold it invisible for its 700 ms delay. The lamp
   pulses while a send is out, and nothing else here loops. Keyframes
   arc-strike and arc-screen-on are arcade.css's. */
@media (prefers-reduced-motion: no-preference) {
  .arc-band .arc-tube { animation: arc-strike 480ms steps(1, end) 200ms both; }
  .arc-arena-wrap {
    animation: arc-screen-on 260ms var(--pickle-ease) 480ms both;
    transform-origin: 50% 50%;
  }
  .arc-overlay,
  .arc-deck { animation: ex-in-sm 480ms var(--pickle-ease) 700ms both; }
  .arc-overlay.arc-death { animation: ex-in-sm 420ms var(--pickle-ease) both; }
  .arc-lamp { animation: pickle-pulse .9s infinite; }
}
