/* Interface layout. Colours all come from theme.css. */

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

/* Anything marked hidden stays hidden.
   The browser's own rule for [hidden] is display:none, but any style
   of ours that sets display - .panel, .choices, .overlay - outranks it
   and quietly puts the element back on screen. That is how both menu
   panels ended up stacked on top of each other while the code believed
   one of them was hidden. */
[hidden] { display: none !important; }

html, body {
  margin: 0; padding: 0;
  height: 100%; width: 100%;
  overflow: hidden;
  background: var(--bg);
  color: var(--ui-text);
  font-family: ui-sans-serif, -apple-system, "Helvetica Neue", sans-serif;
  overscroll-behavior: none;
  touch-action: none;
  user-select: none; -webkit-user-select: none;
}

#stage { position: fixed; inset: 0; }

#court {
  display: block;
  width: 100%; height: 100%;
  touch-action: none;
}

/* ---- Heads-up display ---- */

#hud {
  position: fixed;
  top: env(safe-area-inset-top, 0px);
  left: env(safe-area-inset-left, 0px);
  right: env(safe-area-inset-right, 0px);
  padding: 0.7rem 1rem;
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  pointer-events: none;
  font-variant-numeric: tabular-nums;
}

.score-block { display: flex; flex-direction: column; gap: 0.12rem; }
.score-block.cpu { align-items: flex-end; }

.score-label {
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ui-dim);
}
.score-value { font-size: 1.9rem; font-weight: 600; line-height: 1; }
.score-block.you .score-value { color: var(--paddle-you); }
.score-block.cpu .score-value { color: var(--paddle-cpu); }

.centre {
  align-self: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.2rem;
  padding-top: 0.5rem;
}

#rally, #latency {
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ui-dim);
  font-variant-numeric: tabular-nums;
  transition: opacity 0.25s, color 0.25s;
}

/* The run score. Breaker only - it takes the centre column, which in
   that mode has nothing else to say. */
#run-score {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.1rem;
  line-height: 1;
}
#run-points {
  font-size: 1.35rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ui-fg);
}
#run-combo {
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ui-accent);
  opacity: 0;
  transition: opacity 0.18s;
}
#run-combo.on { opacity: 1; }

#rally { opacity: 0; }
#rally.on { opacity: 1; }

/* The connection reading stays up for the whole game rather than
   taking turns with the rally count - when a ball stutters, this is
   the first thing worth looking at. */
#latency { opacity: 0; }
#latency.on { opacity: 1; }
#latency.fair { color: var(--ui-accent); }
#latency.poor { color: var(--paddle-cpu); }

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

.overlay {
  position: fixed; inset: 0;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 1.15rem;
  padding: calc(env(safe-area-inset-top, 0px) + 1.5rem) 1.5rem
           calc(env(safe-area-inset-bottom, 0px) + 1.5rem);
  background: var(--ui-panel);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  text-align: center;
}

.title {
  font-size: clamp(2.2rem, 11vw, 3.4rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1;
  margin: 0;
}
.subtitle { color: var(--ui-dim); margin: 0; font-size: 0.95rem; max-width: 30ch; line-height: 1.5; }

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

button {
  font: inherit;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--ui-text);
  background: transparent;
  border: 1.5px solid var(--ui-line);
  border-radius: 3px;
  padding: 0.6rem 1.15rem;
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s;
}
button:hover { border-color: var(--ui-dim); }
button:focus-visible { outline: 2px solid var(--ui-accent); outline-offset: 2px; }
button[aria-pressed="true"] { border-color: var(--ui-accent); color: var(--ui-accent); }

button.primary {
  border-color: var(--ui-accent);
  color: var(--bg);
  background: var(--ui-accent);
  padding: 0.72rem 2rem;
  font-size: 1.02rem;
}
button.primary:hover { opacity: 0.9; border-color: var(--ui-accent); }

.hint {
  font-size: 0.75rem;
  color: var(--ui-dim);
  letter-spacing: 0.03em;
  max-width: 32ch;
  line-height: 1.55;
  margin: 0;
}

.field-label {
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ui-dim);
  margin: 0 0 -0.55rem;
}

/* Serve prompt shown over the court */
#message {
  position: fixed;
  left: 0; right: 0;
  top: 50%;
  transform: translateY(-50%);
  text-align: center;
  pointer-events: none;
  font-size: clamp(1.1rem, 5vw, 1.5rem);
  font-weight: 600;
  letter-spacing: -0.01em;
  opacity: 0;
  transition: opacity 0.2s;
}
#message.on { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  * { transition-duration: 0.01ms !important; }
}

/* ---- Playing a friend ---- */

.panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.9rem;
}

input[type="text"] {
  font: inherit;
  font-size: 1.15rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  text-align: center;
  width: 6.5rem;
  color: var(--ui-text);
  background: transparent;
  border: 1.5px solid var(--ui-line);
  border-radius: 3px;
  padding: 0.55rem 0.5rem;
}
input[type="text"]::placeholder { color: var(--ui-dim); opacity: 0.55; letter-spacing: 0.22em; }
input[type="text"]:focus { outline: none; border-color: var(--ui-accent); }

button.quiet {
  border-color: transparent;
  color: var(--ui-dim);
  font-weight: 500;
  font-size: 0.85rem;
}
button.quiet:hover { color: var(--ui-text); border-color: transparent; }

.code {
  font-size: clamp(2.6rem, 15vw, 4rem);
  font-weight: 700;
  letter-spacing: 0.16em;
  text-indent: 0.16em;      /* keeps it optically centred despite the tracking */
  line-height: 1;
  color: var(--ui-accent);
  font-variant-numeric: tabular-nums;
}

/* THE READY CARD: who you are, what the match is, what it pays. */
.queue-who {
  display: flex; align-items: baseline; justify-content: center; gap: 0.5rem;
  margin: 0.2rem 0 0.1rem; flex-wrap: wrap;
}
.queue-who b {
  font-family: "Baloo 2", ui-rounded, system-ui, sans-serif;
  font-weight: 800; font-size: 1.25rem; color: var(--ui-text);
}
.queue-who span {
  font-family: Orbitron, ui-monospace, monospace;
  font-size: 0.6rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ui-dim);
}
.queue-facts {
  list-style: none; margin: 0.9rem 0 0.2rem; padding: 0;
  display: flex; flex-direction: column; gap: 0.35rem;
  font-size: 0.85rem; color: var(--ui-dim);
}
.queue-facts b { color: var(--ui-text); font-variant-numeric: tabular-nums; }
.queue-ranked {
  margin: 1rem 0 0; font-size: 0.72rem; line-height: 1.5;
  color: var(--ui-dim); max-width: 22rem;
}

/* THE WAIT. A ball going back and forth over a line, in the gold the
   credits use. Three static dots looked like the screen had stopped,
   which is the one thing a waiting screen must never look like. */
.rallying {
  position: relative;
  width: min(62%, 11rem);
  height: 2rem;
  margin: 0.5rem auto 0.1rem;
}
.rallying::before {
  content: '';
  position: absolute; left: 0; right: 0; top: 50%;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--edge), transparent);
}
.rally-ball {
  position: absolute; top: 50%; left: 0;
  width: 0.72rem; height: 0.72rem; margin-top: -0.36rem;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #FFF0B5, #F2C14E 55%, #9A6E12);
  box-shadow: 0 0 10px rgba(242, 193, 78, 0.65);
  animation: rally-across 1.5s cubic-bezier(0.45, 0, 0.55, 1) infinite alternate,
             rally-squash 1.5s ease-in-out infinite alternate;
}
@keyframes rally-across {
  from { left: 0; }
  to   { left: calc(100% - 0.72rem); }
}
/* squashed at the ends, round through the middle - the same trick the
   ball in the game uses to say it was struck */
@keyframes rally-squash {
  0%   { transform: scale(0.82, 1.18); }
  16%  { transform: scale(1, 1); }
  84%  { transform: scale(1, 1); }
  100% { transform: scale(0.82, 1.18); }
}
@media (prefers-reduced-motion: reduce) {
  .rally-ball { animation: none; left: calc(50% - 0.36rem); }
}
/* a quieter button, for the second thing you can do on a card */
.pill-btn.quiet {
  background: transparent;
  border: 1px solid var(--edge-dim);
  color: var(--ui-dim);
  box-shadow: none;
}

.link {
  font-size: 0.72rem;
  color: var(--ui-dim);
  word-break: break-all;
  max-width: 26ch;
  margin: 0;
  line-height: 1.5;
}

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

.icon-button {
  position: absolute;
  top: calc(env(safe-area-inset-top, 0px) + 0.8rem);
  right: calc(env(safe-area-inset-right, 0px) + 0.9rem);
  width: 2.6rem; height: 2.6rem;
  display: flex; align-items: center; justify-content: center;
  padding: 0;
  border: none;
  color: var(--ui-dim);
  background: transparent;
}
.icon-button:hover { color: var(--ui-text); border: none; }
.icon-button svg {
  width: 1.35rem; height: 1.35rem;
  fill: none; stroke: currentColor;
  stroke-width: 1.7; stroke-linecap: round;
}

.panel-title {
  font-size: 1.35rem;
  font-weight: 700;
  letter-spacing: -0.015em;
  margin: 0;
}

.settings-list {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  width: 100%;
  max-width: 26rem;
  text-align: left;
}

.setting {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0.9rem 1rem;
  align-items: center;
  padding: 0.95rem 0.2rem;
  border-top: 1px solid var(--ui-line);
}
.setting:first-child { border-top: none; }

.setting-label { font-weight: 600; font-size: 0.98rem; }
.setting-note {
  grid-column: 1;
  font-size: 0.8rem;
  color: var(--ui-dim);
  line-height: 1.5;
  margin: 0.2rem 0 0;
  max-width: 34ch;
}

/* The picker: every option in a scrolling grid, the current one lit. */
.picker { z-index: 30; }
.picker-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.5rem;
  width: 100%;
  max-width: 26rem;
  max-height: 62vh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 0.2rem;
}
.picker-item {
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 0.75rem 0.6rem;
  border: 1.5px solid var(--ui-line);
  border-radius: 0.7rem;
  background: transparent;
  color: var(--ui-text);
  text-align: center;
}
.picker-item.current {
  border-color: var(--ui-accent);
  color: var(--ui-accent);
  box-shadow: 0 0 0 1px var(--ui-accent) inset;
}

/* A switch, not a checkbox: it reads as on or off at a glance. */
.switch {
  width: 3rem; height: 1.7rem;
  padding: 0;
  border: 1.5px solid var(--ui-line);
  border-radius: 1rem;
  background: transparent;
  position: relative;
  grid-row: span 2;
  transition: background 0.18s, border-color 0.18s;
  flex: none;
}
.switch span {
  position: absolute;
  top: 50%; left: 0.2rem;
  width: 1.15rem; height: 1.15rem;
  margin-top: -0.575rem;
  border-radius: 50%;
  background: var(--ui-dim);
  transition: transform 0.18s, background 0.18s;
}
.switch[aria-checked="true"] {
  background: var(--ui-accent);
  border-color: var(--ui-accent);
}
.switch[aria-checked="true"] span {
  background: var(--bg);
  transform: translateX(1.25rem);
}
.switch:focus-visible { outline: 2px solid var(--ui-accent); outline-offset: 3px; }

.choice-value {
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: capitalize;
  color: var(--ui-accent);
  border-color: var(--ui-line);
  padding: 0.45rem 0.9rem;
  grid-row: span 2;
}

/* A way out of a game in progress.
   Bottom left, where the court is not and a thumb playing the game is
   not either. It only ever appears while a game is running. */
#quit-game {
  position: fixed;
  left: calc(env(safe-area-inset-left, 0px) + 0.7rem);
  bottom: calc(env(safe-area-inset-bottom, 0px) + 0.7rem);
  z-index: 4;
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ui-dim);
  border-color: transparent;
  padding: 0.5rem 0.75rem;
}
#quit-game:hover { color: var(--ui-text); border-color: var(--ui-line); }

/* ============================================================
   HUD chrome — the court decides what the interface wears.
   Set by Skins.applyToPage as data-hud on the root element.
   ============================================================ */

/* plain — the default: tracked caps, no background */

[data-hud="arcade"] .score-value,
[data-hud="arcade"] .title,
[data-hud="arcade"] .panel-title,
[data-hud="arcade"] .code {
  font-family: "Baloo 2", ui-rounded, "Trebuchet MS", system-ui, sans-serif;
  font-weight: 800;
}
[data-hud="arcade"] .score-block {
  padding: 0.3rem 0.6rem;
  border-radius: 8px;
  background: rgba(0, 0, 0, 0.28);
  border: 2px solid rgba(255, 255, 255, 0.75);
}
[data-hud="arcade"] .score-label { color: rgba(255, 255, 255, 0.72); }

[data-hud="neon"] .score-value,
[data-hud="neon"] .title,
[data-hud="neon"] .panel-title,
[data-hud="neon"] .code {
  font-family: Orbitron, ui-monospace, "Courier New", monospace;
  font-weight: 800;
  letter-spacing: 0.02em;
}
[data-hud="neon"] .score-block {
  padding: 0.3rem 0.65rem;
  border-radius: 3px;
  background: rgba(0, 0, 0, 0.35);
  border: 1px solid currentColor;
}
[data-hud="neon"] .score-block.you  { color: var(--paddle-you); }
[data-hud="neon"] .score-block.cpu  { color: var(--paddle-cpu); }
[data-hud="neon"] .score-block.you .score-value { text-shadow: 0 0 10px var(--paddle-you); }
[data-hud="neon"] .score-block.cpu .score-value { text-shadow: 0 0 10px var(--paddle-cpu); }
[data-hud="neon"] .score-label { color: inherit; opacity: 0.7; }
[data-hud="neon"] .title { text-shadow: 0 0 18px var(--ui-accent); }

/* The two settings rows are longer now, so the list may need to scroll
   on a short screen rather than pushing the Done button off the end. */
.settings-list {
  max-height: 60vh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

/* ============================================================
   Held sideways.

   The court is the same either way, so the only question is where
   the interface goes. Upright it sits across the top, because a tall
   screen has room there. Turned sideways the court is limited by the
   height, and there is a wide band of spare width at each side - so
   the scoreboard moves into it and the court keeps the full height.
   That is what makes both orientations draw the court the same size.
   ============================================================ */

@media (orientation: landscape) {
  #hud {
    top: 0; bottom: 0;
    padding: 0.6rem calc(env(safe-area-inset-right, 0px) + 0.7rem)
             0.6rem calc(env(safe-area-inset-left, 0px) + 0.7rem);
    align-items: center;
  }
  /* Narrow, so the scoreboard fits in the spare width rather than
     stealing it. Sideways the court is limited by the screen's height
     and there is only a little width to spare - a plate wide enough to
     eat into it shrinks the court, which is what made the two
     orientations disagree. */
  .score-block { align-items: center; gap: 0.05rem; }
  .score-block.cpu { align-items: center; }
  .score-value { font-size: 1.55rem; }
  .score-label { font-size: 0.55rem; letter-spacing: 0.1em; }

  [data-hud="arcade"] .score-block,
  [data-hud="neon"] .score-block {
    padding: 0.2rem 0.3rem;
    min-width: 2.1rem;
  }

  /* Small enough to sit in the corner without touching the court's
     bottom edge. */
  #quit-game { font-size: 0.6rem; padding: 0.35rem 0.4rem; }

  /* The labels are what made the plates wide - "COMPUTER" is a long
     word and the block is as wide as its widest child. Sideways there
     is no room for it, and none needed: the two are already told apart
     by which side they are on and by colour. */
  .score-label { display: none; }
  .score-block { max-width: 18vw; }

  /* The court now fills the height, so the top middle is over it. The
     rally and connection readings go into the left margin instead,
     under the score, where there is nothing else. */
  .centre {
    position: fixed;
    top: 58%;
    left: calc(env(safe-area-inset-left, 0px) + 0.7rem);
    align-items: flex-start;
    padding-top: 0;
    max-width: 5rem;
  }
  #rally, #latency { font-size: 0.55rem; letter-spacing: 0.1em; }

  #quit-game {
    bottom: calc(env(safe-area-inset-bottom, 0px) + 0.5rem);
    left: calc(env(safe-area-inset-left, 0px) + 0.6rem);
  }

  /* menus stay readable on a short screen */
  .overlay { gap: 0.75rem; padding-top: 0.8rem; padding-bottom: 0.8rem; }
  .title { font-size: clamp(1.8rem, 7vw, 2.6rem); }
  .settings-list { max-height: 52vh; }
  .hint { display: none; }
}

/* One button per breaker level. */
.level-button {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  align-items: center;
  padding: 0.55rem 0.9rem;
  min-width: 7rem;
}
.level-name { font-weight: 700; font-size: 0.95rem; }
.level-note {
  font-size: 0.62rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ui-dim);
}
/* ---- the campaign map ----

   Levels as nodes running away down a tunnel, which is the same shape
   as the court they are played in - the menu and the game are meant to
   read as the same place.

   Depth is done by scale and dimming rather than by CSS perspective.
   A real 3D transform would fight the live court rendering behind it
   for the same vanishing point and lose, because that one is set by a
   camera and this one by a stylesheet. Sizing each node by how far
   down the chain it is gets the same read and always agrees with the
   picture behind it. */

.panel.wide { width: 100%; max-width: none; }

/* While the map is up, the menu's own backdrop gets out of the way.

   The map is drawn IN the court now, so a translucent, blurred sheet
   over the canvas is a sheet over the map - which is why the nodes came
   out as faint smudges even though they were bright, correctly placed
   objects in the scene. The interface keeps only its words. */
#menu.mapping {
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  justify-content: flex-end;
  pointer-events: none;
}
#menu.mapping > * { pointer-events: auto; }
#menu.mapping .hint { display: none; }
/* The game's scoreboard belongs to a game, and there is not one on. */
body:has(#menu.mapping:not([hidden])) #hud { opacity: 0; }
/* nor in the lobby, or under the store and settings */
body:has(#menu.lobby:not([hidden])) #hud,
body:has(#store:not([hidden])) #hud,
body:has(#settings:not([hidden])) #hud { opacity: 0; }

#tunnel {
  position: relative;
  width: 100%;
  height: 66vh;
  max-height: 34rem;
  overflow: hidden;
  /* The map handles its own dragging, so the browser must not also try
     to scroll the page with the same finger. */
  touch-action: none;
}

/* Pinned to the viewport, not to the panel.

   The labels are placed by projecting each cube through the camera,
   which answers in the canvas's own coordinates - so the layer holding
   them has to share those coordinates. Sitting inside the panel meant
   every label was offset by wherever the panel happened to be. */
#tunnel-track {
  position: fixed;
  inset: 0;
  pointer-events: none;
}

/* The words that go with a node. The cube itself is drawn in the 3D
   scene; this is only the label, put where the camera says that cube
   landed. Text is kept out of the scene so it stays crisp - a name
   rendered into a 3D texture at the far end of a tunnel is a smudge. */
.node-label {
  position: absolute;
  display: flex;
  /* Number and stars on ONE line. Stacked, a node's label was two
     rows deep and the pair hung well below the box - which is a lot of
     interface under something the size of a die, and it is what kept
     running into the caption at the near end of the board. Side by
     side it reads as one small tag under the piece. */
  flex-direction: row;
  align-items: center;
  gap: 0.45em;
  transform: translate(-50%, 0);
  white-space: nowrap;
  pointer-events: none;      /* the tap is handled against the cubes */
}

.node-name {
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ui-text);
  font-size: 1em;
}
.node-label.locked .node-name { color: var(--ui-line); }

.stars { display: flex; gap: 0.18em; justify-content: center; line-height: 1; }
.stars span { color: var(--ui-dim); opacity: 0.3; font-size: 1em; }

/* An earned star is LIT, not printed.

   Flat gold glyphs sat on the board like stickers: everything else in
   the menu - the nodes, the route, the grid - is glass and light, and a
   solid shape with a hard edge next to that reads as belonging to a
   different picture. So the fill is nearly white, the way the middle of
   anything bright is, and the gold is thrown around it as light. */
.stars span.on {
  color: #FFE9B4;
  opacity: 1;
  text-shadow:
    0 0 3px var(--star-on, #FFC64A),
    0 0 8px rgba(255, 176, 40, 0.75),
    0 0 18px rgba(255, 150, 20, 0.45);
}
#over-stars span { font-size: 1.5rem; }

/* The bar across the top of the board. Fixed to the screen rather than
   flowing with the panel, because the panel is only a frame around a
   court that fills the whole viewport. */
#tunnel-bar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: max(0.5rem, env(safe-area-inset-top)) 0.9rem 0.7rem;
  background: linear-gradient(to bottom,
              rgba(1, 4, 12, 0.85) 55%, rgba(1, 4, 12, 0));
  z-index: 5;
}

#tunnel-bar #breaker-back { flex: none; margin: 0; padding: 0.3rem 0.2rem; }

#tunnel-caption {
  margin: 0;
  flex: 1;
  text-align: center;
  min-height: 2.4rem;
  /* Kept clear of the Back button on the left, so the name of the level
     stays centred on the board rather than on what is left of the bar. */
  padding-right: 3rem;
}

/* The name of whatever the board is looking at, then where that sits
   in the run. Two lines, because one line holding both is too long to
   read at a glance on a phone. */
.cap-name {
  display: block;
  color: var(--ui-text);
  letter-spacing: 0.16em;
  font-size: 0.82rem;
}

.cap-rest { display: block; }

/* On the same line as the name it belongs to. */
.cap-stars { display: inline-flex; margin-left: 0.55em; vertical-align: baseline; }
.cap-stars span { font-size: 0.8em; }

/* Stars, wherever they appear: on a level button and on the result
   screen. An earned star is lit; an unearned one is left in place so
   you can see what is still on offer. */
#over-stars { margin: 0.1rem 0 0.2rem; }

/* The scoring, broken out, so the number on the result screen is
   something you can argue with rather than just receive. */
.tally {
  display: grid;
  grid-template-columns: auto auto;
  gap: 0.22rem 1.2rem;
  margin: 0.5rem 0 0.2rem;
  font-size: 0.78rem;
  font-variant-numeric: tabular-nums;
}
.tally dt { color: var(--ui-dim); text-align: left; }
.tally dd { margin: 0; text-align: right; font-weight: 600; }
.tally dt.lead, .tally dd.lead {
  color: var(--ui-accent);
  font-size: 0.92rem;
  padding-top: 0.3rem;
  margin-top: 0.15rem;
  border-top: 1px solid var(--ui-line, rgba(255,255,255,0.14));
}


/* ---- the level card ----

   What you get when you pick a node on the campaign map: what the
   level is, how you did on it last time, and what finishing it is
   worth - before you commit to playing it. It sits over the board
   rather than replacing it, so the level you are reading about is
   still the cube you tapped. */
#node-card {
  position: fixed;
  left: 50%;
  bottom: 1rem;
  transform: translateX(-50%);
  width: min(24rem, calc(100vw - 1.8rem));
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: 0.7rem;
  background: var(--ui-panel);
  border: 1px solid var(--ui-accent);
  border-radius: 0.9rem;
  box-shadow: 0 0 1.4rem rgba(87, 232, 255, 0.16), 0 0.6rem 2rem rgba(0, 0, 0, 0.55);
  z-index: 6;
}


/* The reward line. A set piece at the end of a sector pays for
   itself; an ordinary level says what par is instead. */
#card-reward {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  padding: 0.4rem 0.55rem;
  border: 1px solid var(--ui-accent);
  border-radius: 0.5rem;
  background: rgba(255, 176, 32, 0.07);
}

#card-reward .tag {
  font-size: 0.68rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ui-dim);
}

#node-card .choices { display: flex; gap: 0.5rem; }
#node-card .choices button { flex: 1; }


/* ---- the store ----

   A list of what there is, in sections, with the purse at the top.
   Everything in it is drawn from the catalogue, so this styles kinds
   of row rather than particular items. */
.purse {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 1.2rem;
  margin: 0 0 0.9rem;
}

.purse-credits {
  font-size: 1.35rem;
  color: var(--star-on, var(--ui-accent));
  letter-spacing: 0.04em;
  font-variant-numeric: tabular-nums;
}

.purse-level { color: var(--ui-dim); letter-spacing: 0.12em; font-size: 0.75rem; }

.store-list {
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
  width: 100%;
  max-height: 60vh;
  overflow-y: auto;
  /* The list scrolls; the page behind it must not come with it. */
  overscroll-behavior: contain;
}

.store-section-name {
  text-align: left;
  margin: 0 0 0.35rem;
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ui-dim);
}

.store-row {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding: 0.55rem 0;
  border-top: 1px solid var(--ui-line);
}

.store-row .store-what { flex: 1; min-width: 0; text-align: left; }
.store-row .store-name { letter-spacing: 0.04em; }
.store-row .store-note {
  margin: 0.15rem 0 0;
  font-size: 0.72rem;
  color: var(--ui-dim);
  /* Long enough to say what a thing does, short enough not to become
     a paragraph in a list. */
  line-height: 1.35;
}

/* How many of a consumable are on the shelf at home. */
.store-held {
  font-size: 0.72rem;
  color: var(--star-on, var(--ui-accent));
  letter-spacing: 0.08em;
}

.store-buy {
  flex: none;
  min-width: 5.2rem;
  padding: 0.42rem 0.6rem;
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
}

.store-buy[disabled] { opacity: 0.4; }

/* The boosts you can arm, on the level card. */
.card-boosts { display: flex; gap: 0.45rem; flex-wrap: wrap; }

.card-boost {
  flex: 1 1 auto;
  padding: 0.4rem 0.5rem;
  font-size: 0.74rem;
  letter-spacing: 0.04em;
}

.card-boost.on {
  border-color: var(--star-on, var(--ui-accent));
  color: var(--star-on, var(--ui-accent));
}

/* Its own line under the buttons, rather than squeezed in beside
   them - .choices is a row, and a balance is not a choice. */
#purse-line { flex-basis: 100%; margin: 0.4rem 0 0; text-align: center; }

/* ============================================================
   THE LOBBY (2026-09-13)

   The home screen is a place: the court you picked is live behind
   it and your ball hangs in the middle. Everything the interface
   adds is glass - dark panels with a lit top edge, the room's own
   colour coming through - and round pucks for the places you can
   go. No bar.
   ============================================================ */
/* the glass, as tokens every sheet shares */
.lobby, #node-card {
  --glass: rgba(10, 13, 20, 0.66);
  --glass-2: rgba(16, 20, 30, 0.52);
  --edge: rgba(228, 244, 255, 0.36);
  --edge-dim: rgba(228, 244, 255, 0.13);
  --gold: #F2C14E;
}
#menu.lobby {
  justify-content: flex-start;
  gap: 0;
  padding: calc(env(safe-area-inset-top, 0px) + 0.9rem) 1rem
           calc(env(safe-area-inset-bottom, 0px) + 1rem);
  background: linear-gradient(180deg,
    rgba(7, 9, 14, 0.62) 0%, rgba(7, 9, 14, 0.10) 26%,
    rgba(7, 9, 14, 0.18) 58%, rgba(7, 9, 14, 0.94) 100%);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  text-align: left;
}
/* the breaker map keeps its own transparent sheet */
#menu.lobby.mapping { background: transparent; justify-content: flex-end; }
#menu.lobby.mapping .topbar, #menu.lobby.mapping .brand,
#menu.lobby.mapping .rail { display: none; }
.rail.left { right: auto; left: calc(env(safe-area-inset-left, 0px) + 0.9rem); }
/* practice: the dials under the score, tappable while the court is not */
.tray { display: flex; gap: 0.3rem; justify-content: center; flex-wrap: wrap; margin-top: 0.3rem; pointer-events: auto; }
.tray .pill {
  font-family: Orbitron, ui-monospace, monospace; font-size: 0.48rem; letter-spacing: 0.12em; text-transform: uppercase;
  padding: 0.3rem 0.5rem; border-radius: 999px; border: 1px solid var(--edge-dim); background: var(--glass, rgba(10, 13, 20, 0.66));
  color: var(--ui-dim); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
}
.tray .pill b { color: var(--ui-text); font-weight: 600; margin-left: 0.2em; }
.tray .pill.go { color: var(--ui-accent); border-color: color-mix(in srgb, var(--ui-accent) 50%, transparent); }
.tray .pill:active { transform: scale(0.96); }

.topbar {
  width: 100%;
  display: flex; align-items: center; justify-content: space-between; gap: 0.6rem;
}
.pill {
  display: inline-flex; align-items: center; gap: 0.5rem;
  padding: 0.45rem 0.6rem 0.45rem 0.7rem;
  border-radius: 999px;
  border: 1px solid var(--edge-dim);
  background: var(--glass);
  box-shadow: inset 0 1px 0 var(--edge), 0 6px 18px rgba(0, 0, 0, 0.35);
  font-family: "Baloo 2", ui-rounded, system-ui, sans-serif;
  font-weight: 800; font-size: 0.95rem; letter-spacing: 0.01em;
  color: var(--ui-text);
  font-variant-numeric: tabular-nums;
}
.pill:hover { border-color: var(--edge-dim); }
.pill .coin {
  width: 1rem; height: 1rem; border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #FFF0B5, #F2C14E 55%, #9A6E12);
  box-shadow: 0 0 8px rgba(242, 193, 78, 0.6);
}
.pill .plus {
  width: 1.25rem; height: 1.25rem; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--ui-accent); color: var(--bg);
  font-family: ui-sans-serif, system-ui, sans-serif; font-weight: 800; font-size: 1rem; line-height: 1;
}
.rank { display: flex; flex-direction: column; align-items: center; gap: 0.3rem; }
.rank .rank-line { display: flex; align-items: center; gap: 0.5rem; }
/* the name sits under the bar, quieter than it but in the same place
   the eye already goes */
.rank .who { font-size: 0.64rem; padding: 2px 10px; }
.rank .lvl {
  font-family: Orbitron, ui-monospace, monospace;
  font-size: 0.68rem; letter-spacing: 0.1em; color: var(--ui-dim);
}
.rank .bar {
  width: 4.4rem; height: 6px; border-radius: 3px;
  background: rgba(255, 255, 255, 0.09); overflow: hidden;
}
.rank .bar i {
  display: block; height: 100%; width: 0;
  background: linear-gradient(90deg, var(--ui-accent), #fff);
  transition: width 0.4s;
}

/* the pucks: round glass, lit edge, an icon, a word */
.puck {
  display: flex; flex-direction: column; align-items: center; gap: 0.3rem;
  padding: 0; border: none; background: transparent;
  color: var(--ui-text);
  font-family: Orbitron, ui-monospace, monospace;
  font-size: 0.58rem; letter-spacing: 0.16em; text-transform: uppercase;
}
.puck svg {
  width: 3.6rem; height: 3.6rem; padding: 0.95rem;
  border-radius: 50%;
  border: 1px solid var(--edge-dim);
  background: radial-gradient(circle at 50% 22%, rgba(255, 255, 255, 0.10), rgba(0, 0, 0, 0) 55%), var(--glass);
  box-shadow: inset 0 1px 0 var(--edge), inset 0 -8px 14px rgba(0, 0, 0, 0.35), 0 8px 22px rgba(0, 0, 0, 0.45);
  fill: none; stroke: var(--ui-accent); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
  transition: transform 0.15s, box-shadow 0.15s;
}
.puck:hover { border: none; }
.puck:active svg { transform: scale(0.94); }
.puck.small { flex: none; }
.puck.small svg { width: 2.5rem; height: 2.5rem; padding: 0.6rem; stroke: var(--ui-dim); }
.puck.small span { display: none; }

.rail {
  position: absolute;
  right: calc(env(safe-area-inset-right, 0px) + 0.9rem);
  top: 27%;
  display: flex; flex-direction: column; gap: 0.7rem;
}

.brand { width: 100%; margin-top: 1.4rem; }
.brand .title { font-family: "Baloo 2", ui-rounded, system-ui, sans-serif; font-weight: 800; font-size: clamp(2rem, 9vw, 2.6rem); }
.brand-sub {
  margin: 0.35rem 0 0;
  font-family: Orbitron, ui-monospace, monospace;
  font-size: 0.62rem; letter-spacing: 0.22em; color: var(--ui-dim); text-transform: uppercase;
}

/* hard mode: ghost fire. The switch is a puck that lights silver when
   it is on, the room burns white round its edges (drawn by the
   renderer), and a chip says what it costs you. */
.lobby { --ember: #E6EAF2; }   /* hard mode is silver, like its flames */
.puck.hard { position: relative; }
/* no position on the icon: Safari stops rounding a positioned svg's background */
.puck.hard svg { stroke: var(--ui-dim); }
.puck.hard.on svg {
  stroke: var(--ember);
  border-color: color-mix(in srgb, var(--ember) 55%, transparent);
  background: radial-gradient(circle at 50% 70%, color-mix(in srgb, var(--ember) 32%, transparent), rgba(0, 0, 0, 0) 62%), var(--glass);
}
/* the pulse: a round ring of its own, animated by scale and fade only -
   iOS draws an animated box-shadow as a rectangle */
.puck.hard .ring {
  position: absolute; left: 0; top: 0; width: 2.5rem; height: 2.5rem;
  border-radius: 50%; pointer-events: none; opacity: 0;
  border: 2px solid var(--ember);
  box-shadow: 0 0 14px var(--ember);
}
.puck.hard.on .ring { animation: ember-ring 2.4s ease-out infinite; }
@keyframes ember-ring {
  0%   { transform: scale(0.92); opacity: 0.85; }
  70%  { transform: scale(1.45); opacity: 0; }
  100% { transform: scale(1.45); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .puck.hard.on .ring { animation: none; } }
/* THE TOUR - the words over the orrery */
#tour-bar {
  position: fixed; top: 0; left: 0; right: 0; z-index: 5;
  display: flex; align-items: center; gap: 0.6rem;
  padding: max(0.5rem, env(safe-area-inset-top)) 0.9rem 0.7rem;
  background: linear-gradient(to bottom, rgba(1, 4, 12, 0.85) 55%, rgba(1, 4, 12, 0));
}
#tour-bar #tour-back { flex: none; margin: 0; padding: 0.3rem 0.2rem;
  font-family: Orbitron, ui-monospace, monospace; font-size: 0.62rem; letter-spacing: 0.14em; text-transform: uppercase; }
#tour-caption { margin: 0; flex: 1; text-align: center;
  font-family: "Baloo 2", ui-rounded, system-ui, sans-serif; font-weight: 800; font-size: 1.15rem; color: var(--ui-text); }
#tour-count { flex: none; font-family: Orbitron, ui-monospace, monospace; font-size: 0.62rem; letter-spacing: 0.14em; color: var(--ui-dim); }
/* the tier strip: five glass pills under the bar */
#tour-tiers {
  position: fixed; left: 0; right: 0; z-index: 5;
  top: calc(max(0.5rem, env(safe-area-inset-top)) + 3.1rem);
  display: flex; justify-content: center; gap: 0.3rem; padding: 0 0.6rem;
  /* Every tier has to be visible, locked or not - it is the map of
     what the Tour is. Five pills in a centred row with no wrapping
     ran off both edges of a narrow phone and took the first and last
     tier with them. */
  flex-wrap: wrap;
  row-gap: 0.25rem;
}
#tour-tiers .tier-pill {
  font-family: Orbitron, ui-monospace, monospace; font-size: 0.52rem; letter-spacing: 0.1em; text-transform: uppercase;
  padding: 0.4rem 0.5rem; border-radius: 999px; white-space: nowrap; flex: none;
  border: 1px solid var(--edge-dim); background: var(--glass); color: var(--ui-dim);
  box-shadow: inset 0 1px 0 var(--edge);
}
#tour-tiers .tier-pill.on { color: var(--ui-text); border-color: color-mix(in srgb, var(--ui-accent) 60%, transparent); }
#tour-tiers .tier-pill.locked { opacity: 0.45; }
#tour-tiers .tier-pill .pip { margin-left: 0.35em; font-size: 0.85em; opacity: 0.7; letter-spacing: 0; }
#tour-tiers .tier-pill .pip.done { color: var(--gold); opacity: 1; }
/* the stop labels, placed by the camera */
#tour-labels { position: fixed; inset: 0; pointer-events: none; z-index: 4; }
#tour-labels .stop-label {
  position: absolute; transform: translate(-50%, 0);
  font-family: "Baloo 2", ui-rounded, system-ui, sans-serif; font-weight: 800; font-size: 0.82rem;
  color: var(--ui-text); text-shadow: 0 1px 6px rgba(0, 0, 0, 0.9), 0 0 14px rgba(0, 0, 0, 0.7);
  white-space: nowrap; transition: opacity 0.2s;
}
#tour-labels .stop-label .mark { display: block; text-align: center; font-family: Orbitron, ui-monospace, monospace; font-size: 0.5rem; letter-spacing: 0.14em; color: var(--gold, #FFD166); }
#tour-labels .stop-label .mark.hard { color: #E6EAF2; }
/* the card: the same glass sheet the breaker uses, at the bottom */
#tour-card {
  position: fixed; left: 0.9rem; right: 0.9rem; z-index: 6; width: auto;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 0.9rem);
  display: flex; flex-direction: column; gap: 0.6rem; padding: 0.7rem;
  border-radius: 1.1rem; border: 1px solid var(--edge-dim);
  background: var(--glass, rgba(10, 13, 20, 0.66));
  box-shadow: inset 0 1px 0 var(--edge), 0 10px 30px rgba(0, 0, 0, 0.45);
}
#tour-card .art, #node-card .art { flex: none; width: 6.4rem; border-radius: 0.7rem; background-size: cover; background-position: center 45%; background-color: rgba(255, 255, 255, 0.04); }
#tour-card .body, #node-card .body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.2rem; }
#tour-card .eyebrow, #node-card .eyebrow { margin: 0; font-family: Orbitron, ui-monospace, monospace; font-size: 0.55rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ui-dim); }
#tour-card .title, #node-card .title { margin: 0; font-size: 1.3rem; line-height: 1.05; }
#tour-card .line, #node-card .line { margin: 0; font-size: 0.8rem; color: var(--ui-dim); }
#tour-card .head, #node-card .head { display: flex; gap: 0.7rem; }
#tour-card .art, #node-card .art { height: 4.6rem; }
#tour-card .marks, #node-card .marks { display: flex; flex-wrap: wrap; align-items: center; gap: 0.3rem; margin-top: 0.25rem; }
#tour-card .marks .stars, #node-card .marks .stars { font-size: 0.95rem; margin-right: 0.2rem; }
/* the hard ladder's stars are gold */
.stars.hard span.on { color: #FFF0B5; text-shadow: 0 0 3px #F2C14E, 0 0 8px rgba(242, 193, 78, 0.85), 0 0 18px rgba(242, 193, 78, 0.5); }
.stars .hm { color: var(--gold); opacity: 1; font-size: 0.7em; margin-right: 0.15em; align-self: center; }
.rec .quick .stars { justify-content: center; font-size: 0.7rem; margin-top: 0.2rem; }
.rec .tier .stop b { color: var(--gold); font-weight: 600; font-size: 0.5rem; margin-left: 0.1em; }
#tour-card .mark, #node-card .mark {
  font-family: Orbitron, ui-monospace, monospace; font-size: 0.5rem; letter-spacing: 0.14em; text-transform: uppercase;
  padding: 0.22rem 0.45rem; border-radius: 0.4rem;
  background: rgba(255, 255, 255, 0.05); border: 1px solid var(--edge-dim); color: var(--ui-dim);
}
#tour-card .mark.on, #node-card .mark.on { color: var(--ui-accent); border-color: color-mix(in srgb, var(--ui-accent) 50%, transparent); }
#tour-card .mark.gold, #node-card .mark.gold { color: var(--gold); border-color: rgba(242, 193, 78, 0.5); }
#tour-card .facts, #node-card .facts {
  display: grid; grid-template-columns: auto 1fr; gap: 0.2rem 0.8rem; margin: 0;
  font-size: 0.74rem; font-variant-numeric: tabular-nums;
  padding-top: 0.5rem; border-top: 1px solid rgba(255, 255, 255, 0.07);
}
#tour-card .facts dt, #node-card .facts dt { color: var(--ui-dim); }
#tour-card .facts dd, #node-card .facts dd { margin: 0; text-align: right; font-weight: 600; color: var(--ui-text); }
#tour-card .choices, #node-card .choices { display: flex; gap: 0.5rem; }
#tour-card .choices .primary, #node-card .choices .primary { flex: 1; }

/* the rank on the result card */
.rankline { width: 100%; display: flex; align-items: center; gap: 0.6rem; margin-top: 0.7rem; }
.rankline .lvl { font-family: Orbitron, ui-monospace, monospace; font-size: 0.72rem; letter-spacing: 0.12em; color: var(--ui-dim); flex: none; }
.rankline .bar { flex: 1; height: 8px; border-radius: 4px; background: rgba(255, 255, 255, 0.09); overflow: hidden; }
.rankline .bar i { display: block; height: 100%; width: 0; background: linear-gradient(90deg, var(--ui-accent), #fff); }
.rankline .xp { font-family: Orbitron, ui-monospace, monospace; font-size: 0.6rem; letter-spacing: 0.08em; color: var(--ui-dim); flex: none; font-variant-numeric: tabular-nums; }
.rankline.up .lvl { color: var(--gold); text-shadow: 0 0 12px rgba(242, 193, 78, 0.8); }
.rankline.up .bar i { background: linear-gradient(90deg, var(--gold), #fff); box-shadow: 0 0 14px rgba(242, 193, 78, 0.8); }
.unlocked { margin: 0.2rem 0 0; font-size: 0.78rem; color: var(--ui-text); }
.unlocked b { color: var(--gold); font-weight: 700; }
/* the moment's burst alone, over a screen that stays usable */
#moment.moment.spark { background: transparent; pointer-events: none; }
#moment.moment.spark #moment-card { display: none; }

/* the level-up moment on the result screen */
.level-up {
  margin: 0.2rem 0 0; padding: 0.4rem 0.9rem; border-radius: 999px;
  font-family: Orbitron, ui-monospace, monospace;
  font-size: 0.68rem; letter-spacing: 0.2em; text-transform: uppercase;
  color: #1A1204; background: linear-gradient(90deg, #FFF0B5, var(--gold));
  box-shadow: 0 0 22px rgba(242, 193, 78, 0.6);
  animation: level-pop 0.6s cubic-bezier(0.2, 1.4, 0.4, 1) both;
}
@keyframes level-pop { from { transform: scale(0.6); opacity: 0; } to { transform: scale(1); opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .level-up { animation: none; } }

/* nothing square may ever show round a puck: no focus ring, round box */
.puck, .puck:focus, .puck:focus-visible, .puck:active { outline: none; border: none; box-shadow: none; border-radius: 50%; background: transparent; }
.hard-chip {
  display: inline-block; margin: 0.5rem 0 0;
  font-family: Orbitron, ui-monospace, monospace;
  font-size: 0.58rem; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ember);
  padding: 0.28rem 0.6rem; border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--ember) 50%, transparent);
  background: color-mix(in srgb, var(--ember) 12%, transparent);
}
#hud-hard { --ember: #E6EAF2; margin-top: 0.3rem; }

/* the tiles sit at the bottom; the room gets the middle */
.tiles {
  width: 100%;
  margin-top: auto;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.6rem;
}
.tile {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column; justify-content: flex-end; align-items: flex-start; gap: 0.1rem;
  min-height: 6rem;
  padding: 0.85rem 0.9rem;
  border-radius: 1.1rem;
  border: 1px solid var(--edge-dim);
  background: var(--glass);
  box-shadow: inset 0 1px 0 var(--edge), 0 10px 30px rgba(0, 0, 0, 0.35);
  text-align: left;
  transition: transform 0.15s, border-color 0.15s;
}
.tile:hover { border-color: var(--edge-dim); }
/* the loadout: three equals, each with its effect strip fused below */
.loadout { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.5rem; }
.pick { display: flex; flex-direction: column; min-width: 0; }
.pick .tile { min-height: 5.6rem; padding: 0.7rem 0.7rem 0.55rem; border-radius: 1rem 1rem 0 0; border-bottom: 0; }
.pick .tile .eyebrow { font-size: 0.48rem; }
.pick .tile .tile-title { font-size: 1rem; width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pick .tile .thumb { width: 5rem; height: 3.2rem; right: -0.5rem; top: -0.35rem; }
.pick .tile .thumb.glyph { display: grid; place-items: center; -webkit-mask: none; mask: none; background: transparent; opacity: 0.7; }
.pick .tile .thumb.glyph svg { width: 2.6rem; height: 2.6rem; fill: none; stroke: var(--ui-accent); stroke-width: 2.2; stroke-linecap: round; filter: drop-shadow(0 0 8px color-mix(in srgb, var(--ui-accent) 60%, transparent)); }
.fx-strip {
  display: flex; align-items: center; gap: 0.35rem; min-width: 0;
  padding: 0.42rem 0.65rem; border-radius: 0 0 1rem 1rem;
  border: 1px solid var(--edge-dim); border-top: 1px solid rgba(255, 255, 255, 0.06);
  background: color-mix(in srgb, var(--glass) 80%, #000); color: var(--ui-dim);
  font-family: "Baloo 2", ui-rounded, system-ui, sans-serif; font-weight: 700; font-size: 0.72rem; text-align: left;
}
.fx-strip span:last-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fx-strip .spark { color: var(--ui-accent); font-size: 0.8rem; flex: none; }
.fx-strip.on { color: var(--ui-text); }
/* the empty slot: quieter than a worn one, and plainly a place
   something goes */
.fx-strip.empty { color: var(--ui-dim); opacity: 0.85; }
.fx-strip.empty .spark { opacity: 0.55; }
.tile:active { transform: scale(0.985); }
.tile.big {
  grid-column: 1 / -1;
  min-height: 7.2rem;
  background: linear-gradient(180deg, color-mix(in srgb, var(--ui-accent) 18%, transparent), var(--glass));
  border-color: color-mix(in srgb, var(--ui-accent) 40%, transparent);
}
.tile .eyebrow {
  font-family: Orbitron, ui-monospace, monospace;
  font-size: 0.58rem; letter-spacing: 0.2em; text-transform: uppercase; color: var(--ui-dim);
}
.tile .tile-title {
  font-family: "Baloo 2", ui-rounded, system-ui, sans-serif;
  font-weight: 800; font-size: 1.25rem; line-height: 1.05; color: var(--ui-text);
}
.tile.big .tile-title { font-size: 2rem; color: #fff; text-shadow: 0 0 18px color-mix(in srgb, var(--ui-accent) 60%, transparent); }
.tile .tile-note { font-size: 0.72rem; color: var(--ui-dim); font-weight: 500; }
.tile .thumb {
  position: absolute; right: -0.4rem; top: -0.4rem;
  width: 6rem; height: 4rem; border-radius: 0.8rem;
  background-size: cover; background-position: center;
  background-color: rgba(255, 255, 255, 0.04);
  opacity: 0.92;
  -webkit-mask: linear-gradient(200deg, #000 40%, transparent 95%);
  mask: linear-gradient(200deg, #000 40%, transparent 95%);
}
/* the picker and the store share the tile look */
.picker-item, .card { background: var(--glass, rgba(10, 13, 20, 0.66)); }
.picker-item {
  display: flex; flex-direction: column; align-items: stretch; gap: 0.4rem; padding: 0.5rem;
  border-radius: 0.9rem;
}
.picker-item .pthumb {
  display: block; width: 100%; aspect-ratio: 16 / 10; border-radius: 0.6rem;
  background-size: cover; background-position: center; background-color: rgba(255, 255, 255, 0.05);
}
.picker-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
/* while thumbnails are being drawn the canvas is swapping courts;
   cover it rather than show the flicker */
body.thumbing #court { opacity: 0; transition: opacity 0.15s; }
#court { transition: opacity 0.25s; }

/* ---- the store ----

   A showroom, not a catalogue (Kevin, 2026-09-18, from the Call of
   Duty store): the room behind the sheet IS the picture - pick a
   court and the room becomes it, pick a ball and the ball swaps -
   with a rail of shelves down the left, one thing in focus at a
   time on the counter, one price bar, and a strip of the rest. */
#store.shop {
  --store-veil: linear-gradient(180deg,
    rgba(7, 9, 14, 0.70) 0%, rgba(7, 9, 14, 0.08) 22%,
    rgba(7, 9, 14, 0.06) 50%, rgba(7, 9, 14, 0.90) 78%, rgba(7, 9, 14, 0.96) 100%);
  justify-content: flex-start;
  gap: 0;
  padding: calc(env(safe-area-inset-top, 0px) + 0.9rem) 1rem
           calc(env(safe-area-inset-bottom, 0px) + 0.9rem);
  background: var(--store-veil);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  text-align: left;
}
#store .topbar { gap: 0.5rem; }
#store .topbar .crumb { flex: 1; min-width: 0; margin: 0; font-size: 1.25rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#store .topbar .rank .bar { width: 3rem; }
.crumb {
  width: 100%; margin: 1.1rem 0 0;
  font-family: "Baloo 2", ui-rounded, system-ui, sans-serif;
  font-weight: 800; font-size: 1.6rem; letter-spacing: -0.01em;
}
.crumb span:first-child { color: var(--ui-accent); }

.showroom {
  width: 100%; flex: 1; min-height: 0;
  display: flex; align-items: flex-start; gap: 0.6rem;
  padding-top: 0.6rem;
}
/* the stage is the canvas behind the sheet; while thumbnails are
   being drawn it holds a still of the last frame, full screen */
.showroom .stage { flex: 1; min-width: 0; min-height: 0; align-self: stretch; position: relative; }
#store.shop { z-index: 30; }
#store.shop > * { position: relative; z-index: 1; }
/* THE STILL HAS TO BEAT THE RULE ABOVE, and for a long time it did
   not: `#store .still` and `#store.shop > *` have exactly the same
   specificity, so the later one won, the still was laid out
   `relative` instead of `fixed`, `inset` stopped meaning anything,
   and an empty div collapsed to nothing at all. The freeze and thaw
   worked perfectly the whole time - they were painting the last
   frame onto an element zero pixels across, so the showroom simply
   showed the canvas swapping rooms, which is black. Selecting the
   direct child wins on specificity and keeps the two rules in
   reading order. */
#store.shop > .still {
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background-size: cover; background-position: center;
}
/* the rail: shelves, top to bottom */
.rail-v { display: flex; flex-direction: column; gap: 0.35rem; flex: none; }
.rail-v .tab-btn {
  width: 3.1rem; height: 3.1rem; padding: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.15rem;
  border-radius: 0.85rem;
  border: 1px solid var(--edge-dim); background: var(--glass); color: var(--ui-dim);
  box-shadow: inset 0 1px 0 var(--edge), 0 6px 18px rgba(0, 0, 0, 0.35);
  font-family: Orbitron, ui-monospace, monospace;
  font-weight: 600; font-size: 0.42rem; letter-spacing: 0.08em; text-transform: uppercase;
}
.rail-v .tab-btn svg { width: 1.3rem; height: 1.3rem; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.rail-v .tab-btn[aria-selected="true"] {
  color: var(--ui-accent); border-color: var(--ui-accent);
  box-shadow: inset 0 1px 0 var(--edge), 0 0 16px color-mix(in srgb, var(--ui-accent) 45%, transparent);
}

/* featured: big cards on the stage, a column you scroll */
.showroom .stage .featured {
  position: absolute; inset: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none;
  display: flex; flex-direction: column; gap: 0.6rem; padding: 0.15rem 0.15rem 1rem;
  -webkit-mask: linear-gradient(180deg, #000 88%, transparent 100%);
  mask: linear-gradient(180deg, #000 88%, transparent 100%);
}
.showroom .stage .featured::-webkit-scrollbar { display: none; }
.feat-card {
  flex: none; display: flex; flex-direction: column; overflow: hidden; text-align: left; padding: 0;
  border-radius: 1rem; border: 1px solid var(--edge-dim);
  background: var(--glass); color: var(--ui-text);
  box-shadow: inset 0 1px 0 var(--edge), 0 10px 30px rgba(0, 0, 0, 0.35);
}
.feat-card .fthumb {
  /* wider than the picture, so its dark foot is cropped away */
  position: relative; width: 100%; aspect-ratio: 2 / 1;
  background-size: cover; background-position: center 30%; background-color: rgba(255, 255, 255, 0.05);
}
.feat-card .ftag {
  position: absolute; left: 0.55rem; top: 0.55rem;
  font-family: Orbitron, ui-monospace, monospace; font-size: 0.5rem; letter-spacing: 0.16em; text-transform: uppercase;
  padding: 0.25rem 0.45rem; border-radius: 0.4rem;
  background: rgba(7, 9, 14, 0.72); border: 1px solid var(--edge-dim); color: var(--ui-dim);
}
.feat-card .ftag.new { color: #FF3C9E; border-color: rgba(255, 60, 158, 0.5); }
.feat-card .ffoot { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; padding: 0.55rem 0.7rem 0.6rem; }
.feat-card .fname {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-family: "Baloo 2", ui-rounded, system-ui, sans-serif; font-weight: 800; font-size: 1.05rem;
}
.feat-card .fprice {
  flex: none; font-family: Orbitron, ui-monospace, monospace; font-weight: 600; font-size: 0.6rem; letter-spacing: 0.1em; text-transform: uppercase;
  padding: 0.3rem 0.55rem; border-radius: 999px;
  background: rgba(242, 193, 78, 0.14); border: 1px solid rgba(242, 193, 78, 0.5); color: var(--gold);
}
.feat-card .fprice.owned { background: rgba(255, 255, 255, 0.05); border-color: var(--edge-dim); color: var(--ui-dim); }
.feat-card .fprice.on { background: color-mix(in srgb, var(--ui-accent) 14%, transparent); border-color: var(--ui-accent); color: var(--ui-accent); }
.feat-card.current { border-color: var(--ui-accent); box-shadow: inset 0 1px 0 var(--edge), 0 0 18px color-mix(in srgb, var(--ui-accent) 45%, transparent); }

/* the counter */
.counter { width: 100%; display: flex; flex-direction: column; gap: 0.6rem; flex: none; }
.focus { display: flex; flex-direction: column; gap: 0.2rem; min-height: 3.6rem; }
.focus-head { display: flex; align-items: center; gap: 0.6rem; }
.focus h3 {
  margin: 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-family: "Baloo 2", ui-rounded, system-ui, sans-serif;
  font-weight: 800; font-size: 1.5rem; line-height: 1.05; letter-spacing: -0.01em; color: var(--ui-text);
}
.focus .flag {
  flex: none;
  font-family: Orbitron, ui-monospace, monospace; font-size: 0.5rem; letter-spacing: 0.16em; text-transform: uppercase;
  padding: 0.25rem 0.45rem; border-radius: 0.4rem;
  background: rgba(7, 9, 14, 0.72); border: 1px solid var(--edge-dim); color: var(--ui-accent);
}
.focus .flag.new { color: #FF3C9E; border-color: rgba(255, 60, 158, 0.5); }
.focus .flag.earned { color: var(--gold); border-color: rgba(242, 193, 78, 0.5); }
.focus p {
  margin: 0; font-size: 0.78rem; line-height: 1.35; color: var(--ui-dim);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
/* one price bar, the brightest thing on the sheet */
.pricebar {
  width: 100%;
  font-family: Orbitron, ui-monospace, monospace;
  font-weight: 700; font-size: 0.82rem; letter-spacing: 0.12em; text-transform: uppercase;
  padding: 0.85rem 0; border-radius: 0.8rem; text-align: center;
  background: linear-gradient(180deg, #FFDC7A, #F2C14E 60%, #D9A63A); color: #1A1204;
  border: 1px solid rgba(255, 235, 170, 0.7);
  box-shadow: 0 8px 26px rgba(242, 193, 78, 0.28), inset 0 1px 0 rgba(255, 255, 255, 0.55);
}
.pricebar:disabled { cursor: default; opacity: 1; }
.pricebar.owned  { background: rgba(255, 255, 255, 0.06); color: var(--ui-text); border-color: var(--edge-dim); box-shadow: inset 0 1px 0 var(--edge); }
.pricebar.equipped { background: color-mix(in srgb, var(--ui-accent) 16%, transparent); color: var(--ui-accent); border-color: var(--ui-accent); box-shadow: 0 0 18px color-mix(in srgb, var(--ui-accent) 35%, transparent); }
.pricebar.locked { background: rgba(255, 255, 255, 0.04); color: var(--ui-dim); border-color: var(--edge-dim); box-shadow: none; }
.pricebar.poor { opacity: 0.55; }
/* bought: a sweep of light along the bar, and it settles */
.pricebar.bought {
  position: relative; overflow: hidden;
  background: linear-gradient(180deg, #FFF3C4, #FFDC7A 60%, #F2C14E); color: #1A1204;
  animation: bar-pop 0.5s cubic-bezier(0.2, 1.4, 0.4, 1);
}
.pricebar.bought::after {
  content: ""; position: absolute; top: -40%; bottom: -40%; width: 40%; left: -50%;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.85), transparent);
  animation: bar-sweep 0.7s ease-out forwards;
}
@keyframes bar-pop { 0% { transform: scale(0.98); } 50% { transform: scale(1.03); } 100% { transform: scale(1); } }
@keyframes bar-sweep { to { left: 120%; } }
/* the purse when it pays: a dip and a flash of the coin */
.pill.spent { animation: purse-spend 0.6s ease-out; }
.pill.spent .coin { animation: coin-flash 0.6s ease-out; }
@keyframes purse-spend { 0% { transform: translateY(0); } 30% { transform: translateY(3px); } 100% { transform: translateY(0); } }
@keyframes coin-flash { 0% { box-shadow: 0 0 8px rgba(242, 193, 78, 0.6); } 40% { box-shadow: 0 0 18px rgba(255, 240, 181, 1); } 100% { box-shadow: 0 0 8px rgba(242, 193, 78, 0.6); } }
@media (prefers-reduced-motion: reduce) { .pricebar.bought, .pricebar.bought::after, .pill.spent, .pill.spent .coin, .shelf-item .thumb .dot.pop { animation: none; } }
/* the chips: a filter for the shelf, and the grid button at the end */
.chips { width: 100%; display: flex; align-items: center; gap: 0.35rem; }
.chips[hidden] { display: none; }
.chip {
  font-family: Orbitron, ui-monospace, monospace;
  font-weight: 600; font-size: 0.52rem; letter-spacing: 0.1em; text-transform: uppercase;
  padding: 0.4rem 0.6rem; border-radius: 999px;
  border: 1px solid var(--edge-dim); background: var(--glass-2); color: var(--ui-dim);
}
.chip[aria-selected="true"] { color: var(--bg); background: var(--ui-accent); border-color: var(--ui-accent); }
.chip.slot { border-color: color-mix(in srgb, var(--ui-accent) 35%, transparent); }
.chip-break { flex-basis: 100%; height: 0; }
.chips { flex-wrap: wrap; row-gap: 0.35rem; }
.shelf-empty { font-size: 0.78rem; color: var(--ui-dim); padding: 0.6rem 0.2rem; }
.chips .grid-btn {
  margin-left: auto; width: 2rem; height: 2rem; border-radius: 0.55rem; display: grid; place-items: center;
  border: 1px solid var(--edge-dim); background: var(--glass-2); color: var(--ui-dim);
}
.chips .grid-btn svg { width: 1.1rem; height: 1.1rem; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linejoin: round; }
.chips .grid-btn[aria-pressed="true"] { color: var(--ui-accent); border-color: var(--ui-accent); }
/* the grid: the whole section over the stage, for a thumb to browse */
.showroom .stage .grid {
  position: absolute; inset: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none;
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.45rem; align-content: start;
  padding: 0.15rem 0.15rem 1rem;
  -webkit-mask: linear-gradient(180deg, #000 90%, transparent 100%);
  mask: linear-gradient(180deg, #000 90%, transparent 100%);
}
.showroom .stage .grid::-webkit-scrollbar { display: none; }
.showroom .stage .grid .shelf-item { width: auto; }

/* the shelf: the rest of the section, in a strip */
.shelf {
  width: 100%; display: flex; gap: 0.45rem;
  overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity; scrollbar-width: none;
  padding: 0.15rem 0.15rem 0.3rem; margin: 0 -0.15rem;
}
.shelf::-webkit-scrollbar { display: none; }
.shelf-item {
  flex: none; width: 5.2rem; scroll-snap-align: start;
  display: flex; flex-direction: column; gap: 0.25rem; padding: 0.3rem;
  border-radius: 0.75rem; border: 1px solid var(--edge-dim);
  background: var(--glass); color: var(--ui-dim);
  box-shadow: inset 0 1px 0 var(--edge), 0 6px 18px rgba(0, 0, 0, 0.3);
  text-align: left;
}
.shelf-item .thumb {
  position: relative; width: 100%; aspect-ratio: 16 / 10; border-radius: 0.5rem;
  background-size: cover; background-position: center 45%; background-color: rgba(255, 255, 255, 0.05);
  display: grid; place-items: center;
}
.shelf-item .thumb .glyph {
  width: 1.8rem; height: 1.8rem;
  fill: none; stroke: var(--ui-accent); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
  filter: drop-shadow(0 0 8px color-mix(in srgb, var(--ui-accent) 70%, transparent));
}
.shelf-item .thumb .dot {
  position: absolute; right: 0.25rem; top: 0.25rem; width: 0.5rem; height: 0.5rem; border-radius: 50%;
  background: var(--ui-accent); box-shadow: 0 0 6px var(--ui-accent);
}
.shelf-item .thumb .dot.owned { background: var(--gold); box-shadow: 0 0 6px rgba(242, 193, 78, 0.7); }
.shelf-item .thumb .dot.pop { animation: dot-pop 0.6s cubic-bezier(0.2, 1.4, 0.4, 1); }
@keyframes dot-pop { 0% { transform: scale(0.4); } 60% { transform: scale(1.9); } 100% { transform: scale(1); } }
.shelf-item .thumb .dot.lock { background: transparent; border: 1px solid rgba(255, 255, 255, 0.4); box-shadow: none; }
.shelf-item .name {
  font-family: "Baloo 2", ui-rounded, system-ui, sans-serif; font-weight: 800; font-size: 0.66rem; line-height: 1.1;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--ui-text);
}
.shelf-item .held { font-family: Orbitron, ui-monospace, monospace; font-size: 0.48rem; letter-spacing: 0.1em; color: var(--ui-accent); }
.shelf-item.current { border-color: var(--ui-accent); box-shadow: inset 0 1px 0 var(--edge), 0 0 14px color-mix(in srgb, var(--ui-accent) 45%, transparent); }
.shelf-item.current .name { color: var(--ui-accent); }

/* the old grid cards are still used by the picker's kin */
.tabs {
  width: 100%; display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
  gap: 0.35rem; margin: 0.7rem 0 0.8rem;
}
.tab-btn {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-family: Orbitron, ui-monospace, monospace;
  font-weight: 600; font-size: 0.58rem; letter-spacing: 0.1em; text-transform: uppercase;
  padding: 0.55rem 0.3rem; border-radius: 999px;
  border: 1px solid var(--edge-dim); background: var(--glass-2); color: var(--ui-dim);
}
.card {
  display: flex; flex-direction: column; overflow: hidden;
  border-radius: 1.1rem;
  border: 1px solid var(--edge-dim);
  box-shadow: inset 0 1px 0 var(--edge), 0 10px 30px rgba(0, 0, 0, 0.35);
  text-align: left;
}
.card .art {
  position: relative; height: 6.6rem; flex: none;
  background-size: cover; background-position: center 45%;
  background-color: rgba(255, 255, 255, 0.04);
}
.card .art .flag {
  position: absolute; left: 0.5rem; top: 0.5rem;
  font-family: Orbitron, ui-monospace, monospace; font-size: 0.52rem; letter-spacing: 0.16em; text-transform: uppercase;
  padding: 0.25rem 0.45rem; border-radius: 0.4rem;
  background: rgba(7, 9, 14, 0.72); border: 1px solid var(--edge-dim); color: var(--ui-accent);
}
.card .art .flag.new { color: #FF3C9E; border-color: rgba(255, 60, 158, 0.5); }
.card .body { padding: 0.65rem 0.7rem 0.7rem; display: flex; flex-direction: column; gap: 0.35rem; flex: 1; }
.card h4 {
  margin: 0;
  font-family: "Baloo 2", ui-rounded, system-ui, sans-serif;
  font-weight: 800; font-size: 1rem; line-height: 1.05; color: var(--ui-text);
}
.card p {
  margin: 0; font-size: 0.68rem; line-height: 1.35; color: var(--ui-dim); min-height: 1.85em;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.card .held { font-family: Orbitron, ui-monospace, monospace; font-size: 0.56rem; letter-spacing: 0.12em; color: var(--ui-accent); }
.card .buy {
  /* pushed to the foot, so the buttons in a row line up whatever the
     note above them ran to */
  margin-top: auto;
  font-family: Orbitron, ui-monospace, monospace;
  font-weight: 600; font-size: 0.68rem; letter-spacing: 0.08em;
  padding: 0.55rem 0; border-radius: 0.65rem; text-align: center;
  background: rgba(242, 193, 78, 0.14); border: 1px solid rgba(242, 193, 78, 0.5); color: var(--gold);
}
.card .buy:disabled { opacity: 1; cursor: default; }
.card .buy.owned { background: rgba(255, 255, 255, 0.05); border-color: var(--edge-dim); color: var(--ui-dim); }
.card .buy.equipped { background: color-mix(in srgb, var(--ui-accent) 14%, transparent); border-color: var(--ui-accent); color: var(--ui-accent); }
.card .buy.locked { background: rgba(255, 255, 255, 0.03); border-color: var(--edge-dim); color: var(--ui-dim); }
.card .buy.poor { opacity: 0.55; }
.card.boost .art { height: 4.2rem; display: grid; place-items: center; }
.card.boost .art .glyph {
  width: 2.6rem; height: 2.6rem;
  fill: none; stroke: var(--ui-accent); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
  filter: drop-shadow(0 0 10px color-mix(in srgb, var(--ui-accent) 70%, transparent));
}

/* ---- the other sheets: settings, picker, waiting, result ---- */
.sheet {
  justify-content: flex-start;
  background: linear-gradient(180deg, rgba(7, 9, 14, 0.78), rgba(7, 9, 14, 0.92));
  backdrop-filter: blur(10px) brightness(0.7);
  -webkit-backdrop-filter: blur(10px) brightness(0.7);
}
.sheet .topbar { margin-bottom: 0.9rem; }
.sheet .topbar .crumb { margin: 0; }
.sheet .settings-list, .sheet .picker-list { max-height: none; flex: 1; min-height: 0; overflow-y: auto; max-width: none; }
.sheet .setting {
  border: 1px solid var(--edge-dim);
  border-top: 1px solid var(--edge-dim);
  border-radius: 1rem;
  background: var(--glass);
  box-shadow: inset 0 1px 0 var(--edge), 0 8px 24px rgba(0, 0, 0, 0.3);
  padding: 0.9rem 0.95rem;
  margin-bottom: 0.55rem;
}
.sheet .setting-label { font-family: "Baloo 2", ui-rounded, system-ui, sans-serif; font-weight: 800; font-size: 1.05rem; }
.sheet .choice-value {
  font-family: Orbitron, ui-monospace, monospace; font-size: 0.66rem; letter-spacing: 0.1em; text-transform: uppercase;
  border-radius: 999px; border: 1px solid color-mix(in srgb, var(--ui-accent) 45%, transparent);
  background: color-mix(in srgb, var(--ui-accent) 12%, transparent);
}
.sheet .switch { border-color: var(--edge-dim); background: rgba(255, 255, 255, 0.05); }
.sheet .switch[aria-checked="true"] { background: var(--ui-accent); border-color: var(--ui-accent); box-shadow: 0 0 14px color-mix(in srgb, var(--ui-accent) 55%, transparent); }
.sheet .picker-list { grid-auto-rows: max-content; }
.sheet .picker-item {
  border: 1px solid var(--edge-dim); border-radius: 1rem;
  box-shadow: inset 0 1px 0 var(--edge), 0 8px 24px rgba(0, 0, 0, 0.3);
  font-family: "Baloo 2", ui-rounded, system-ui, sans-serif; font-weight: 800; font-size: 0.95rem;
}
.sheet .picker-item.current { border-color: var(--ui-accent); box-shadow: inset 0 1px 0 var(--edge), 0 0 16px color-mix(in srgb, var(--ui-accent) 45%, transparent); }

.glass-card {
  width: 100%;
  display: flex; flex-direction: column; gap: 0.5rem;
  padding: 1.2rem 1rem;
  border-radius: 1.2rem;
  border: 1px solid var(--edge-dim);
  background: var(--glass);
  box-shadow: inset 0 1px 0 var(--edge), 0 10px 30px rgba(0, 0, 0, 0.35);
}
.glass-card.centred { align-items: center; text-align: center; }
.glass-card.grow { flex: 1; justify-content: center; }
.glass-card .eyebrow {
  margin: 0;
  font-family: Orbitron, ui-monospace, monospace; font-size: 0.6rem; letter-spacing: 0.2em; text-transform: uppercase; color: var(--ui-dim);
}
.glass-card .code { font-family: Orbitron, ui-monospace, monospace; font-weight: 800; text-shadow: 0 0 22px color-mix(in srgb, var(--ui-accent) 60%, transparent); }
.glass-card .title { font-family: "Baloo 2", ui-rounded, system-ui, sans-serif; font-weight: 800; }
.glass-card .subtitle { max-width: none; }
.glass-card .tally { width: 100%; grid-template-columns: 1fr auto; }
.glass-card .tally dt.lead, .glass-card .tally dd.lead { border-top-color: var(--edge-dim); }

/* the credit, wherever a price is written: the purse's yellow ball */
.credit {
  display: inline-block; width: 0.85em; height: 0.85em; border-radius: 50%; vertical-align: -0.08em; margin-right: 0.35em;
  background: radial-gradient(circle at 35% 35%, #FFF0B5, #F2C14E 55%, #9A6E12);
  box-shadow: 0 0 6px rgba(242, 193, 78, 0.6);
}
.pricebar .buyword { margin-left: 0.9em; }

/* the powerups running, as chips under the score */
.powers { display: flex; gap: 0.3rem; justify-content: center; flex-wrap: wrap; margin-top: 0.2rem; pointer-events: none; }
.powers .pw {
  font-family: Orbitron, ui-monospace, monospace; font-size: 0.5rem; letter-spacing: 0.14em; text-transform: uppercase;
  padding: 0.22rem 0.45rem; border-radius: 0.4rem; border: 1px solid currentColor; background: rgba(7, 9, 14, 0.6);
  animation: level-pop 0.35s cubic-bezier(0.2, 1.4, 0.4, 1) both;
}
.powers .pw.wide { color: #57E8FF; } .powers .pw.slow { color: #7CA8FF; } .powers .pw.shield { color: #6CF58A; }
.powers .pw.laser { color: #FF7A50; } .powers .pw.pierce { color: #FFB021; } .powers .pw.magnet { color: #E070FF; }

/* ---- the record ---- */
.record-list { width: 100%; flex: 1; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; display: flex; flex-direction: column; gap: 0.55rem; padding-bottom: 1rem; }
.rec {
  border: 1px solid var(--edge-dim); border-radius: 1rem; background: var(--glass);
  box-shadow: inset 0 1px 0 var(--edge), 0 8px 24px rgba(0, 0, 0, 0.3);
  padding: 0.8rem 0.9rem; text-align: left; color: var(--ui-text);
}
.rec-head { display: flex; align-items: baseline; justify-content: space-between; gap: 0.6rem; margin-bottom: 0.5rem; }
.rec-head h3 { margin: 0; font-family: "Baloo 2", ui-rounded, system-ui, sans-serif; font-weight: 800; font-size: 1.1rem; }
.rec-head .sum { font-family: Orbitron, ui-monospace, monospace; font-size: 0.6rem; letter-spacing: 0.1em; color: var(--ui-dim); font-variant-numeric: tabular-nums; white-space: nowrap; }
.rec-head .sum b { color: var(--gold); font-weight: 600; }
.rec .rankline { margin-top: 0.2rem; }
.rec .totals { display: flex; gap: 1.2rem; margin-top: 0.6rem; }
.rec .totals div { display: flex; flex-direction: column; gap: 0.1rem; }
.rec .totals b { font-family: "Baloo 2", ui-rounded, system-ui, sans-serif; font-weight: 800; font-size: 1.3rem; line-height: 1; }
.rec .totals span { font-family: Orbitron, ui-monospace, monospace; font-size: 0.52rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ui-dim); }
/* the breaker: a hundred levels as a grid of stars */
.rec .sector { font-family: Orbitron, ui-monospace, monospace; font-size: 0.5rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ui-dim); margin: 0.5rem 0 0.25rem; }
.rec .stargrid { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 0.25rem; }
.rec .cell {
  display: flex; align-items: center; justify-content: space-between; gap: 0.15rem;
  padding: 0.25rem 0.35rem; border-radius: 0.45rem; background: rgba(255, 255, 255, 0.04); border: 1px solid transparent;
  font-family: Orbitron, ui-monospace, monospace; font-size: 0.5rem; color: var(--ui-dim);
}
.rec .cell .n { min-width: 1.4em; }
.rec .cell .stars { gap: 0.05em; font-size: 0.6rem; }
.rec .cell.locked { opacity: 0.35; }
.rec .cell.hard { border-color: rgba(242, 193, 78, 0.55); }
.rec .cell .hm { color: var(--gold); font-size: 0.55rem; text-shadow: 0 0 6px rgba(242, 193, 78, 0.8); }
/* the tour: a row per tier */
.rec .tier { display: grid; grid-template-columns: 5.2rem 1fr auto; align-items: center; gap: 0.5rem; padding: 0.35rem 0; border-top: 1px solid rgba(255, 255, 255, 0.06); }
.rec .tier:first-of-type { border-top: 0; }
.rec .tier .tname { font-family: "Baloo 2", ui-rounded, system-ui, sans-serif; font-weight: 800; font-size: 0.9rem; }
.rec .tier .stops { display: flex; gap: 0.35rem; }
.rec .tier .stop {
  width: 1.5rem; height: 1.5rem; border-radius: 50%; display: grid; place-items: center;
  border: 1px solid var(--edge-dim); color: var(--ui-dim); font-size: 0.7rem; background: rgba(255, 255, 255, 0.04);
}
.rec .tier .stop { font-family: Orbitron, ui-monospace, monospace; font-size: 0.6rem; }
.rec .tier .stop.won { color: var(--ui-accent); border-color: var(--ui-accent); box-shadow: 0 0 8px color-mix(in srgb, var(--ui-accent) 45%, transparent); }
.rec .tier .stop.hard { color: var(--gold); border-color: var(--gold); box-shadow: 0 0 8px rgba(242, 193, 78, 0.6); }
.rec .tier .tstate { font-family: Orbitron, ui-monospace, monospace; font-size: 0.5rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ui-dim); text-align: right; }
.rec .tier .tstate.done { color: var(--gold); }
.rec .tier.locked { opacity: 0.4; }
/* quick match: three columns */
.rec .quick { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.4rem; }
.rec .quick div { text-align: center; padding: 0.45rem 0; border-radius: 0.6rem; background: rgba(255, 255, 255, 0.04); }
.rec .quick b { display: block; font-family: "Baloo 2", ui-rounded, system-ui, sans-serif; font-weight: 800; font-size: 1.1rem; line-height: 1.1; }
.rec .quick span { font-family: Orbitron, ui-monospace, monospace; font-size: 0.5rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ui-dim); }
.rec .quick i { display: block; font-style: normal; font-family: Orbitron, ui-monospace, monospace; font-size: 0.5rem; color: var(--gold); margin-top: 0.15rem; }
/* the collection */
.rec .coll { display: flex; flex-direction: column; gap: 0.35rem; }
.rec .coll div { display: grid; grid-template-columns: 4.5rem 1fr auto; align-items: center; gap: 0.6rem; font-size: 0.8rem; }
.rec .coll .bar { height: 6px; border-radius: 3px; background: rgba(255, 255, 255, 0.09); overflow: hidden; }
.rec .coll .bar i { display: block; height: 100%; background: linear-gradient(90deg, var(--ui-accent), #fff); }
.rec .coll b { font-family: Orbitron, ui-monospace, monospace; font-size: 0.6rem; letter-spacing: 0.08em; color: var(--ui-dim); font-weight: 600; font-variant-numeric: tabular-nums; }
/* groups, and a section that folds */
.rec-group { margin: 0.5rem 0 0; font-family: Orbitron, ui-monospace, monospace; font-size: 0.56rem; letter-spacing: 0.2em; text-transform: uppercase; color: var(--ui-dim); text-align: left; }
.rec.fold .rec-head { cursor: pointer; margin-bottom: 0; }
.rec.fold .rec-head .chev { width: 0.55rem; height: 0.55rem; border-right: 2px solid var(--ui-dim); border-bottom: 2px solid var(--ui-dim); transform: rotate(45deg); margin: 0 0.2rem 0.2rem 0.4rem; transition: transform 0.2s; flex: none; }
.rec.fold.open .rec-head .chev { transform: rotate(-135deg); margin-bottom: -0.2rem; }
.rec.fold.shut .fold-body { display: none; }
.rec.fold.open .fold-body { margin-top: 0.4rem; }
.rec .quick .soon { opacity: 0.55; }
/* hard mode on the breaker map's labels */
.node-label .hm { color: var(--gold); font-size: 0.7em; text-shadow: 0 0 6px rgba(242, 193, 78, 0.8); margin-left: 0.15em; }

/* ---- a moment: bought, earned, levelled ---- */
#moment.moment {
  z-index: 40; justify-content: center;
  background: rgba(7, 9, 14, 0.6);
  backdrop-filter: none; -webkit-backdrop-filter: none;
}
#moment-fx { position: fixed; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.moment-actions .quiet { color: var(--ui-text); opacity: 0.8; }
.moment-actions .quiet[hidden], .moment-actions .primary[hidden] { display: none; }
#moment-card {
  position: relative; max-width: 22rem; padding: 1.5rem 1.2rem 1.2rem;
  background: rgba(10, 13, 20, 0.94);
  border-color: rgba(242, 193, 78, 0.55);
  box-shadow: inset 0 1px 0 rgba(255, 240, 181, 0.5), 0 0 40px rgba(242, 193, 78, 0.25), 0 20px 50px rgba(0, 0, 0, 0.5);
  animation: moment-in 0.55s cubic-bezier(0.2, 1.4, 0.4, 1);
}
#moment-card .eyebrow { color: var(--gold); }
#moment-card .art {
  width: 100%; aspect-ratio: 2 / 1; border-radius: 0.8rem; margin: 0.2rem 0 0.3rem;
  background-size: cover; background-position: center 30%; background-color: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--edge-dim); box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4);
}
#moment-card .art[hidden] { display: none; }
#moment-card .title { font-size: clamp(1.9rem, 9vw, 2.6rem); margin: 0; }
#moment-card .subtitle { margin: 0; }
.moment-actions { display: flex; flex-direction: column; gap: 0.4rem; width: 100%; margin-top: 0.6rem; }
.moment-actions .primary { width: 100%; }
@keyframes moment-in { 0% { transform: scale(0.7) translateY(30px); opacity: 0; } 100% { transform: none; opacity: 1; } }
@media (prefers-reduced-motion: reduce) { #moment-card { animation: none; } }

/* the result: the card sits in the room's middle, the tiles at the foot */
#over.result { justify-content: center; gap: 0.8rem; }
#over.result .tiles { margin-top: 0; }
#over.result .tile { min-height: 5.2rem; }

/* playing a friend */
.tiles.friend { margin-top: auto; }
.tile.join { justify-content: center; gap: 0.6rem; }
.tile.join .join-row { display: flex; gap: 0.5rem; width: 100%; }
.tile.join input[type="text"] {
  flex: 1; min-width: 0;
  font-family: Orbitron, ui-monospace, monospace; font-size: 1.05rem;
  border-radius: 0.8rem; border: 1px solid var(--edge-dim); background: rgba(255, 255, 255, 0.05);
}
.pill-btn {
  font-family: Orbitron, ui-monospace, monospace; font-size: 0.7rem; letter-spacing: 0.1em; text-transform: uppercase;
  padding: 0.6rem 1rem; border-radius: 999px;
  background: var(--ui-accent); color: var(--bg); border: 1px solid var(--ui-accent);
}
.tiles.friend .tile.join { grid-column: 1 / -1; }

/* WHAT IS NEXT, on a Record card. Quieter than the numbers above it
   and set apart by a rule, so it reads as a pointer rather than as
   another statistic. */
.rec-next {
  margin: 0.7rem 0 0;
  padding-top: 0.6rem;
  border-top: 1px solid var(--edge-dim);
  font-family: Orbitron, ui-monospace, monospace;
  font-size: 0.58rem; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ui-accent);
}

/* One quiet line above the doors: the nearest thing worth doing.
   Deliberately under the weight of the doors themselves - it is a
   nudge, not an instruction. */
.next-up {
  grid-column: 1 / -1;
  margin: 0 0 0.1rem;
  font-family: Orbitron, ui-monospace, monospace;
  font-size: 0.58rem; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ui-dim);
  text-align: center;
  /* it sits over the room, not over a card */
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.85);
}

/* THE TWO DOORS sit side by side, and are the same size - measured,
   they match to the pixel. What made Computer read heavier was the
   words: a longer title at the same size fills more of the card. So
   the titles are fitted to the card rather than the other way round. */
.tiles .tile.big.door { grid-column: auto; min-height: 7.2rem; }
.tiles .tile.big.door .tile-title { font-size: clamp(1.5rem, 7.2vw, 2rem); }
/* the longer of the two words comes down a notch so the pair sit at
   the same weight on the screen */
.tiles .tile.big.door#door-computer .tile-title { font-size: clamp(1.3rem, 6.2vw, 1.75rem); }
.tiles .tile.big.door .tile-note { min-height: 2.4em; }

/* versus the computer: three levels in a row, two modes, back under */
.tiles.computer { grid-template-columns: repeat(6, 1fr); }
.tiles.computer .tile.lvl { grid-column: span 2; padding: 0.85rem 0.7rem; }
.tiles.computer .tile.mode { grid-column: span 3; }
.tiles .tile.back { grid-column: 1 / -1; min-height: 4.2rem; }

/* versus players: the doors that are not open yet */
.tile.soon { background: transparent; box-shadow: none; border-style: dashed; border-color: var(--edge-dim); }
.tile.soon .tile-title { color: var(--ui-dim); }
.tile.soon .eyebrow { color: var(--ui-accent); opacity: 0.8; }
.tile.soon:active { transform: none; }

/* the breaker level card wears the glass too */
#node-card {
  background: var(--glass, rgba(10, 13, 20, 0.66));
  border: 1px solid var(--edge-dim, rgba(228, 244, 255, 0.13));
  border-radius: 1.2rem;
  box-shadow: inset 0 1px 0 var(--edge, rgba(228, 244, 255, 0.36)), 0 10px 30px rgba(0, 0, 0, 0.45);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
}
#node-card .choices button { border-radius: 999px; }
#node-card .choices button.primary { font-family: Orbitron, ui-monospace, monospace; font-size: 0.72rem; letter-spacing: 0.12em; text-transform: uppercase; }
/* the map's own bar */
#tunnel-bar button.quiet { font-family: Orbitron, ui-monospace, monospace; font-size: 0.62rem; letter-spacing: 0.14em; text-transform: uppercase; }

/* a readout, not a control */
.sheet .choice-value.readout {
  border-color: var(--edge-dim); background: rgba(255, 255, 255, 0.04); color: var(--ui-dim);
  text-transform: none; letter-spacing: 0.06em;
}
/* the demo button on the map's bar, opposite Back */
#tunnel-bar #demos-open { flex: none; margin: 0; padding: 0.3rem 0.2rem; }

/* the breaker card's art is a drawing of the level itself: the room
   seen from the paddle, its blocks where they stand */
#node-card .art svg { width: 100%; height: 100%; display: block; }
#node-card .art { width: 4.4rem; height: 6.2rem; background: rgba(255, 255, 255, 0.03); overflow: hidden; }

/* the Computer menu: how you are doing, on the tile itself */
.tile .tile-stat { display: block; margin-top: 0.35rem; font-family: Orbitron, ui-monospace, monospace; font-size: 0.55rem; letter-spacing: 0.1em; color: var(--ui-dim); }
.tile .tile-stat .stars { display: inline-flex; font-size: 0.7rem; margin-right: 0.3em; vertical-align: middle; }
.tile .tile-stat .gold { color: var(--gold); font-weight: 600; }
/* a card whose picture is still being drawn breathes rather than sitting black */
.thumb.wait, .fthumb.wait {
  background-image: linear-gradient(110deg, rgba(255, 255, 255, 0.03) 30%, rgba(255, 255, 255, 0.09) 50%, rgba(255, 255, 255, 0.03) 70%);
  background-size: 220% 100%;
  animation: thumb-wait 1.6s linear infinite;
}
@keyframes thumb-wait { from { background-position: 120% 0; } to { background-position: -120% 0; } }
@media (prefers-reduced-motion: reduce) { .thumb.wait, .fthumb.wait { animation: none; } }

/* every sheet reads the same way as the store: home at the left, the name beside it */
.sheet .topbar { justify-content: flex-start; }
.sheet .topbar .crumb { flex: 1; text-align: left; }
/* a row that only reports: the readout goes under the note, full width, rather than squeezing it */
.sheet .setting.readout-row { grid-template-columns: 1fr; }
.sheet .setting.readout-row .setting-note { grid-row: 2; margin-top: 0; }
.sheet .setting.readout-row .readout { grid-row: 3; justify-self: start; }
/* The account row stacks further: the readout, then who you are, then
   the way in, then the way out. Each needs its own row said out loud -
   the rule above pins every note to row 2, and two notes in one row
   land on top of each other. */
.sheet .setting.readout-row .account-id { grid-row: 4; margin-top: 8px; }
.sheet .setting.readout-row .signin-bay { grid-row: 5; }
.sheet .setting.readout-row .setting-quiet { grid-row: 5; }
.sheet .setting.readout-row .signin-why { grid-row: 6; margin-top: 6px; }
.sheet .setting.readout-row .setting-danger { grid-row: 7; }
/* the effect picker's None */
.pthumb.none { display: grid; place-items: center; }
.pthumb .pnone { font-size: 1.6rem; color: var(--ui-dim); }
.pthumb svg.glyph { width: 60%; height: 60%; display: block; margin: 8% auto; fill: none; stroke: var(--ui-accent); stroke-width: 2.4; }

/* the tuning log on the result, only while the dial is on */
.dial-log { margin-top: 14px; text-align: left; }
.dial-log pre { margin: 0 0 10px; font: 12px/1.5 ui-monospace, Menlo, monospace; white-space: pre-wrap; opacity: 0.85; }

/* colour variants on the product page: one dot per colour, the one in focus ringed */
.swatches { display: flex; gap: 0.5rem; margin-top: 0.4rem; }
.swatch { width: 26px; height: 26px; border-radius: 50%; border: 2px solid var(--edge-dim); padding: 0; cursor: pointer;
  box-shadow: inset 0 0 0 2px rgba(0,0,0,0.35); }
.swatch[aria-selected="true"] { border-color: #fff; box-shadow: inset 0 0 0 2px rgba(0,0,0,0.35), 0 0 0 2px var(--edge); }

/* tokens: a second pricebar, and the line of what is held */
.pricebar.token { background: linear-gradient(180deg, rgba(255,214,110,0.22), rgba(255,214,110,0.08)); border-color: rgba(255,214,110,0.55); color: #FFE7A8; }
.tokens-held { margin: 0; font-size: 12px; letter-spacing: 0.04em; opacity: 0.75; text-align: center; }

/* The way out of an account. Quiet until it is armed, because it is
   not a thing anyone should reach for by accident. */
.setting-danger {
  grid-column: 1 / -1;
  justify-self: start;
  margin-top: 10px;
  padding: 9px 16px;
  border: 1px solid rgba(255,255,255,0.18);
  border-radius: 999px;
  background: transparent;
  color: rgba(255,255,255,0.62);
  font: inherit;
  font-size: 0.86rem;
  letter-spacing: 0.01em;
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.setting-danger:hover { color: rgba(255,255,255,0.85); border-color: rgba(255,255,255,0.3); }
.setting-danger.armed {
  color: #FFD2C4;
  border-color: rgba(255,120,80,0.55);
  background: rgba(255,90,50,0.12);
}
.setting-danger[disabled] { opacity: 0.5; cursor: default; }

/* An account id, there to be read out once and otherwise ignored. */
.account-id {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.72rem;
  letter-spacing: 0.02em;
  color: rgba(255,255,255,0.38);
  margin-top: 4px;
  user-select: all;
  -webkit-user-select: all;
  word-break: break-all;
}

/* Here for a while and then not. Warm, so it reads as a clock
   rather than a warning. */
.focus .flag.limited {
  color: #FFD9A0;
  border-color: rgba(255, 170, 60, 0.5);
  background: rgba(255, 170, 60, 0.12);
}

/* Where Google's own sign-in button sits. Theirs, unaltered - it is
   the one people recognise, and Google asks that it not be restyled. */
.signin-bay {
  grid-column: 1 / -1;
  justify-self: start;
  margin-top: 12px;
  min-height: 40px;
}
.signin-why { grid-column: 1 / -1; color: #FFD2C4; margin-top: 6px; }

/* Who you just played, and the two things you can do about them.
   Quiet: most matches end with nobody wanting either button. */
.over-player {
  display: flex; align-items: center; justify-content: center;
  gap: 10px; flex-wrap: wrap; margin: 14px 0 2px;
  font-size: 0.82rem; color: var(--ui-dim);
}
.over-player .pill.small {
  padding: 5px 12px; font-size: 0.72rem;
  color: rgba(255,255,255,0.55); border-color: rgba(255,255,255,0.16);
}
.over-player .pill.small:hover { color: rgba(255,255,255,0.85); }
.over-player .pill.small[disabled] { opacity: 0.45; }
.over-player .pill.small.armed { color: #FFD2C4; border-color: rgba(255,120,80,0.55); }

/* Leaving an account, which is nothing to be careful about: it is all
   on the server and it comes back on the next sign-in. */
.setting-quiet {
  grid-column: 1 / -1;
  justify-self: start;
  margin-top: 12px;
  padding: 9px 18px;
  border: 1px solid var(--edge-dim);
  border-radius: 999px;
  background: transparent;
  color: var(--ui-accent);
  font: inherit;
  font-size: 0.86rem;
  cursor: pointer;
}
.setting-quiet:hover { border-color: var(--ui-accent); }
.setting-quiet[disabled] { opacity: 0.5; cursor: default; }

/* What you have and who you are, on one line under the loadout. */
.purse-row {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; margin-top: 2px;
}
.purse-row #purse-line { margin: 0; }
.who {
  border: 1px solid var(--edge-dim);
  border-radius: 999px;
  background: transparent;
  color: var(--ui-dim);
  font: inherit; font-size: 0.72rem; letter-spacing: 0.04em;
  padding: 4px 12px;
  cursor: pointer;
  white-space: nowrap;
}
.who:hover { color: var(--ui-accent); border-color: var(--ui-accent); }
.who.signed { color: var(--ui-accent); }

/* The account sheet: the same pieces as the old settings row, stacked
   and centred rather than laid into a grid. */
#account-card .signin-bay { justify-self: center; margin: 16px auto 0; }
#account-card .setting-quiet,
#account-card .setting-danger { justify-self: center; margin: 14px auto 0; }
#account-card .account-id { text-align: center; margin-top: 10px; }

/* The admin's corner. Plain on purpose: it is used a handful of times
   a year and should not look like part of the game. */
.give { width: min(420px, 90%); margin: 26px auto 0; text-align: left; }
.give .eyebrow { margin-bottom: 8px; }
.give-row { display: flex; gap: 8px; margin-bottom: 8px; }
.give-row input, .give-row select {
  flex: 1; min-width: 0;
  padding: 9px 12px;
  border: 1px solid var(--edge-dim); border-radius: 10px;
  background: rgba(255,255,255,0.03); color: var(--ui-text);
  font: inherit; font-size: 0.86rem;
}
.give-row .pill-btn { flex: none; }
#give-said { margin-top: 6px; min-height: 1.2em; }

/* The name other players see, said properly: it is the one thing on
   this page anybody actually enjoys having. */
.gamertag {
  font-family: Orbitron, ui-monospace, monospace;
  font-size: clamp(1.4rem, 6vw, 2.1rem);
  letter-spacing: 0.06em;
  color: var(--ui-accent);
  margin: 6px 0 10px;
  word-break: break-word;
}
#account-card .pill.small {
  padding: 5px 14px; font-size: 0.72rem;
  color: rgba(255,255,255,0.6); border-color: rgba(255,255,255,0.18);
  background: transparent; border-style: solid; border-width: 1px;
  border-radius: 999px; cursor: pointer; font-family: inherit;
}
#account-card .pill.small:hover { color: var(--ui-accent); border-color: var(--ui-accent); }


/* The opening: the name, and what the game is in one line. Held over
   the court rather than over a blank screen, so the first thing
   anybody sees is the thing they came for. */
.opening {
  position: fixed; inset: 0; z-index: 40;
  display: grid; place-items: center;
  background: radial-gradient(ellipse at center, rgba(4,6,10,0.72), rgba(4,6,10,0.94));
  pointer-events: auto;      /* it waits to be tapped */
  cursor: pointer;
}
.opening.going { animation: opening-out 0.45s ease forwards; pointer-events: none; }
.opening-inner { position: relative; text-align: center; padding: 0 24px; }

.opening-name {
  position: relative;
  margin: 0;
  font-family: Orbitron, ui-monospace, monospace;
  font-size: clamp(2.6rem, 14vw, 5rem);
  letter-spacing: 0.12em;
  /* Cyan into magenta - the two colours the game already is: the
     court's lines and the ball. The gradient is painted into the
     letters themselves, so the glow comes from a drop-shadow rather
     than a text-shadow, which would fall behind transparent type and
     never be seen. */
  background: linear-gradient(103deg, #6BE4FF 0%, #9ED7FF 26%, #FF4FD8 74%, #FF7A3C 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 0 14px rgba(120, 220, 255, 0.45))
          drop-shadow(0 0 42px rgba(255, 60, 200, 0.28));
  animation: opening-name 0.9s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
/* The split either side of it, the way a bad signal separates the
   colours. Two copies of the word behind the real one. */
.opening-name::before,
.opening-name::after {
  content: 'Backwall';
  position: absolute;
  left: 0; right: 0; top: 0;
  background: none;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  filter: none;
  z-index: -1;
  opacity: 0.5;
}
.opening-name::before { color: #00E5FF; transform: translate(-3px, 1px); }
.opening-name::after  { color: #FF2BD1; transform: translate(3px, -1px); }

.opening-line {
  position: relative;
  display: inline-block;
  margin: 18px 0 0;
  padding: 7px 18px;
  font-family: Orbitron, ui-monospace, monospace;
  font-size: clamp(0.66rem, 3vw, 0.86rem);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: #C9F4FF;
  /* Balanced, so it never breaks after "back" and leaves "wall" on a
     line by itself - which is the one wrap this sentence cannot
     survive, since the whole line is about the back wall. No
     max-width with it: `ch` ignores letter-spacing, so 20ch measured
     far narrower than the text actually is and forced three lines on
     a wide screen. Balance alone wraps only when it has to. */
  text-wrap: balance;
  /* A strip of signal rather than a sentence: a wash behind, a
     hairline above and below, and both fading out at the ends. */
  background: linear-gradient(90deg, rgba(0,229,255,0) 0%, rgba(0,229,255,0.14) 24%,
                                     rgba(255,43,209,0.14) 76%, rgba(255,43,209,0) 100%);
  border-top: 1px solid rgba(120, 230, 255, 0.32);
  border-bottom: 1px solid rgba(255, 90, 210, 0.28);
  text-shadow: 0 0 12px rgba(120, 230, 255, 0.45);
  animation: opening-line 0.8s ease 0.5s both;
}

/* The invitation, once the name has had its moment. */
.opening-tap {
  margin: 30px 0 0;
  font-family: Orbitron, ui-monospace, monospace;
  font-size: 0.74rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.55);
  animation: opening-tap 2.4s ease 1.3s infinite both;
}

@keyframes opening-name {
  from { opacity: 0; transform: scale(1.14); filter: blur(6px); }
  to   { opacity: 1; transform: scale(1); }
}
@keyframes opening-line {
  from { opacity: 0; transform: translateY(8px); letter-spacing: 0.4em; }
  to   { opacity: 1; transform: none; letter-spacing: 0.2em; }
}
@keyframes opening-tap {
  0%   { opacity: 0; }
  18%  { opacity: 0.8; }
  70%  { opacity: 0.8; }
  100% { opacity: 0.25; }
}
@keyframes opening-out { to { opacity: 0; visibility: hidden; } }
@media (prefers-reduced-motion: reduce) {
  .opening-name, .opening-line { animation-duration: 0.01s; animation-delay: 0s; opacity: 1; }
  .opening-tap { animation: none; opacity: 0.7; }
}
