/* Copyright (c) 2026 Dr. Jason Cross. All rights reserved. */
:root {
  color-scheme: light dark;
  --bg: #0f1420;
  --panel: #1a2233;
  --border: #2c3650;
  --text: #e6e9f0;
  --muted: #93a0bd;
  /* Validated status/categorical palette (dataviz skill reference instance),
     dark-mode steps since this app renders a single fixed dark theme.
     Status colors (good/warning/serious/critical) are mode-invariant by spec. */
  --accent: #3987e5;   /* categorical slot 1 (blue) - "Supply", neutral news, links */
  --aqua: #199e70;     /* categorical slot 2 (aqua) - "Demand" */
  --good: #0ca30c;
  --warning: #fab219;
  --serious: #ec835a;
  --critical: #d03b3b;
  --bad: var(--critical);
  --warn: var(--warning);
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  min-height: 100vh;
}

.hidden { display: none !important; }

.site-footer {
  text-align: center;
  color: var(--muted);
  font-size: 0.8rem;
  padding: 1.5rem 1rem 2rem;
}

/* Round-start quiz gate: a full-screen blocking overlay - trading is also
   blocked server-side (require_quiz_complete), this is just the UI half. */
.quiz-overlay {
  position: fixed;
  inset: 0;
  background: rgba(6, 9, 16, 0.92);
  z-index: 9000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  overflow-y: auto;
}
.quiz-card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 16px;
  max-width: 560px;
  width: 100%;
  padding: 2rem 2.25rem;
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.5);
}
.quiz-heading { font-size: 1.3rem; margin: 0 0 1.25rem; text-align: center; color: var(--accent); }
.quiz-progress { font-size: 0.85rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 0.5rem; }
.quiz-question { font-size: 1.3rem; margin: 0 0 1.25rem; line-height: 1.4; }
.quiz-choices { display: flex; flex-direction: column; gap: 0.6rem; }
.quiz-choice-btn {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--border);
  color: var(--text);
  text-align: left;
  padding: 0.75rem 1rem;
  font-weight: 500;
  border-radius: 8px;
}
.quiz-choice-btn:hover { background: rgba(57, 135, 229, 0.15); border-color: var(--accent); }
.quiz-feedback { margin-top: 1.1rem; }
.quiz-feedback-correct { color: var(--good); font-weight: 700; font-size: 1.1rem; }
.quiz-feedback-wrong { color: var(--bad); margin-bottom: 0.75rem; line-height: 1.5; }
.quiz-reflection-prompt { font-size: 1.1rem; line-height: 1.5; margin-bottom: 1rem; }
.quiz-reflection-input { width: 100%; box-sizing: border-box; padding: 0.75rem; border-radius: 8px; border: 1px solid var(--border); background: #0f1420; color: var(--text); font-family: inherit; font-size: 0.95rem; resize: vertical; }
.quiz-reflection-error { color: var(--bad); font-size: 0.85rem; min-height: 1.2em; margin: 0.5rem 0; }

#join-screen {
  max-width: 420px;
  margin: 10vh auto;
  padding: 2rem;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
}

#join-screen h1 { margin-top: 0; font-size: 1.4rem; }

label { display: block; margin: 1rem 0 0.25rem; font-size: 0.85rem; color: var(--muted); }

input {
  width: 100%;
  padding: 0.6rem 0.75rem;
  background: #0f1420;
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text);
  font-size: 1rem;
}

input:focus { outline: 2px solid var(--accent); }

button {
  cursor: pointer;
  border: none;
  border-radius: 8px;
  padding: 0.6rem 1rem;
  font-size: 0.95rem;
  font-weight: 600;
  background: var(--accent);
  color: white;
}

button:disabled { opacity: 0.5; cursor: not-allowed; }
button.secondary { background: transparent; border: 1px solid var(--border); color: var(--text); }
button.small { padding: 0.3rem 0.6rem; font-size: 0.85rem; }

#join-submit { width: 100%; margin-top: 1.25rem; }

#error-banner {
  color: var(--bad);
  font-size: 0.85rem;
  margin-top: 0.75rem;
  min-height: 1.2em;
}

#game-screen { max-width: 1100px; margin: 0 auto; padding: 1.25rem; }

.topbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1.25rem;
}

.topbar .stat { font-size: 0.9rem; color: var(--muted); }
.topbar .stat strong { color: var(--text); font-size: 1.1rem; }

.grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
@media (max-width: 800px) { .grid { grid-template-columns: 1fr; } }

.panel {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 1rem 1.25rem;
  margin-bottom: 1rem;
}

.panel h2 { margin: 0 0 0.75rem; font-size: 1rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; }

table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
th { text-align: left; color: var(--muted); font-weight: 500; padding: 0.4rem; border-bottom: 1px solid var(--border); }
td { padding: 0.5rem 0.4rem; border-bottom: 1px solid var(--border); }
tr:last-child td { border-bottom: none; }

.req-satisfied { color: var(--good); }
.req-missing { color: var(--bad); }

.qty-input { width: 3.5rem; padding: 0.3rem; }

.order-panel {
  border-top: 3px solid var(--accent);
  background: linear-gradient(180deg, rgba(57, 135, 229, 0.08), transparent 45%), var(--panel);
}

.order-hero { display: flex; gap: 1.5rem; align-items: center; margin-bottom: 1.1rem; }
.order-hero-media { flex: 0 0 220px; }
.order-vehicle-image {
  width: 220px;
  height: 150px;
  object-fit: contain;
  background: radial-gradient(ellipse at center, rgba(255, 255, 255, 0.06), transparent 70%);
  filter: drop-shadow(0 10px 18px rgba(0, 0, 0, 0.5));
}
.order-hero-info { flex: 1; min-width: 0; }
.order-vehicle-name { font-size: 1.5rem; font-weight: 700; margin-bottom: 0.5rem; }

@media (max-width: 700px) {
  .order-hero { flex-direction: column; }
  .order-hero-media { flex: 0 0 auto; width: 100%; display: flex; justify-content: center; }
}

.order-economics { display: flex; gap: 0.6rem; flex-wrap: wrap; margin-bottom: 0.9rem; }
.order-stat {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.45rem 0.8rem;
}
.order-stat-label { display: block; font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); margin-bottom: 0.15rem; }
.order-stat-value { font-size: 1.1rem; font-weight: 700; }
.order-stat-value.profit-positive { color: var(--good); }
.order-stat-value.profit-negative { color: var(--bad); }

.order-progress-track {
  height: 8px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.07);
  overflow: hidden;
}
.order-progress-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--aqua), var(--good));
  transition: width 0.35s ease;
}
.order-progress-label { margin-top: 0.4rem; font-size: 0.82rem; color: var(--muted); }

.order-parts { border-top: 1px solid var(--border); padding-top: 0.75rem; }
.order-parts-head,
.order-part-row {
  display: grid;
  grid-template-columns: 1.7fr 0.55fr 0.55fr 0.85fr 0.9fr;
  gap: 0.5rem;
  align-items: center;
}
.order-parts-head {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  padding: 0 0.6rem 0.5rem;
}
.order-part-row {
  padding: 0.55rem 0.6rem;
  border-radius: 8px;
  font-size: 0.92rem;
}
.order-part-row:nth-child(odd) { background: rgba(255, 255, 255, 0.025); }
.order-part-row.is-ready .part-name { color: var(--text); }
.order-part-name { display: flex; align-items: center; gap: 0.45rem; font-weight: 500; }

.status-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 600;
  white-space: nowrap;
}
.status-chip.ready { background: rgba(12, 163, 12, 0.16); color: var(--good); }
.status-chip.missing { background: rgba(208, 59, 59, 0.16); color: var(--bad); }

.build-btn { width: 100%; margin-top: 1.1rem; }

@media (max-width: 560px) {
  .order-parts-head, .order-part-row { grid-template-columns: 1.4fr 0.5fr 0.5fr 0.7fr; }
  .order-parts-head span:nth-child(4), .order-part-row .order-part-price { display: none; }
}

.price-above-base { color: var(--bad); }
.price-below-base { color: var(--good); }
.demand-some { color: var(--warn); font-weight: 600; }
.demand-exceeds { color: var(--bad); font-weight: 700; }

.request-controls { display: flex; flex-direction: column; gap: 0.3rem; align-items: flex-start; }

/* Groups every part's unit rows visually - the stats row is the "header" for
   its own product group, so it needs to read as distinct from the rows above
   (a different part) as much as from its own factory/peer rows below. */
.stats-row td { background: rgba(255, 255, 255, 0.07); }

/* Shared by Market and Inventory: each group of rows (a part, in either
   table) is one rounded, accent-striped "card". border-collapse:separate is
   required for border-radius to render on td corners at all (the default
   collapsed border model clips it), and every row in the group shares a
   left-edge accent stripe + top/bottom border so the whole run of rows reads
   as one contiguous block instead of a flat, undifferentiated row list. */
.card-table { border-collapse: separate; border-spacing: 0; }
.card-table tbody tr td:first-child { border-left: 3px solid var(--accent); }
.card-table tbody tr td:last-child { border-right: 1px solid var(--border); }
.card-table tbody tr td { border-top: 1px solid var(--border); border-bottom: none; transition: background-color 0.12s ease; }
.card-table tbody tr:not(.group-start) td { border-top: none; }
.card-table tbody tr.group-end td { border-bottom: 1px solid var(--border); }
.card-table tbody tr.group-start td:first-child { border-top-left-radius: 10px; }
.card-table tbody tr.group-start td:last-child { border-top-right-radius: 10px; }
.card-table tbody tr.group-end td:first-child { border-bottom-left-radius: 10px; }
.card-table tbody tr.group-end td:last-child { border-bottom-right-radius: 10px; }
.card-table tbody tr:hover td { background-color: rgba(255, 255, 255, 0.05); }
.card-table .group-spacer td { border: none; padding: 5px 0; background: transparent; }

.panel-subtitle { text-transform: none; letter-spacing: normal; font-size: 0.8rem; color: var(--muted); font-weight: 400; }
.subsection { font-size: 0.85rem; color: var(--muted); margin: 1rem 0 0.5rem; text-transform: uppercase; letter-spacing: 0.03em; }

.peer-row { background: rgba(79, 140, 255, 0.06); font-size: 0.85rem; }
.factory-row { background: rgba(255, 255, 255, 0.03); }
.peer-indent { padding-left: 1.5rem; color: var(--muted); }
.peer-price { color: var(--accent); font-weight: 600; }
.peer-tag {
  display: inline-block;
  margin-left: 0.4rem;
  padding: 0.05rem 0.4rem;
  border-radius: 999px;
  background: rgba(79, 140, 255, 0.15);
  color: var(--accent);
  font-size: 0.7rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}
.list-controls { display: flex; align-items: center; gap: 0.35rem; white-space: nowrap; }
.price-input { width: 4.5rem; padding: 0.3rem; }

.confetti-container { position: fixed; inset: 0; pointer-events: none; overflow: hidden; z-index: 9999; }
.confetti-piece {
  position: absolute;
  top: -12px;
  width: 8px;
  height: 14px;
  opacity: 0.9;
  animation-name: confetti-fall;
  animation-timing-function: ease-in;
  animation-fill-mode: forwards;
}
@keyframes confetti-fall {
  0% { transform: translateY(0) rotate(0deg); opacity: 1; }
  100% { transform: translateY(105vh) rotate(540deg); opacity: 0.85; }
}

.completion-popup {
  position: fixed;
  top: 38%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: var(--panel);
  border: 2px solid var(--good);
  color: var(--text);
  font-size: 1.8rem;
  font-weight: 800;
  padding: 1.25rem 2.25rem;
  border-radius: 16px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
  z-index: 10000;
  opacity: 1;
  transition: opacity 0.6s ease;
}
.completion-popup.fade-out { opacity: 0; }

.complete-banner {
  background: rgba(62, 207, 142, 0.15);
  border: 1px solid var(--good);
  border-radius: 8px;
  padding: 0.75rem;
  margin-bottom: 0.75rem;
  font-size: 0.9rem;
}

.part-icon { display: inline-block; margin-right: 0.3rem; }

/* --- Scarcity meter: fill hue carries severity (critical -> serious ->
   warning -> good), unfilled track stays a fixed light neutral so state
   reads from the fill alone. --- */
.meter-cell { min-width: 7rem; }
.meter-label {
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  margin-bottom: 0.2rem;
}
.meter-track {
  height: 8px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.14);
  overflow: hidden;
}
.meter-fill { height: 100%; border-radius: 999px; transition: width 0.3s ease; }
/* Track tint matches the fill's own hue (per dataviz meter spec: "lighter step
   of the same ramp") so the filled/unfilled boundary is always visible - a flat
   near-invisible track made every fill level look the same at a glance. */
.meter-very_scarce .meter-label, .meter-very_scarce .meter-fill { color: var(--critical); background: var(--critical); }
.meter-very_scarce .meter-track { background: rgba(208, 59, 59, 0.18); }
.meter-scarce .meter-label, .meter-scarce .meter-fill { color: var(--serious); background: var(--serious); }
.meter-scarce .meter-track { background: rgba(236, 131, 90, 0.18); }
.meter-balanced .meter-label, .meter-balanced .meter-fill { color: var(--warning); background: var(--warning); }
.meter-balanced .meter-track { background: rgba(250, 178, 25, 0.18); }
.meter-surplus .meter-label, .meter-surplus .meter-fill,
.meter-abundant .meter-label, .meter-abundant .meter-fill { color: var(--good); background: var(--good); }
.meter-surplus .meter-track, .meter-abundant .meter-track { background: rgba(12, 163, 12, 0.18); }
.meter-no_demand .meter-label { color: var(--muted); }
.meter-no_demand .meter-fill { background: var(--muted); }

/* --- Supply vs demand dual bar: fixed categorical hues, Supply=blue, Demand=aqua --- */
.sd-bars { display: flex; flex-direction: column; gap: 0.25rem; min-width: 6.5rem; }
.sd-row { display: flex; align-items: center; gap: 0.35rem; font-size: 0.68rem; color: var(--muted); }
.sd-row-label { width: 3.2rem; flex-shrink: 0; }
.sd-track {
  flex: 1;
  height: 6px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.14);
  overflow: hidden;
}
/* display:block is required here - .sd-fill is a <span> nested inside
   .sd-track (not a direct flex child, so it never gets auto-blockified),
   and `width` has no effect on inline elements per the CSS spec. Without
   this every fill bar silently ignored its computed width and rendered at
   a fixed default size regardless of the actual supply/demand numbers. */
.sd-fill { display: block; height: 100%; border-radius: 999px; }
.sd-fill.supply { background: var(--accent); }
.sd-fill.demand { background: var(--aqua); }
.sd-fill.hoarded { background: var(--serious); }
.sd-row-hoarded { color: var(--serious); }
.sd-row-hoarded .sd-value { color: var(--serious); }
.sd-row-empty { visibility: hidden; }
.sd-value { width: 1.4rem; text-align: right; font-weight: 600; color: var(--text); }

/* Game-specific hover explanations on the scarcity meter and supply/demand
   bars - text content is chosen per-row in JS (bucket/relationship aware),
   this just handles the popup chrome. */
[data-tooltip] { position: relative; cursor: help; }
[data-tooltip]::after {
  content: attr(data-tooltip);
  position: absolute;
  bottom: calc(100% + 10px);
  left: 0;
  width: 230px;
  background: #0a0e18;
  color: var(--text);
  border: 1px solid var(--border);
  padding: 0.65rem 0.8rem;
  border-radius: 8px;
  font-size: 0.78rem;
  font-weight: 400;
  line-height: 1.42;
  white-space: normal;
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.5);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.15s ease;
  z-index: 60;
}
[data-tooltip]:hover::after, [data-tooltip]:focus-visible::after {
  opacity: 1;
  visibility: visible;
}

.panel-hint { margin: -0.4rem 0 0.9rem; font-size: 0.85rem; color: var(--muted); }

.trend-up { color: var(--critical); }
.trend-down { color: var(--good); }
.trend-flat { color: var(--muted); }

.sparkline { display: block; vertical-align: middle; }
.sparkline-line { fill: none; stroke: var(--muted); stroke-width: 1.5; stroke-linejoin: round; stroke-linecap: round; }
.sparkline-dot { fill: var(--accent); }

.how-it-works { border-top: 3px solid var(--accent); }
.how-it-works p { margin: 0.4rem 0; font-size: 0.95rem; line-height: 1.5; color: var(--text); }
.how-it-works p:first-of-type { margin-top: 0; }

.market-part-name { font-size: 1.05rem; font-weight: 700; }
/* Seller identifier on factory/peer rows - deliberately NOT styled like
   market-part-name (bold, larger), so it reads as "who's selling this" at
   the same visual weight as the price, not as if it were the part name. */
.seller-name { font-weight: 400; font-size: 0.85rem; }
.sold-out-tag {
  display: block;
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--bad);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  margin-bottom: 0.25rem;
}
.pending-note { font-size: 0.72rem; color: var(--muted); margin-top: 0.3rem; }
