/* Retro CRT phosphor terminal. Designed for clarity at 320px and up.
   The datacenter floor is the main visual stage  -  it should always be
   readable above a fold even on a small phone. */

:root {
  --bg: #050a07;
  --bg-panel: #0a1410;
  --bg-deep: #020503;
  --fg: #46f08a;
  --fg-dim: #2a8c50;
  --fg-bright: #b4ffd0;
  --warn: #f0c846;
  --bad: #ff5050;
  --good: #46f08a;
  --frontier: #b46aff;     /* B200 accent  -  distinguishes tiers visually */
  --premium: #6ab4ff;      /* H100 */
  --border: #1d3a28;
  --gold:   #ffd066;       /* personal-best ribbon accent */
  /* Type ramp: 4 sizes only. Apply via class or direct font-size, no
     ad-hoc one-off pixel values. Mobile-first; bump 1px at desktop. */
  --t-dim: 11px;    /* labels, muted secondary */
  --t-base: 13px;   /* default body / row values */
  --t-emph: 15px;   /* emphasized rows / button labels */
  --t-hero: 18px;   /* NET, BREAKING headline, single-shot hero */
  /* System monospace fallback chain. Google-Fonts-hosted faces split
     the box-drawing range out of their default subset, so loading
     JetBrains Mono via CDN leaves U+2500-257F drawn by the system
     fallback at a different advance width than the latin+block chars,
     which shatters any ASCII art that mixes them. System monospaces
     (Menlo / Consolas / Courier) ship the full ranges in one face. */
  --mono: 'Menlo', 'Consolas', 'Courier New', ui-monospace, monospace;
}

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

html, body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--mono);
  font-size: 14px;
  line-height: 1.5;
  min-height: 100vh;
  overflow-x: hidden;
  -webkit-font-smoothing: none;
}

body.crt {
  text-shadow: 0 0 2px var(--fg), 0 0 6px rgba(70, 240, 138, 0.4);
}

/* Phosphor scanlines  -  overlay layer, pointer-events: none so it never
   blocks the action. Tiny flicker animation gives it warmth. */
.scanlines {
  position: fixed; inset: 0; pointer-events: none; z-index: 100;
  background: repeating-linear-gradient(
    to bottom,
    transparent 0,
    transparent 2px,
    rgba(0, 0, 0, 0.18) 2px,
    rgba(0, 0, 0, 0.18) 3px
  );
  animation: flicker 6s infinite;
}
.bloom {
  position: fixed; inset: 0; pointer-events: none; z-index: 99;
  background: radial-gradient(ellipse at center, transparent 60%, rgba(0, 0, 0, 0.5) 100%);
}
@keyframes flicker {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.97; }
}

.screen {
  max-width: 920px;
  margin: 0 auto;
  padding: 16px 12px 80px;
  min-height: 100vh;
}

/* CRITICAL: ensure the [hidden] attribute actually hides elements. CSS
   selectors like `.game-screen { display: flex }` can override the browser
   default `[hidden] { display: none }` because they're more specific. Force
   it back. */
[hidden] { display: none !important; }

/* Game screen specifically: fit to viewport, no scroll. The scene takes the
   middle flex space; everything else stacks tight. */
.screen.game-screen:not([hidden]) {
  height: 100vh;
  min-height: 100vh;
  max-height: 100vh;
  padding: 6px 10px 4px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  overflow: hidden;
}
.screen.game-screen .scene {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  padding: 4px;
  margin-bottom: 0;
}
.screen.game-screen .scene .scene-svg {
  flex: 1 1 auto;
  min-height: 0;
  max-height: 100%;
}
.screen.game-screen .topbar { margin-bottom: 0; padding: 6px 10px; }
.screen.game-screen .ticker { margin-bottom: 0; padding: 4px 10px; }
.screen.game-screen .actionbar {
  margin-bottom: 0;
  padding: 4px 8px;
  gap: 4px;
}
.screen.game-screen .actions {
  margin-top: 0;
  padding: 6px 0 4px;
}

.banner {
  color: var(--fg-bright);
  white-space: pre;
  text-align: center;
  font-size: 11px;
  /* Critical: rows of block chars (█) need line-height 1 or vertical
     gaps appear between each row of the title art. Body inherits 1.5. */
  line-height: 1;
  letter-spacing: 0;
  margin: 8px 0 12px;
  overflow-x: auto;
  overflow-y: hidden;
}
@media (min-width: 600px) { .banner { font-size: 14px; } }

/* Spec card  -  the GPU pricing + objective bar that sits directly under
   the boot banner. Lifted out of the cramped ASCII title so the title
   reads clean. Uses the same dim-border / panel-bg as .log and the
   region cards so the landing-page stack reads as one consistent surface. */
.spec-card {
  display: grid;
  grid-template-columns: 1fr;
  gap: 10px;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  padding: 12px 14px;
  margin-bottom: 12px;
}
@media (min-width: 600px) {
  .spec-card { grid-template-columns: 1fr 1fr 1fr; gap: 18px; }
}
.spec-col { display: flex; flex-direction: column; gap: 4px; }
.spec-label {
  color: var(--fg-bright);
  font-size: var(--t-dim);
  letter-spacing: 2px;
  font-weight: bold;
}
.spec-bar {
  height: 6px;
  background: var(--bg-deep);
  border: 1px solid var(--border);
  position: relative;
}
.spec-bar-fill {
  display: block;
  height: 100%;
  background: var(--fg);
}
.spec-bar-fill.premium { background: var(--premium); }
.spec-meta {
  color: var(--fg-dim);
  font-size: var(--t-dim);
  letter-spacing: 1px;
}
.spec-meta.warn { color: var(--warn); }
.spec-objective .spec-label { color: var(--warn); }

.banner-small {
  color: var(--fg-bright);
  font-size: 18px;
  margin: 12px 0 16px;
  border-bottom: 1px solid var(--border);
  padding-bottom: 8px;
}

.log {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  padding: 12px;
  margin: 12px 0;
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 60vh;
  overflow-y: auto;
}
.log p { margin: 6px 0; }
.log ol, .log ul { margin: 6px 0 6px 24px; }
.log b { color: var(--fg-bright); }

/* Academy lesson cards. Stacked, scrollable, dense but readable.
   Each lesson is a self-contained school-teacher voice block:
   concrete example -> mechanism -> "in this game" tie-back. */
.learn-intro {
  color: var(--fg-dim);
  font-size: var(--t-base);
  line-height: 1.6;
  max-width: 720px;
  margin: 8px auto 20px;
  text-align: center;
}
.lesson {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-left: 3px solid var(--fg);
  padding: 16px 18px;
  margin: 0 0 14px;
  max-width: 720px;
  margin-left: auto;
  margin-right: auto;
}
.lesson h2 {
  color: var(--fg-bright);
  font-size: var(--t-emph);
  letter-spacing: 1.5px;
  margin: 0 0 12px;
  padding-bottom: 8px;
  border-bottom: 1px dashed var(--border);
}
.lesson-num {
  display: inline-block;
  background: var(--fg);
  color: var(--bg);
  padding: 2px 8px;
  margin-right: 10px;
  font-size: var(--t-dim);
  letter-spacing: 2px;
}
.lesson p, .lesson ul {
  color: var(--fg);
  font-size: var(--t-base);
  line-height: 1.55;
  margin: 0 0 10px;
}
.lesson ul { padding-left: 22px; }
.lesson li { margin: 4px 0; }
.lesson b { color: var(--fg-bright); }
.lesson i { color: var(--warn); font-style: normal; }
.lesson code {
  background: var(--bg-deep);
  border: 1px solid var(--border);
  padding: 0 4px;
  color: var(--fg-bright);
  font-size: var(--t-dim);
}
.lesson .in-this-game {
  background: var(--bg-deep);
  border-left: 2px solid var(--warn);
  padding: 8px 10px;
  margin-top: 12px;
  margin-bottom: 0;
  color: var(--fg-dim);
  font-size: var(--t-dim);
}
.lesson .in-this-game b { color: var(--warn); }

.hotkey-list {
  list-style: none;
  margin: 6px 0;
  padding: 0;
}
.hotkey-list li { margin: 4px 0; }
kbd {
  display: inline-block;
  padding: 1px 6px;
  border: 1px solid var(--fg-dim);
  background: var(--bg-panel);
  color: var(--fg-bright);
  font-family: var(--mono);
  font-size: var(--t-dim);
  letter-spacing: 1px;
  min-width: 18px;
  text-align: center;
}

.prompt {
  display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px;
}

/* Buttons */
.btn, .btn-primary, .btn-ghost, .btn-small {
  font-family: var(--mono);
  font-size: 14px;
  background: transparent;
  color: var(--fg);
  border: 1px solid var(--fg);
  padding: 10px 14px;
  cursor: pointer;
  text-shadow: inherit;
  transition: background 0.1s, color 0.1s, transform 0.05s;
  min-height: 44px; /* touch target */
}
.btn:hover, .btn-primary:hover, .btn-small:hover {
  background: var(--fg); color: var(--bg);
}
.btn:active, .btn-primary:active, .btn-small:active { transform: translateY(1px); }
.btn-primary { color: var(--fg-bright); border-color: var(--fg-bright); }
.btn-ghost { border-color: var(--fg-dim); color: var(--fg-dim); }
.btn-ghost:hover { background: var(--fg-dim); color: var(--bg); }
/* Touch target: 44px tall is the Apple/Material floor for one-thumb taps.
   Padding kept tight so the chrome still reads compact next to the larger
   primary buttons. */
.btn-small {
  padding: 10px 12px; font-size: var(--t-base); min-height: 44px;
}
.btn-clear { border-color: var(--fg-dim); color: var(--fg-dim); padding: 10px 12px; }

/* Top bar / news ticker */
.topbar {
  display: flex; gap: 16px; align-items: center; flex-wrap: wrap;
  border: 1px solid var(--border);
  padding: 10px 14px;
  margin-bottom: 8px;
}
.topbar .stat { color: var(--fg-bright); font-size: var(--t-base); }
.topbar .btn-ghost { margin-left: auto; padding: 4px 10px; min-height: 32px; }

/* Active-region pill: tiny pixel-art chip of the chosen state + label. Lives
   in the topbar so the player always knows which run they're in. */
.region-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 8px 2px 4px;
  border: 1px solid var(--border);
  border-radius: 2px;
  background: var(--bg-panel);
  letter-spacing: 1px;
}
.region-badge-art {
  width: 28px;
  height: 20px;
  image-rendering: pixelated;
}
#ui-region-name { color: var(--fg-bright); font-weight: bold; font-size: 12px; }

.ticker {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-left: 3px solid var(--warn);
  padding: 8px 12px;
  margin-bottom: 12px;
  font-size: var(--t-base);
}
.ticker-line { color: var(--warn); }
.ticker-effect {
  margin-top: 4px;
  font-size: var(--t-dim);
  letter-spacing: 1px;
}
.ticker-pre { color: var(--fg); margin-right: 8px; font-weight: bold; }

/* Region selector  -  three big chunky cards with pixel art previews. */
.region-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 10px;
  width: 100%;
}
@media (min-width: 600px) { .region-grid { grid-template-columns: 1fr 1fr 1fr; } }

.region-card {
  font-family: var(--mono);
  background: var(--bg-panel);
  border: 1px solid var(--fg);
  color: var(--fg);
  padding: 12px;
  text-align: left;
  cursor: pointer;
  text-shadow: inherit;
  display: flex; flex-direction: column; gap: 6px;
  min-height: auto;
  transition: background 0.12s, transform 0.05s;
}
.region-card:hover { background: rgba(70, 240, 138, 0.08); }
.region-card:active { transform: translateY(1px); }
.region-art {
  width: 100%;
  height: 60px;
  image-rendering: pixelated;
}
.region-name {
  color: var(--fg-bright);
  font-size: 14px;
  letter-spacing: 2px;
  font-weight: bold;
}
.region-blurb {
  color: var(--fg-dim);
  font-size: 11px;
  line-height: 1.4;
}

/* DATACENTER FLOOR  -  the main visual stage */
.floor {
  background: var(--bg-deep);
  border: 1px solid var(--border);
  padding: 14px 14px 10px;
  margin-bottom: 12px;
  position: relative;
}
.floor-title {
  color: var(--fg-bright);
  font-size: 11px;
  letter-spacing: 3px;
  margin-bottom: 12px;
  text-align: center;
  border-bottom: 1px dashed var(--border);
  padding-bottom: 8px;
}

.rack-row {
  display: grid;
  grid-template-columns: 80px 1fr 30px;
  align-items: center;
  gap: 8px;
  margin: 4px 0;
}
@media (min-width: 600px) {
  .rack-row { grid-template-columns: 130px 1fr 40px; }
}
.rack-label {
  font-size: 13px;
  color: var(--fg-bright);
  line-height: 1.15;
}
.rack-sub {
  display: block;
  font-size: 10px;
  color: var(--fg-dim);
  letter-spacing: 0.5px;
}
.rack-slots {
  display: flex; flex-wrap: wrap; gap: 4px;
  min-height: 28px;
  align-content: center;
}
.gpu-card {
  width: 36px; height: 27px;
  display: inline-block;
  image-rendering: pixelated;
  image-rendering: crisp-edges;
  flex-shrink: 0;
}
@media (min-width: 600px) {
  .gpu-card { width: 44px; height: 33px; }
}
.gpu-card.pending {
  animation: gpu-pending 0.7s ease-in-out infinite;
}
.gpu-card.serving {
  animation: gpu-pulse 0.5s ease-out;
}
.gpu-card.h100 { filter: drop-shadow(0 0 3px var(--premium)); }
.gpu-card.b200 { filter: drop-shadow(0 0 4px var(--frontier)); }
@keyframes gpu-pending {
  0%, 100% { opacity: 0.4; }
  50%      { opacity: 1; }
}
@keyframes gpu-pulse {
  0%   { transform: scale(1) translateY(0);   filter: brightness(1); }
  40%  { transform: scale(1.2) translateY(-3px); filter: brightness(1.6); }
  100% { transform: scale(1) translateY(0);   filter: brightness(1); }
}
.rack-empty {
  color: var(--fg-dim);
  font-style: italic;
  font-size: 11px;
  opacity: 0.6;
}
/* Legacy slot class kept for fallback */
.rack-slot {
  width: 14px; height: 14px;
  display: inline-block;
  color: var(--fg);
  font-size: 14px;
}
@keyframes rack-pulse {
  0% { transform: scale(1); filter: brightness(1); }
  50% { transform: scale(1.3); filter: brightness(1.6); }
  100% { transform: scale(1); filter: brightness(1); }
}
@keyframes blink {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.3; }
}
.rack-count {
  color: var(--fg-bright);
  text-align: right;
  font-size: 13px;
}

.power-bar {
  margin: 10px 0 8px;
  padding: 6px 10px;
  border: 1px dashed var(--border);
  display: flex; align-items: center; gap: 12px;
  font-size: 12px;
  color: var(--fg);
}
.power-icon { font-size: 16px; }
.power-flow {
  letter-spacing: 4px;
  color: var(--warn);
  animation: power-flow 1s linear infinite;
}
@keyframes power-flow {
  0%   { opacity: 0.4; transform: translateX(-2px); }
  50%  { opacity: 1; transform: translateX(0); }
  100% { opacity: 0.4; transform: translateX(2px); }
}

.queue-row {
  display: grid;
  grid-template-columns: 80px 1fr;
  gap: 8px; align-items: center;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px dashed var(--border);
}
@media (min-width: 600px) {
  .queue-row { grid-template-columns: 130px 1fr; }
}
.queue-label {
  color: var(--fg-bright);
  font-size: 12px;
}
.queue-bar { display: flex; flex-direction: column; gap: 4px; }
.queue-icons {
  display: flex; flex-wrap: wrap; gap: 2px;
  min-height: 18px;
  font-size: 12px;
}
.queue-icon { display: inline-block; }
.queue-icon.waiting { color: var(--fg-dim); }
.queue-icon.served  { color: var(--good); animation: served-pop 0.3s ease-out; }
.queue-icon.dropped { color: var(--bad); animation: dropped-fade 0.5s ease-out; }
@keyframes served-pop {
  0%   { transform: scale(0.5); opacity: 0; }
  50%  { transform: scale(1.4); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
@keyframes dropped-fade {
  0%   { opacity: 1; }
  100% { opacity: 0.5; }
}
.queue-stat {
  font-size: 11px; color: var(--fg-dim);
}

/* Action bar */
.actionbar {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  padding: 10px 12px;
  margin-bottom: 12px;
  display: flex; flex-direction: column; gap: 8px;
}
.action-group, .action-row {
  display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
}
.action-row { font-size: 12px; }
.action-sep { color: var(--fg-dim); opacity: 0.4; padding: 0 2px; }
.tally-strip { display: inline-flex; gap: 8px; align-items: center; }
.tally-strip b { color: var(--fg-bright); }
.tally-strip .tally-h100 b { color: var(--premium); }
.tally-strip .tally-b200 b { color: var(--frontier); }

/* Topbar objective banner - the always-visible "next goal" line that
   anchors the player's next-tap intent. */
.objective {
  color: var(--warn);
  letter-spacing: 1px;
  padding: 2px 8px;
  border-left: 2px solid var(--warn);
  font-size: 11px;
  flex: 1 1 200px;
  text-align: left;
  text-shadow: 0 0 4px var(--warn);
}
.mute-toggle {
  font-size: 14px;
  padding: 2px 8px;
  border: none;
  background: transparent;
  cursor: pointer;
}
.mute-toggle:hover { background: rgba(70, 240, 138, 0.1); }
.action-label {
  font-size: 11px; color: var(--fg-dim); letter-spacing: 2px; min-width: 50px;
}
.action-cart {
  font-size: 11px; color: var(--warn); margin-left: auto;
}
.action-meta {
  font-size: 11px; color: var(--fg-dim);
}
.radio-chip {
  font-size: 12px;
  padding: 4px 8px;
  border: 1px solid var(--fg-dim);
  color: var(--fg-dim);
  cursor: pointer;
}
.radio-chip:has(input:checked) {
  border-color: var(--fg);
  color: var(--fg-bright);
  background: rgba(70, 240, 138, 0.08);
}
.radio-chip.locked {
  opacity: 0.45;
  pointer-events: none;
  border-style: dashed;
}
.radio-chip.locked .chip-price { color: var(--fg-dim); }
.radio-chip input { display: none; }
#price {
  background: var(--bg);
  border: 1px solid var(--fg-dim);
  color: var(--fg-bright);
  padding: 4px 8px;
  font-family: var(--mono);
  font-size: 14px;
  width: 80px;
  text-align: right;
  text-shadow: inherit;
}
#price:focus {
  outline: none; border-color: var(--fg-bright); box-shadow: 0 0 4px var(--fg-bright);
}

/* RUN DAY lives INSIDE the action row now, anchored right. Big, pulsing,
   not banished to the bottom of the page. */
.btn-run-day {
  margin-left: auto;
  font-size: 16px;
  padding: 12px 24px;
  letter-spacing: 2px;
  background: var(--bg-panel);
  color: var(--fg-bright);
  border: 2px solid var(--fg-bright);
  box-shadow: 0 0 14px rgba(70, 240, 138, 0.45);
  animation: btn-runday-idle 2.4s ease-in-out infinite;
}
.btn-run-day:hover {
  background: var(--fg-bright);
  color: var(--bg);
  box-shadow: 0 0 22px rgba(180, 255, 208, 0.7);
}
.btn-run-day.running {
  pointer-events: none;
  opacity: 0.7;
  animation: run-pulse 0.8s ease-in-out infinite;
}
@keyframes btn-runday-idle {
  0%, 100% { box-shadow: 0 0 12px rgba(70, 240, 138, 0.35); }
  50%      { box-shadow: 0 0 22px rgba(70, 240, 138, 0.7); }
}

.btn-market {
  border-color: var(--warn);
  color: var(--warn);
}
.btn-market:hover { background: var(--warn); color: var(--bg); }
.btn-market:disabled { opacity: 0.4; pointer-events: none; }

.power-row { gap: 8px; }
@keyframes run-pulse {
  0%, 100% { box-shadow: 0 0 0 var(--fg); }
  50%      { box-shadow: 0 0 12px var(--fg); }
}

/* Day-transition flash  -  quick scanline wipe between days. */
.day-flash {
  position: fixed; inset: 0; pointer-events: none; z-index: 200;
  background: linear-gradient(to bottom, transparent 0%, var(--fg) 49%, var(--fg) 51%, transparent 100%);
  background-size: 100% 6px;
  opacity: 0;
  animation: day-wipe 0.5s ease-out;
}
@keyframes day-wipe {
  0%   { opacity: 0; transform: translateY(-100%); }
  50%  { opacity: 0.4; }
  100% { opacity: 0; transform: translateY(100%); }
}

/* P&L flash on cash counter */
@keyframes cash-up   { 0% { color: var(--good); transform: scale(1.15); } 100% { color: var(--fg-bright); transform: scale(1); } }
@keyframes cash-down { 0% { color: var(--bad);  transform: scale(1.15); } 100% { color: var(--fg-bright); transform: scale(1); } }
.cash-up   { animation: cash-up   0.6s ease-out; }
.cash-down { animation: cash-down 0.6s ease-out; }

.good { color: var(--good); }
.warn { color: var(--warn); }
.bad  { color: var(--bad); }
.dim  { color: var(--fg-dim); }
.premium-c  { color: var(--premium); }
.frontier-c { color: var(--frontier); }

/* GPU sprite blocks in the primer screen  -  original ASCII art rendered in
   the same phosphor palette as the rest of the game. */
.gpu-sprite {
  font-family: var(--mono);
  font-size: 11px;
  white-space: pre;
  color: var(--fg);
  background: var(--bg-deep);
  border: 1px solid var(--border);
  padding: 10px;
  margin: 10px 0;
  overflow-x: auto;
  text-shadow: 0 0 3px var(--fg);
}
@media (min-width: 600px) { .gpu-sprite { font-size: 13px; } }

.action-cart.bad { color: var(--bad); }

/* Power chip shows today's spot price next to the fuel name. */
.chip-fuel { font-weight: bold; letter-spacing: 1px; }
.chip-price {
  font-size: 10px;
  color: var(--warn);
  margin-left: 4px;
  letter-spacing: 0.5px;
}
.radio-chip:has(input:checked) .chip-price { color: var(--fg-bright); }

.grid-strain-warn {
  flex-basis: 100%;
  margin-top: 4px;
  padding: 4px 8px;
  font-size: 11px;
  color: var(--bad);
  border: 1px dashed var(--bad);
  background: rgba(255, 80, 80, 0.06);
  letter-spacing: 0.5px;
}

/* Sell buttons. Different border so they don't blur with buy. */
.btn-small.btn-sell {
  border-color: var(--warn);
  color: var(--warn);
}
.btn-small.btn-sell:hover {
  background: var(--warn);
  color: var(--bg);
}

/* Tier info modal */
.tier-modal {
  background: var(--bg-panel);
  color: var(--fg);
  border: 1px solid var(--fg);
  font-family: var(--mono);
  padding: 16px;
  max-width: 920px;
  width: 92%;
}
.tier-modal::backdrop { background: rgba(0, 0, 0, 0.7); }
.tier-modal-lede {
  color: var(--fg-dim);
  font-size: var(--t-dim);
  line-height: 1.5;
  margin: 0 0 12px;
  padding: 8px 10px;
  border-left: 2px solid var(--fg-dim);
  background: var(--bg-panel);
}
.tier-modal-lede b { color: var(--fg-bright); }
.tier-modal h2 {
  color: var(--fg-bright);
  font-size: 16px;
  letter-spacing: 3px;
  margin-bottom: 12px;
  border-bottom: 1px solid var(--border);
  padding-bottom: 8px;
}
.tier-table {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
  margin-bottom: 12px;
}
@media (min-width: 700px) { .tier-table { grid-template-columns: 1fr 1fr 1fr; } }
.tier-col {
  border: 1px solid var(--border);
  padding: 10px;
  background: var(--bg-deep);
}
.tier-col h3 {
  font-size: 13px;
  letter-spacing: 1px;
  margin-bottom: 6px;
}
.a100-col h3 { color: var(--fg-bright); }
.h100-col h3 { color: var(--premium); }
.b200-col h3 { color: var(--frontier); }
.tier-col ul {
  list-style: none;
  font-size: 11px;
  line-height: 1.6;
  color: var(--fg-dim);
}
.tier-col ul li b { color: var(--fg-bright); }
.tier-modal-art {
  width: 100%;
  height: 40px;
  margin-bottom: 6px;
}

/* SCENE  -  composited isometric SVG datacenter. */
.scene {
  background: var(--bg-deep);
  border: 1px solid var(--border);
  padding: 6px;
  margin-bottom: 12px;
}
.scene-svg { width: 100%; height: auto; display: block; }
.scene-card.pending { animation: gpu-pending 0.7s ease-in-out infinite; }
/* Tier coloring on customer figures. The sprite uses currentColor for
   head / body / arms, so setting `color` on the <use> element cascades
   through. Player reads demand mix at a glance: green = A100 budget
   workload, blue = H100 production, violet = B200 frontier. */
.scene-customer { color: var(--fg); }
.scene-customer.tier-a100 { color: var(--fg); }
.scene-customer.tier-h100 { color: var(--premium); }
.scene-customer.tier-b200 { color: var(--frontier); }
.scene-customer.waiting { opacity: 0.85; }
.scene-customer.served {
  filter: drop-shadow(0 0 3px var(--good));
  animation: served-pop 0.35s ease-out;
}
.scene-customer.dropped {
  color: var(--bad);
  opacity: 0.35;
  animation: dropped-fade 0.5s ease-out;
}

.inv-tally {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  margin-top: 6px;
  padding: 6px 8px;
  font-size: 12px;
  border-top: 1px dashed var(--border);
}
.tally-a100 b { color: var(--fg-bright); }
.tally-h100 b { color: var(--premium); }
.tally-b200 b { color: var(--frontier); }
.btn-tiny {
  background: transparent;
  border: 1px solid var(--fg-dim);
  color: var(--fg-dim);
  font-family: var(--mono);
  font-size: var(--t-dim);
  /* Visual chrome still small, but the touch area is bumped to 32px tall
     via padding so a thumb can land it. */
  padding: 9px 10px;
  min-height: 32px;
  cursor: pointer;
  margin-left: auto;
}
.btn-tiny:hover { background: var(--fg-dim); color: var(--bg); }

/* Eco viz - escalates with served customers during run.
   diesel: smoke puffs drift up; grid: sparks flicker; ppa: sun pulses. */
.smoke-puff {
  animation: smoke-rise 1.4s ease-out forwards;
}
@keyframes smoke-rise {
  0%   { opacity: 0.7; transform: translate(0, 0) scale(1); }
  100% { opacity: 0;   transform: translate(0, -50px) scale(2.2); }
}
.grid-spark {
  animation: spark-flash 0.35s ease-out forwards;
}
@keyframes spark-flash {
  0%   { opacity: 1;   filter: drop-shadow(0 0 4px #f0c846); }
  100% { opacity: 0;   filter: drop-shadow(0 0 0 transparent); }
}
.ppa-sun.pulse { animation: sun-pulse 0.6s ease-out; }
@keyframes sun-pulse {
  0%   { filter: drop-shadow(0 0 0 #ffd700); }
  50%  { filter: drop-shadow(0 0 10px #ffd700) brightness(1.4); }
  100% { filter: drop-shadow(0 0 0 #ffd700); }
}
.scene-power.eco-on.eco-diesel { filter: drop-shadow(0 0 8px rgba(120,120,120,0.4)); }
.scene-power.eco-on.eco-ppa    { filter: drop-shadow(0 0 8px #ffd700); }

/* Idle-state diesel still belches occasional puffs even when not running -
   reinforces "this is dirty" before the player even hits RUN DAY. */
.scene-power.eco-diesel { animation: drum-idle-smoke 4s ease-in-out infinite; }
@keyframes drum-idle-smoke {
  0%, 80%, 100% { filter: drop-shadow(0 -4px 6px rgba(120,120,120,0.0)); }
  90%           { filter: drop-shadow(0 -10px 8px rgba(140,140,140,0.5)); }
}
.scene-power.eco-grid .grid-spark { animation: spark-idle 3s ease-in-out infinite; }
@keyframes spark-idle {
  0%, 70%, 100% { opacity: 0.3; }
  80%           { opacity: 1;   filter: drop-shadow(0 0 4px #f0c846); }
}
.scene-power.eco-ppa .ppa-sun {
  animation: sun-idle-glow 3.5s ease-in-out infinite;
}
@keyframes sun-idle-glow {
  0%, 100% { filter: drop-shadow(0 0 3px #f0c846); }
  50%      { filter: drop-shadow(0 0 9px #ffd700) brightness(1.15); }
}

/* Output cables from panels to PSU  -  marching dashes so the player
   sees power flowing into the junction box, matching the rack-side bus. */
.scene-power.eco-ppa .ppa-cable {
  animation: ppa-cable-flow 1.6s linear infinite;
}
.scene-power.eco-ppa .ppa-cable:nth-of-type(2) {
  animation-delay: -0.8s;
}
@keyframes ppa-cable-flow {
  from { stroke-dashoffset: 18; }
  to   { stroke-dashoffset: 0; }
}

/* Panel shimmer  -  a diagonal sweep across the glass surface every few
   seconds. The two panels offset so they don't fire in unison. */
.scene-power.eco-ppa .ppa-shimmer {
  animation: ppa-shimmer 4.5s ease-in-out infinite;
}
.scene-power.eco-ppa .ppa-panel-2 .ppa-shimmer {
  animation-delay: -2.2s;
}
@keyframes ppa-shimmer {
  0%, 70%, 100% { opacity: 0; }
  80%           { opacity: 0.25; }
  85%           { opacity: 0.35; }
  90%           { opacity: 0.15; }
}

/* Empty slot outlines so the player sees rack capacity visually. */
.scene-card.empty-slot { opacity: 0.55; }

/* Brownout / blackout: physically dark a GPU card. Kills the LED blink
   animation, drops fill saturation, and overlays a faint X so the player
   can count exactly how many GPUs went offline. */
.scene-card.brownout-off {
  animation: none !important;
  filter: grayscale(1) brightness(0.35) !important;
  opacity: 0.5;
}
.scene-card.brownout-off .gpu-led { opacity: 0 !important; animation: none !important; }

/* Whole-scene tints layered on the #game container during runDay. They
   stack: heatwave (red glow) + brownout (yellow flicker) + blackout (dim
   the whole rack area to black with a NO POWER overlay). */
.scene-heatwave .floor {
  box-shadow: inset 0 0 80px rgba(255, 80, 80, 0.18);
}
.scene-heatwave .floor::after {
  content: 'HEAT WAVE';
  position: absolute; top: 4px; right: 10px;
  color: var(--bad); font-size: var(--t-dim); letter-spacing: 3px;
  font-weight: bold;
  animation: scene-warn-flash 1.4s ease-in-out infinite;
}
.scene-brownout .floor {
  animation: scene-brownout-flicker 1.1s steps(2, end) infinite;
}
@keyframes scene-brownout-flicker {
  0%, 100% { filter: none; }
  50%      { filter: brightness(0.7); }
}
.scene-blackout #scene-svg {
  filter: brightness(0.25) contrast(1.4);
}
.scene-blackout .floor::after {
  content: 'NO POWER';
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  color: var(--bad); font-size: 32px; letter-spacing: 8px;
  font-weight: bold;
  text-shadow: 0 0 12px var(--bad);
  pointer-events: none;
  z-index: 5;
  animation: scene-warn-flash 0.9s ease-in-out infinite;
}
@keyframes scene-warn-flash {
  0%, 100% { opacity: 0.55; }
  50%      { opacity: 1; }
}

/* Filled GPU cards: subtle LED blink so racks feel alive. Cards inherit
   their tier color via inline style; the gpu-slot symbol's LED rect uses
   #f0c846 so this just adds a glow. */
.scene-card:not(.empty-slot):not(.pending) {
  animation: gpu-led-blink 2.2s ease-in-out infinite;
}
.scene-card.a100:not(.empty-slot):not(.pending) { filter: drop-shadow(0 0 1px #46f08a); }
.scene-card.h100:not(.empty-slot):not(.pending) { filter: drop-shadow(0 0 2px #6ab4ff); }
.scene-card.b200:not(.empty-slot):not(.pending) { filter: drop-shadow(0 0 3px #b46aff); }
@keyframes gpu-led-blink {
  0%, 90%, 100% { opacity: 1; }
  95%           { opacity: 0.65; }
}

/* Activity LEDs per GPU card, gated by data-util-tier (low / med / high / max).
   The sprite ships .gpu-led .gpu-led-1 .. .gpu-led-N per card; we light the
   subset that matches the current utilization bucket. led-blink keyframe is
   shared with the existing rack LEDs above. */
.scene-card .gpu-led { opacity: 0.18; }

/* Low: only LED-1 alive, slow heartbeat. */
.scene-card[data-util-tier="low"] .gpu-led-1 {
  opacity: 1;
  animation: led-blink 2.6s steps(2, end) infinite;
}

/* Mid: LEDs 1-2, faster. */
.scene-card[data-util-tier="med"] .gpu-led-1,
.scene-card[data-util-tier="med"] .gpu-led-2 {
  opacity: 1;
  animation: led-blink 1.4s steps(2, end) infinite;
}
.scene-card[data-util-tier="med"] .gpu-led-2 { animation-delay: -0.4s; }

/* High: LEDs 1..N-1 alive, fast. Cover up to 7 LEDs (B200 has 8). */
.scene-card[data-util-tier="high"] .gpu-led-1,
.scene-card[data-util-tier="high"] .gpu-led-2,
.scene-card[data-util-tier="high"] .gpu-led-3,
.scene-card[data-util-tier="high"] .gpu-led-4,
.scene-card[data-util-tier="high"] .gpu-led-5,
.scene-card[data-util-tier="high"] .gpu-led-6,
.scene-card[data-util-tier="high"] .gpu-led-7 {
  opacity: 1;
  animation: led-blink 0.8s steps(2, end) infinite;
}
.scene-card[data-util-tier="high"] .gpu-led-2 { animation-delay: -0.2s; }
.scene-card[data-util-tier="high"] .gpu-led-3 { animation-delay: -0.4s; }
.scene-card[data-util-tier="high"] .gpu-led-4 { animation-delay: -0.6s; }
.scene-card[data-util-tier="high"] .gpu-led-5 { animation-delay: -0.1s; }
.scene-card[data-util-tier="high"] .gpu-led-6 { animation-delay: -0.3s; }
.scene-card[data-util-tier="high"] .gpu-led-7 { animation-delay: -0.5s; }

/* Max: every LED screaming. Red warning tint on a couple of them so the
   player feels the over-stress. */
.scene-card[data-util-tier="max"] .gpu-led {
  opacity: 1;
  animation: led-blink 0.5s steps(2, end) infinite;
}
.scene-card[data-util-tier="max"] .gpu-led-2 { animation-delay: -0.1s; fill: #ff5050; }
.scene-card[data-util-tier="max"] .gpu-led-3 { animation-delay: -0.2s; }
.scene-card[data-util-tier="max"] .gpu-led-4 { animation-delay: -0.3s; }
.scene-card[data-util-tier="max"] .gpu-led-5 { animation-delay: -0.4s; fill: #ff5050; }
.scene-card[data-util-tier="max"] .gpu-led-6 { animation-delay: -0.05s; }
.scene-card[data-util-tier="max"] .gpu-led-7 { animation-delay: -0.15s; fill: #ff5050; }
.scene-card[data-util-tier="max"] .gpu-led-8 { animation-delay: -0.25s; }

/* Grid outage: the player chose grid AND the day got curtailed or browned-out.
   GPUs visibly go dark (LEDs muted, racks dimmed) so the outage is felt, not
   just read. Diesel/solar are independent power sources and stay lit. */
.scene-grid-outage .scene-card .gpu-led {
  fill: #666 !important;
  animation: none !important;
  opacity: 0.4 !important;
}
.scene-grid-outage #scene-rack-a100,
.scene-grid-outage #scene-rack-h100,
.scene-grid-outage #scene-rack-b200 {
  filter: grayscale(0.85) brightness(0.55);
  transition: filter 0.4s ease-out;
}
.scene-grid-outage .scene-card:not(.empty-slot) {
  animation: none;
}

/* News ticker reacts to event days. Spike = pulse yellow glow; bad = red. */
.ticker.event-spike { animation: ticker-spike 1.6s ease-out 1; border-left-color: var(--warn); }
.ticker.event-bad   { animation: ticker-bad   1.6s ease-out 1; border-left-color: var(--bad); }
@keyframes ticker-spike {
  0%   { box-shadow: 0 0 0 transparent; }
  30%  { box-shadow: 0 0 18px rgba(240, 200, 70, 0.55), inset 0 0 12px rgba(240, 200, 70, 0.2); }
  100% { box-shadow: 0 0 0 transparent; }
}
@keyframes ticker-bad {
  0%   { box-shadow: 0 0 0 transparent; }
  30%  { box-shadow: 0 0 18px rgba(255, 80, 80, 0.55), inset 0 0 12px rgba(255, 80, 80, 0.2); }
  100% { box-shadow: 0 0 0 transparent; }
}

/* Cash floater - drifts up + fades when cash changes. */
.cash-float {
  position: fixed;
  transform: translate(-50%, 0);
  font-family: var(--mono);
  font-size: 22px;
  font-weight: bold;
  text-shadow: 0 0 6px currentColor;
  pointer-events: none;
  z-index: 300;
  animation: cash-float 1.4s ease-out forwards;
  letter-spacing: 1px;
}
@keyframes cash-float {
  0%   { opacity: 0; transform: translate(-50%, 6px); }
  20%  { opacity: 1; transform: translate(-50%, -8px); }
  100% { opacity: 0; transform: translate(-50%, -54px); }
}

/* Three-strand power cable - each strand animates at a different speed
   and phase so electricity appears to flow. */
.power-strand { stroke-linecap: round; }
.strand-a { animation: bus-pulse 1.2s linear infinite; }
.strand-b { animation: bus-pulse 1.6s linear infinite; animation-delay: -0.4s; }
.strand-c { animation: bus-pulse 1.4s linear infinite; animation-delay: -0.8s; }
@keyframes bus-pulse {
  0%   { stroke-dashoffset:   0; opacity: 0.45; }
  50%  { stroke-dashoffset: -10; opacity: 0.95; }
  100% { stroke-dashoffset: -20; opacity: 0.45; }
}

/* Rack status LEDs - staggered blink rates so each rack looks alive. */
.rack-led { filter: drop-shadow(0 0 1.5px currentColor); }
.led-fast     { animation: led-blink 0.8s steps(2, end) infinite; }
.led-mid      { animation: led-blink 1.4s steps(2, end) infinite; animation-delay: -0.3s; }
.led-slow     { animation: led-blink 2.6s steps(2, end) infinite; animation-delay: -0.7s; }
.led-power    { animation: led-pulse 2.0s ease-in-out infinite; }
.led-network  { animation: led-blink 1.1s steps(2, end) infinite; animation-delay: -0.5s; }
.led-activity { animation: led-flicker 0.5s steps(2, end) infinite; animation-delay: -0.2s; }
.led-warn     { animation: led-rare 4.0s ease-in-out infinite; animation-delay: -1.5s; }
@keyframes led-blink {
  0%, 49%   { opacity: 1; }
  50%, 100% { opacity: 0.2; }
}
@keyframes led-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.5; }
}
@keyframes led-flicker {
  0%, 10%, 30%, 60%, 100% { opacity: 1; }
  15%, 25%, 65%, 80%      { opacity: 0.3; }
}
@keyframes led-rare {
  0%, 90%, 100% { opacity: 0.4; }
  93%, 97%      { opacity: 1; }
}

/* Live drop overlay during runDay - pinned to scene top-right so the
   running served + lost counts are HUGE and unmissable. */
.drop-overlay {
  position: absolute;
  top: 8px; right: 8px;
  background: rgba(5, 10, 7, 0.85);
  border: 1px solid var(--border);
  padding: 8px 12px;
  font-family: var(--mono);
  text-align: right;
  line-height: 1.3;
  pointer-events: none;
  z-index: 30;
  text-shadow: 0 0 4px currentColor;
}
.scene { position: relative; }
.drop-served { color: var(--fg-bright); font-size: 13px; letter-spacing: 1px; }
.drop-lost   { color: var(--bad); font-size: 18px; letter-spacing: 1px; font-weight: bold; margin-top: 4px; }
.drop-overlay.drop-flash { animation: drop-flash-anim 0.35s ease-out; }
@keyframes drop-flash-anim {
  0%   { background: rgba(5, 10, 7, 0.85);  transform: scale(1); }
  30%  { background: rgba(255, 80, 80, 0.4); transform: scale(1.06); }
  100% { background: rgba(5, 10, 7, 0.85);  transform: scale(1); }
}
.drop-overlay.drop-final {
  border-color: var(--bad);
  box-shadow: 0 0 18px rgba(255, 80, 80, 0.45);
}

/* Combined Day Close card: replaces the old day-log + news-card duo with a
   single end-of-day artifact - BREAKING strip on event days, 3-column
   BOOKS / PLANT / QUEUE grid, bottom strip with hint + cash + NEXT DAY.
   Animations + sfx are staged in JS (showDayClose). */
.day-close-wrap {
  position: fixed;
  inset: 0;
  background: rgba(2, 5, 3, 0.82);
  backdrop-filter: blur(4px);
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 12px;
  animation: dc-fade-in 0.22s ease-out;
}
.day-close-wrap[hidden] { display: none; }
@keyframes dc-fade-in {
  0%   { opacity: 0; }
  100% { opacity: 1; }
}
.day-close-card {
  position: relative;
  background: var(--bg-panel);
  border: 1px solid var(--fg);
  box-shadow: 0 0 32px rgba(70, 240, 138, 0.4);
  width: 100%;
  max-width: 760px;
  max-height: 92vh;
  overflow-y: auto;
  padding: 0;
  animation: dc-card-in 0.32s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes dc-card-in {
  0%   { transform: scale(0.9) translateY(12px); opacity: 0; }
  100% { transform: scale(1) translateY(0);      opacity: 1; }
}
.day-close-card.dc-shake { animation: dc-card-shake 0.22s ease-out; }
@keyframes dc-card-shake {
  0%, 100% { transform: translate(0, 0); }
  20%      { transform: translate(-3px, 1px); }
  40%      { transform: translate(3px, -1px); }
  60%      { transform: translate(-2px, 1px); }
  80%      { transform: translate(2px, -1px); }
}

/* BREAKING strip at top of card. Only rendered on news-event days. */
.day-close-breaking {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border-bottom: 1px dashed var(--border);
  background: rgba(240, 200, 70, 0.04);
}
.day-close-breaking[hidden] { display: none; }
.day-close-breaking.dc-breaking-in .dc-breaking-art { animation: dc-breaking-zoom 0.34s cubic-bezier(0.34, 1.56, 0.64, 1); }
@keyframes dc-breaking-zoom {
  0%   { transform: scale(1.1); opacity: 0.4; }
  100% { transform: scale(1);   opacity: 1; }
}
.dc-breaking-art {
  width: 64px;
  height: 52px;
  flex-shrink: 0;
  filter: drop-shadow(0 0 4px rgba(240, 200, 70, 0.4));
}
.dc-breaking-text { flex: 1; min-width: 0; }
.dc-breaking-tag {
  display: inline-block;
  color: var(--warn);
  font-size: var(--t-dim);
  letter-spacing: 3px;
  font-weight: bold;
  margin-bottom: 4px;
  animation: tag-blink 1.2s ease-in-out infinite;
}
.dc-breaking-tag.curtail { color: var(--bad); }
.dc-breaking-tag.inspect { color: var(--bad); }
.dc-breaking-headline {
  color: var(--fg-bright);
  font-size: var(--t-hero);
  line-height: 1.25;
  letter-spacing: 0.5px;
  min-height: 1.25em;
}

/* 3-column grid: BOOKS / PLANT / QUEUE. Net column dividers are 1px dashed. */
.day-close-grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 0;
}
@media (max-width: 560px) {
  .day-close-grid { grid-template-columns: 1fr; }
}
.dc-col {
  padding: 12px 14px;
  border-right: 1px dashed var(--border);
  min-width: 0;
}
.dc-col:last-child { border-right: none; }
@media (max-width: 560px) {
  .dc-col { border-right: none; border-bottom: 1px dashed var(--border); }
  .dc-col:last-child { border-bottom: none; }
}
.dc-col-head {
  color: var(--fg-dim);
  font-size: var(--t-dim);
  letter-spacing: 3px;
  font-weight: bold;
  margin-bottom: 8px;
  text-shadow: none;
}
.dc-rows { list-style: none; padding: 0; margin: 0; }
.dc-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  padding: 2px 0;
  font-size: var(--t-base);
}
.dc-row-label {
  color: var(--fg-dim);
  font-size: var(--t-dim);
  letter-spacing: 1px;
}
.dc-row-val {
  color: var(--fg-bright);
  font-family: var(--mono);
  font-size: var(--t-base);
  text-align: right;
}
.dc-row-bad .dc-row-val { color: var(--bad); }
.dc-row-warn .dc-row-val { color: var(--warn); }
.dc-row-slam { animation: dc-row-slam-anim 0.18s ease-out; }
@keyframes dc-row-slam-anim {
  0%   { transform: translateX(-6px); opacity: 0; }
  100% { transform: translateX(0);    opacity: 1; }
}
.dc-divider {
  margin: 8px 0 6px;
  border-top: 1px dashed var(--border);
}
.dc-net {
  color: var(--fg-bright);
  font-size: var(--t-hero);
  font-weight: bold;
  letter-spacing: 1.5px;
  text-align: center;
  /* No text-shadow stacking: rely on the body-level crt glow only. */
}
.dc-net.good { color: var(--good); }
.dc-net.bad  { color: var(--bad); }
.dc-net-sub {
  color: var(--fg-dim);
  font-size: var(--t-dim);
  letter-spacing: 1px;
  text-align: center;
  margin-top: 2px;
}
.dc-foot {
  font-size: var(--t-dim);
  color: var(--fg-dim);
  letter-spacing: 0.5px;
}
.dc-foot .dc-foot-row1 { color: var(--fg); font-size: var(--t-base); }
.dc-foot .dc-foot-row2 { color: var(--fg-dim); }
.dc-foot .dc-foot-row2.warn { color: var(--warn); }

/* Bottom strip: hint + cash total + NEXT DAY (tomorrow headline embedded). */
.day-close-foot {
  padding: 10px 14px 12px;
  border-top: 1px dashed var(--border);
}
.dc-hint {
  color: var(--fg-dim);
  font-size: var(--t-dim);
  letter-spacing: 0.5px;
  min-height: 1.4em;
  margin-bottom: 6px;
}
.dc-foot-row {
  display: flex;
  align-items: center;
  gap: 10px;
}
.dc-cash {
  color: var(--fg-bright);
  font-size: var(--t-emph);
  font-weight: bold;
  letter-spacing: 1px;
  flex: 1 1 auto;
}
.dc-next {
  font-size: var(--t-base);
  letter-spacing: 1.5px;
  padding: 10px 18px;
  border: 2px solid var(--fg-bright);
  color: var(--fg-bright);
  background: var(--bg-panel);
  min-height: 44px;
  cursor: pointer;
  font-family: var(--mono);
  /* Avoid stacking bold + bright + glow: chrome is the border, not text-shadow. */
}
.dc-next:hover { background: var(--fg-bright); color: var(--bg); }

/* Personal-best ribbon. Slides in from the corner after NET settles. */
.dc-ribbon {
  position: absolute;
  top: 8px;
  right: 8px;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  padding: 6px 10px;
  background: var(--bg-deep);
  border: 1px solid var(--gold);
  box-shadow: 0 0 14px rgba(255, 208, 102, 0.55);
  pointer-events: none;
}
.dc-ribbon[hidden] { display: none; }
.dc-ribbon-in { animation: dc-ribbon-slide 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); }
@keyframes dc-ribbon-slide {
  0%   { transform: translateX(120%); opacity: 0; }
  100% { transform: translateX(0);    opacity: 1; }
}
.dc-ribbon-tag {
  color: var(--gold);
  font-size: var(--t-dim);
  letter-spacing: 2px;
  font-weight: bold;
}
.dc-ribbon-text {
  color: var(--fg-bright);
  font-size: var(--t-base);
}

/* Inline toast used by flashLog() for bail-out messages (replaces the old
   day-log warn re-use). */
.ii-toast {
  position: fixed;
  top: 12px;
  left: 50%;
  transform: translateX(-50%);
  padding: 8px 14px;
  background: var(--bg-panel);
  border: 1px solid var(--bad);
  color: var(--bad);
  font-family: var(--mono);
  font-size: var(--t-base);
  z-index: 300;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease-out;
}
.ii-toast.show { opacity: 1; }

/* BREAKING news event card. Fullscreen overlay with a big sprite + headline
   + effect line + dismiss button. One sprite per event keyed by news.icon. */
.news-card-wrap {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(2, 5, 3, 0.86);
  backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  animation: news-fade-in 0.25s ease-out;
}
.news-card-wrap[hidden] { display: none; }
@keyframes news-fade-in {
  0%   { opacity: 0; }
  100% { opacity: 1; }
}
.news-card {
  background: var(--bg-panel);
  border: 2px solid var(--warn);
  width: 100%;
  max-width: 560px;
  padding: 18px 22px;
  box-shadow: 0 0 36px rgba(240, 200, 70, 0.5);
  animation: news-slide-in 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes news-slide-in {
  0%   { transform: scale(0.85) translateY(20px); opacity: 0; }
  100% { transform: scale(1) translateY(0); opacity: 1; }
}
.news-card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px dashed var(--border);
  padding-bottom: 8px;
  margin-bottom: 14px;
}
.news-card-tag {
  color: var(--warn);
  font-size: 12px;
  letter-spacing: 3px;
  font-weight: bold;
  animation: tag-blink 1.2s ease-in-out infinite;
}
.news-card-tag.curtail { color: var(--bad); }
.news-card-tag.inspect { color: var(--bad); }
.news-card-tag.forecast { color: var(--fg-dim); animation: none; }
@keyframes tag-blink {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.55; }
}
.news-card-body {
  display: flex;
  align-items: center;
  gap: 18px;
  margin-bottom: 16px;
}
.news-card-art {
  width: 140px;
  height: 110px;
  flex-shrink: 0;
  filter: drop-shadow(0 0 6px rgba(70, 240, 138, 0.35));
}
.news-card-text { flex: 1; min-width: 0; }
.news-card-headline {
  color: var(--fg-bright);
  font-size: 15px;
  line-height: 1.4;
  margin-bottom: 10px;
  text-shadow: 0 0 4px currentColor;
}
.news-card-effect {
  color: var(--warn);
  font-size: 12px;
  letter-spacing: 1.5px;
  padding: 6px 8px;
  border-left: 3px solid var(--warn);
  background: rgba(240, 200, 70, 0.06);
}
.news-card-close {
  display: block;
  width: 100%;
  padding: 12px;
  font-size: 14px;
  letter-spacing: 2px;
  background: var(--bg-panel);
  color: var(--fg-bright);
  border: 2px solid var(--fg-bright);
}
.news-card-close:hover {
  background: var(--fg-bright);
  color: var(--bg);
}

@media (max-width: 520px) {
  .news-card-body { flex-direction: column; }
  .news-card-art { width: 100%; height: 120px; }
}

/* Leaderboard scope tabs: TODAY (daily-seed bucket) + ALL-TIME. */
.lb-tabs {
  display: flex;
  gap: 4px;
  margin: 0 0 8px;
  border-bottom: 1px solid var(--border);
}
.lb-tab {
  font-family: var(--mono);
  font-size: var(--t-base);
  letter-spacing: 2px;
  background: transparent;
  color: var(--fg-dim);
  border: 1px solid var(--border);
  border-bottom: none;
  padding: 8px 14px;
  min-height: 36px;
  cursor: pointer;
  text-shadow: inherit;
}
.lb-tab:hover { color: var(--fg); }
.lb-tab.is-active {
  color: var(--fg-bright);
  border-color: var(--fg-bright);
  background: var(--bg-panel);
}
