/* theme.css — dark terminal theme for Ad Hoc Markets v2.
   One stylesheet for all pages. Monospace numerics, green/amber accents on
   near-black, readable on a projector. No external fonts or assets. */

:root {
  --bg: #0a0e14;
  --bg-panel: #111820;
  --bg-panel-2: #0d141c;
  --bg-hover: #1a2230;
  --bg-input: #0c1219;
  --border: #1e2a3a;
  --border-bright: #2c3d52;
  --text: #c5cdd8;
  --text-dim: #5c6a7a;
  --text-bright: #e8edf3;
  --green: #00d67e;
  --green-dim: rgba(0, 214, 126, 0.2);
  --red: #ff4d6a;
  --red-dim: rgba(255, 77, 106, 0.2);
  --blue: #4da6ff;
  --blue-dim: rgba(77, 166, 255, 0.2);
  --amber: #ffcc00;
  --amber-dim: rgba(255, 204, 0, 0.18);
  --font: "SF Mono", "Fira Code", "JetBrains Mono", "Consolas", ui-monospace, monospace;
  --radius: 6px;
  --gap: 8px;
}

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

html, body {
  height: 100%;
}

body {
  font-family: var(--font);
  background: var(--bg);
  color: var(--text);
  font-size: 13px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--blue); text-decoration: none; }
a:hover { text-decoration: underline; }

.mono { font-variant-numeric: tabular-nums; font-feature-settings: "tnum"; }
.pos { color: var(--green); }
.neg { color: var(--red); }
.flat { color: var(--text); }
.dim { color: var(--text-dim); }
.bright { color: var(--text-bright); }
.amber { color: var(--amber); }
.blue { color: var(--blue); }
.right { text-align: right; }
.center { text-align: center; }
.nowrap { white-space: nowrap; }
.hidden { display: none !important; }
.grow { flex: 1; }
.muted-sm { font-size: 11px; color: var(--text-dim); }

/* ---------- Layout scaffolding ---------- */
.app { display: flex; min-height: 100vh; }

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 10px 18px;
  background: var(--bg-panel);
  border-bottom: 1px solid var(--border);
}
.topbar h1 { font-size: 15px; color: var(--text-bright); font-weight: 700; letter-spacing: 0.5px; }
.topbar .brand { display: flex; align-items: center; gap: 10px; }
.topbar .spacer { flex: 1; }

.dash { display: flex; flex: 1; min-height: 0; }

.sidebar {
  width: 210px;
  flex-shrink: 0;
  background: var(--bg-panel);
  border-right: 1px solid var(--border);
  padding: 12px 8px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.sidebar-item {
  padding: 9px 14px;
  border-radius: var(--radius);
  color: var(--text-dim);
  cursor: pointer;
  font-size: 13px;
  user-select: none;
  display: flex;
  align-items: center;
  gap: 8px;
}
.sidebar-item:hover { background: var(--bg-hover); color: var(--text); }
.sidebar-item.active { background: var(--blue-dim); color: var(--blue); font-weight: 600; }
.sidebar .spacer { flex: 1; }

.content { flex: 1; padding: 20px 24px; overflow-y: auto; min-width: 0; }
.page { max-width: 1200px; }
.page-title { font-size: 20px; color: var(--text-bright); font-weight: 700; margin-bottom: 4px; }
.page-sub { color: var(--text-dim); margin-bottom: 18px; font-size: 12px; }
.dash-page { display: none; }
.dash-page.active { display: block; }

/* ---------- Panels ---------- */
.panel {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.panel-header {
  padding: 8px 12px;
  border-bottom: 1px solid var(--border);
  font-weight: 600;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--text-dim);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.panel-body { padding: 12px 14px; overflow-y: auto; flex: 1; min-height: 0; }
.panel-body.flush { padding: 0; }

.card {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px;
}
.card + .card { margin-top: 12px; }

/* ---------- Buttons ---------- */
.btn {
  font-family: var(--font);
  font-size: 12px;
  padding: 7px 14px;
  border-radius: var(--radius);
  border: 1px solid var(--border-bright);
  background: var(--bg-hover);
  color: var(--text);
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
  white-space: nowrap;
}
.btn:hover { background: var(--bg-panel-2); border-color: var(--blue); color: var(--text-bright); }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }
.btn-primary { background: var(--green-dim); border-color: var(--green); color: var(--green); font-weight: 600; }
.btn-primary:hover { background: rgba(0, 214, 126, 0.32); color: var(--text-bright); }
.btn-secondary { background: var(--bg-hover); border-color: var(--border-bright); }
.btn-sm { padding: 5px 10px; font-size: 11px; }
.btn-xs { padding: 3px 8px; font-size: 10px; }
.btn-danger { border-color: var(--red); color: var(--red); background: transparent; }
.btn-danger:hover { background: var(--red-dim); color: var(--text-bright); }
.btn-buy { background: var(--green-dim); border-color: var(--green); color: var(--green); }
.btn-buy:hover { background: rgba(0, 214, 126, 0.34); }
.btn-buy.active { background: var(--green); color: #04120b; font-weight: 700; }
.btn-sell { background: var(--red-dim); border-color: var(--red); color: var(--red); }
.btn-sell:hover { background: rgba(255, 77, 106, 0.34); }
.btn-sell.active { background: var(--red); color: #1a0409; font-weight: 700; }
.btn-block { width: 100%; }
.btn-amber { border-color: var(--amber); color: var(--amber); background: var(--amber-dim); }
.btn-amber:hover { background: rgba(255, 204, 0, 0.3); color: var(--text-bright); }

.btn-row { display: flex; gap: 8px; flex-wrap: wrap; }

/* ---------- Forms ---------- */
label { display: block; font-size: 11px; color: var(--text-dim); margin-bottom: 4px; text-transform: uppercase; letter-spacing: 0.5px; }
input, select, textarea {
  font-family: var(--font);
  font-size: 13px;
  background: var(--bg-input);
  border: 1px solid var(--border-bright);
  color: var(--text-bright);
  border-radius: var(--radius);
  padding: 8px 10px;
  width: 100%;
}
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--blue); }
input::placeholder, textarea::placeholder { color: var(--text-dim); }
textarea { resize: vertical; min-height: 60px; }
.field { margin-bottom: 14px; }
.field .hint { font-size: 11px; color: var(--text-dim); margin-top: 4px; text-transform: none; letter-spacing: 0; }
.field-row { display: flex; gap: 12px; flex-wrap: wrap; }
.field-row > .field { flex: 1; min-width: 120px; }
.inline-check { display: flex; align-items: center; gap: 8px; }
.inline-check input { width: auto; }
.inline-check label { margin: 0; text-transform: none; letter-spacing: 0; }
.input-prefix { position: relative; }
.input-prefix > span { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); color: var(--text-dim); }
.input-prefix > input { padding-left: 22px; }

/* ---------- Tables ---------- */
table.data { width: 100%; border-collapse: collapse; font-size: 12px; }
table.data th {
  text-align: left; color: var(--text-dim); font-weight: 500; padding: 6px 8px;
  border-bottom: 1px solid var(--border); font-size: 10px; text-transform: uppercase; letter-spacing: 0.5px;
}
table.data td { padding: 6px 8px; border-bottom: 1px solid var(--border); }
table.data tr:hover td { background: var(--bg-hover); }
table.data td.num, table.data th.num { text-align: right; font-variant-numeric: tabular-nums; }

/* ---------- Status pills ---------- */
.pill {
  font-size: 10px; padding: 2px 9px; border-radius: 11px; text-transform: uppercase;
  letter-spacing: 0.6px; font-weight: 600; display: inline-block;
}
.pill.draft { background: var(--bg-hover); color: var(--text-dim); }
.pill.lobby { background: var(--blue-dim); color: var(--blue); }
.pill.active { background: var(--green-dim); color: var(--green); }
.pill.paused { background: var(--amber-dim); color: var(--amber); }
.pill.ended { background: var(--red-dim); color: var(--red); }
.pill.finished { background: var(--red-dim); color: var(--red); }
.pill.settled { background: var(--blue-dim); color: var(--blue); }
.pill.archived { background: var(--bg-hover); color: var(--text-dim); }
.pill.late { background: var(--amber-dim); color: var(--amber); }
.pill.kicked { background: var(--red-dim); color: var(--red); }

.status-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 6px; }
.status-dot.connected { background: var(--green); box-shadow: 0 0 6px var(--green); }
.status-dot.connecting { background: var(--amber); }
.status-dot.disconnected { background: var(--red); }
/* v3 realtime protocol states (CONTRACT §9): live=green, reconnecting/resyncing=amber, stale=red. */
.status-dot.live { background: var(--green); box-shadow: 0 0 6px var(--green); }
.status-dot.reconnecting, .status-dot.resyncing { background: var(--amber); box-shadow: 0 0 6px var(--amber); animation: dot-pulse 1s infinite; }
.status-dot.stale { background: var(--red); box-shadow: 0 0 6px var(--red); animation: dot-pulse 1s infinite; }
@keyframes dot-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }

/* ---------- admin rows (games / classes lists) ---------- */
.list-row {
  display: flex; align-items: center; gap: 14px; padding: 12px 14px;
  border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-panel);
  margin-bottom: 8px;
}
.list-row .main { flex: 1; min-width: 0; }
.list-row .name { color: var(--text-bright); font-weight: 600; font-size: 14px; }
.list-row .meta { color: var(--text-dim); font-size: 11px; margin-top: 3px; }
.list-row .actions { display: flex; gap: 6px; flex-wrap: wrap; }

/* ---------- Auth ---------- */
.auth-wrap { display: flex; align-items: center; justify-content: center; min-height: 100vh; padding: 20px; }
.auth-card { width: 100%; max-width: 380px; }
.auth-card h1 { font-size: 22px; color: var(--text-bright); text-align: center; margin-bottom: 4px; }
.auth-card .tag { text-align: center; color: var(--text-dim); margin-bottom: 22px; font-size: 12px; }
.auth-tabs { display: flex; margin-bottom: 18px; border-bottom: 1px solid var(--border); }
.auth-tab { flex: 1; text-align: center; padding: 10px; cursor: pointer; color: var(--text-dim); }
.auth-tab.active { color: var(--text-bright); border-bottom: 2px solid var(--blue); }

/* ---------- Toast / banner ---------- */
.toast-host { position: fixed; top: 16px; right: 16px; z-index: 1000; display: flex; flex-direction: column; gap: 8px; }
.toast {
  background: var(--bg-panel); border: 1px solid var(--border-bright); border-left-width: 3px;
  border-radius: var(--radius); padding: 10px 14px; max-width: 340px; box-shadow: 0 6px 20px rgba(0,0,0,0.4);
  font-size: 12px; color: var(--text-bright);
}
.toast.ok { border-left-color: var(--green); }
.toast.err { border-left-color: var(--red); }
.toast.info { border-left-color: var(--blue); }
.toast.warn { border-left-color: var(--amber); }
.banner { padding: 10px 14px; border-radius: var(--radius); font-size: 12px; margin-bottom: 14px; }
.banner.err { background: var(--red-dim); color: var(--red); border: 1px solid var(--red); }
.banner.ok { background: var(--green-dim); color: var(--green); border: 1px solid var(--green); }
.banner.info { background: var(--blue-dim); color: var(--blue); border: 1px solid var(--blue); }

/* ---------- Modal ---------- */
.modal-host { position: fixed; inset: 0; background: rgba(0,0,0,0.6); display: flex; align-items: center; justify-content: center; z-index: 900; padding: 20px; }
.modal { background: var(--bg-panel); border: 1px solid var(--border-bright); border-radius: 8px; max-width: 460px; width: 100%; padding: 20px; }
.modal h3 { color: var(--text-bright); margin-bottom: 12px; }

/* ---------- Code chip (join / class codes) ---------- */
.codechip {
  display: inline-block; font-size: 15px; font-weight: 700; letter-spacing: 3px;
  color: var(--amber); background: var(--amber-dim); border: 1px solid var(--amber);
  padding: 3px 10px; border-radius: var(--radius);
}

/* ---------- Class membership chip (Users page) ----------
   Single class is the expected case (one chip, blue). A second-or-later
   membership is a "the model allows it, the UI nudges away from it" case —
   styled amber like a warning, with an explanatory title. */
.class-chip {
  display: inline-flex; align-items: center; gap: 4px; font-size: 11px;
  color: var(--blue); background: var(--blue-dim); border: 1px solid var(--blue);
  padding: 2px 6px 2px 8px; border-radius: 10px; white-space: nowrap;
}
.class-chip-extra { color: var(--amber); background: var(--amber-dim); border-color: var(--amber); }
.class-chip .chip-x {
  cursor: pointer; font-weight: 700; opacity: 0.7; padding: 0 2px; line-height: 1;
}
.class-chip .chip-x:hover { opacity: 1; }

/* ---------- Trading terminal grid ---------- */
.terminal { display: flex; flex-direction: column; height: 100vh; }
.ticker-strip {
  display: flex; gap: 10px; overflow-x: auto; padding: 8px 14px; background: var(--bg-panel);
  border-bottom: 1px solid var(--border); flex-shrink: 0;
}
.ticker-item {
  border: 1px solid var(--border); border-radius: var(--radius); padding: 6px 12px; min-width: 150px;
  cursor: pointer; flex-shrink: 0; background: var(--bg-panel-2);
}
.ticker-item.selected { border-color: var(--blue); }
.ticker-item .sym { color: var(--text-bright); font-weight: 700; }
.ticker-item .px { font-size: 16px; font-variant-numeric: tabular-nums; }

/* Term grid (reverted to the original layout, instructor request): LEFT
   column is the price chart (top, full column width, ~200px) followed by
   the order-book ladder, which gets the rest of the vertical space. Middle
   column: order ticket (top), news, trade tape. RIGHT column is itself a
   flex stack: Portfolio, then My Orders directly under it, then a
   collapsed-by-default Available pane at the bottom. The ticker strip above
   this grid is a plain selector — clicking a card just selects a security;
   chart + ladder + ticket all follow the selection. */
.term-grid {
  flex: 1; display: grid; gap: var(--gap); padding: var(--gap); min-height: 0;
  grid-template-columns: 360px 1fr 320px;
  /* News/Trades rows flex to whatever height is left under the order ticket
     so the whole grid fits the viewport: every panel (portfolio, My Orders,
     Available, Trades, News, ladder) then scrolls INSIDE its own box
     instead of the page growing (instructor request, Aug 18). If the ticket
     alone is taller than the screen, the grid scrolls as a whole. */
  grid-template-rows: max-content minmax(140px, 1fr) minmax(170px, 1.2fr);
  grid-template-areas:
    "left order   portfolio"
    "left news    portfolio"
    "left trades  portfolio";
  overflow-y: auto;
}
.area-portfolio > .panel-body, .area-trades > .panel-body, .area-news > .panel-body,
.orders-panel > .panel-body { overflow-y: auto; overscroll-behavior: contain; }
.area-left { grid-area: left; display: flex; flex-direction: column; gap: var(--gap); min-height: 0; min-width: 0; }
.area-left > .chart-panel { flex: 0 0 200px; min-height: 0; }
.area-left > .book-panel { flex: 1; min-height: 0; }
.area-order { grid-area: order; min-width: 0; }
.area-portfolio {
  grid-area: portfolio; min-width: 0; min-height: 0;
  display: flex; flex-direction: column; gap: var(--gap);
}
.area-portfolio > .portfolio-panel { flex: 1; min-height: 120px; }
.area-portfolio > .orders-panel { flex: 0 0 210px; }
.area-portfolio > .avail-pane { flex: 0 0 auto; max-height: 45%; }
.area-news { grid-area: news; min-width: 0; }
.area-trades { grid-area: trades; min-width: 0; }

@media (max-width: 1000px) {
  .term-grid {
    grid-template-columns: 1fr;
    grid-template-rows: auto;
    grid-template-areas: "left" "order" "portfolio" "news" "trades";
  }
  .area-left { min-height: 380px; }
  .area-portfolio { min-height: 480px; }
}

/* order book depth (projector.html's two-sided book — unchanged) */
.depth { width: 100%; border-collapse: collapse; font-size: 12px; }
.depth th { color: var(--text-dim); font-size: 10px; text-transform: uppercase; padding: 3px 8px; text-align: right; }
.depth td { padding: 2px 8px; text-align: right; font-variant-numeric: tabular-nums; position: relative; }
.depth td.px-bid { color: var(--green); }
.depth td.px-ask { color: var(--red); }
.depth .depthbar { position: absolute; top: 0; bottom: 0; right: 0; opacity: 0.14; }
.depth .depthbar.bid { background: var(--green); }
.depth .depthbar.ask { background: var(--red); }

/* Order-book ladder (terminal.html only): single price column + qty column,
   asks on top (highest -> lowest), a spread divider row, then bids
   (highest -> lowest) at the bottom. Distinct from .depth (projector.html's
   two-sided book) so that page is untouched. */
.ladder { width: 100%; border-collapse: collapse; font-size: 12px; }
.ladder td { padding: 4px 10px; font-variant-numeric: tabular-nums; position: relative; }
.ladder td.lvl-price { text-align: left; font-weight: 600; }
.ladder td.lvl-price.px-bid { color: var(--green); }
.ladder td.lvl-price.px-ask { color: var(--red); }
.ladder td.lvl-qty { text-align: right; }
.ladder td.own-lvl { box-shadow: inset 0 0 0 1px var(--blue); }
.ladder td.own-lvl::after { content: "\2022"; color: var(--blue); margin-left: 4px; }
.ladder .depthbar { position: absolute; top: 0; bottom: 0; right: 0; opacity: 0.14; }
.ladder .depthbar.bid { background: var(--green); }
.ladder .depthbar.ask { background: var(--red); }
.ladder tr.lvl-row { cursor: pointer; }
.ladder tr.lvl-row:hover td { background: var(--bg-hover); }
.ladder tr.spread-row td {
  text-align: center; color: var(--text-dim); background: var(--bg-panel-2); font-size: 11px; padding: 6px;
  border-top: 1px solid var(--border); border-bottom: 1px solid var(--border);
}

/* Price chart (terminal.html — top of the left column, above the ladder). */
.price-chart { width: 100%; height: 170px; display: block; background: var(--bg-panel-2); }

/* "Available" pane (terminal.html right column, under My Orders): a
   collapsed-by-default <details>, styled like the wizard's neutral
   .disclosure rather than console.html's red .sensitive (this isn't an
   answer key, just per-security estimates mirroring risk.py's worst-case
   admission arithmetic client-side — build brief #1/#2). */
.avail-pane {
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--bg-panel); overflow: hidden;
  display: flex; flex-direction: column; min-height: 0;
}
.avail-pane > summary {
  cursor: pointer; padding: 8px 12px; font-weight: 600; font-size: 11px;
  text-transform: uppercase; letter-spacing: 1px; color: var(--blue);
  list-style: none;
}
.avail-pane > summary::-webkit-details-marker { display: none; }
.avail-pane > summary::before { content: "▸ "; }
.avail-pane[open] > summary::before { content: "▾ "; }
.avail-pane[open] > summary { border-bottom: 1px solid var(--border); }
.avail-pane .avail-sub { text-transform: none; font-weight: 400; color: var(--text-dim); letter-spacing: 0; }
.avail-body { padding: 10px 12px; overflow-y: auto; }
.avail-ingredients { margin-bottom: 10px; padding-bottom: 8px; border-bottom: 1px solid var(--border); }
.avail-sec { padding: 8px 0; border-bottom: 1px solid var(--border); }
.avail-sec:last-child { border-bottom: none; }
.avail-sec .sym { color: var(--text-bright); font-weight: 700; display: block; margin-bottom: 2px; }
.avail-line { display: flex; justify-content: space-between; font-size: 12px; padding-top: 3px; }
.avail-line .lbl { color: var(--text-dim); }
.avail-line .val { color: var(--text-bright); }
.avail-note { margin: 1px 0 4px; }

/* trade tape / news feed */
.feed { list-style: none; }
.feed li { padding: 7px 4px; border-bottom: 1px solid var(--border); }
.feed .fh { color: var(--text-bright); }
.feed .fb { color: var(--text-dim); font-size: 11px; margin-top: 2px; }
.feed .ft { color: var(--text-dim); font-size: 10px; float: right; }
.tape-row { display: flex; justify-content: space-between; font-size: 12px; padding: 3px 4px; border-bottom: 1px solid var(--border); font-variant-numeric: tabular-nums; }

/* portfolio */
.kv { display: flex; justify-content: space-between; padding: 4px 0; border-bottom: 1px solid var(--border); }
.kv .k { color: var(--text-dim); }
.kv .v { font-variant-numeric: tabular-nums; color: var(--text-bright); }
.big-num { font-size: 22px; font-variant-numeric: tabular-nums; color: var(--text-bright); }

/* Team panel (terminal, teams_allowed only) */
.team-panel { margin-bottom: 12px; padding-bottom: 10px; border-bottom: 1px solid var(--border); }

/* Score card + trade simulator removed from the terminal (see terminal.html
   git history for restoration — build-brief item 6). */

/* clock */
.clock-big { font-size: 20px; font-variant-numeric: tabular-nums; color: var(--amber); font-weight: 700; }

/* ---------- Wizard ---------- */
.wizard { max-width: 900px; margin: 0 auto; }
.steps { display: flex; gap: 6px; margin-bottom: 22px; }
.step {
  flex: 1; text-align: center; padding: 10px; border-radius: var(--radius); border: 1px solid var(--border);
  color: var(--text-dim); font-size: 12px; background: var(--bg-panel);
}
.step.active { border-color: var(--blue); color: var(--blue); background: var(--blue-dim); }
.step.done { border-color: var(--green); color: var(--green); }
.step .n { font-weight: 700; margin-right: 6px; }
.wizard-body { min-height: 320px; }
.wizard-nav { display: flex; justify-content: space-between; margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--border); }

.issuer-card, .instr-card, .event-card {
  border: 1px solid var(--border); border-radius: var(--radius); padding: 14px; margin-bottom: 12px; background: var(--bg-panel-2);
}
.issuer-card > .head, .instr-card > .head, .event-card > .head {
  display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;
}
.preset-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 12px; }
.preset-card { border: 1px solid var(--border); border-radius: var(--radius); padding: 14px; cursor: pointer; background: var(--bg-panel); }
.preset-card:hover { border-color: var(--blue); }
.preset-card.selected { border-color: var(--green); background: var(--green-dim); }
.preset-card .plabel { color: var(--text-bright); font-weight: 700; margin-bottom: 6px; }
.preset-card .psum { color: var(--text-dim); font-size: 11px; }

.disclosure { margin-top: 10px; }
.disclosure > summary { cursor: pointer; color: var(--blue); font-size: 12px; padding: 4px 0; }
.disclosure[open] > summary { margin-bottom: 10px; }

.review-line { padding: 6px 0; border-bottom: 1px solid var(--border); }
.review-line .lead { color: var(--text-bright); }

/* ---------- Projector ---------- */
.projector { padding: 24px 40px; min-height: 100vh; }
.projector .pj-top { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 24px; }
.projector .pj-title { font-size: 34px; color: var(--text-bright); font-weight: 800; }
.projector .pj-clock { font-size: 48px; font-variant-numeric: tabular-nums; color: var(--amber); font-weight: 800; }
.projector .pj-grid { display: grid; grid-template-columns: 1.4fr 1fr; gap: 28px; }
.projector table.lb { width: 100%; border-collapse: collapse; font-size: 22px; }
.projector table.lb th { color: var(--text-dim); text-align: left; padding: 8px 12px; font-size: 14px; text-transform: uppercase; }
.projector table.lb td { padding: 10px 12px; border-bottom: 1px solid var(--border); font-variant-numeric: tabular-nums; }
.projector table.lb td.rank { color: var(--amber); font-weight: 800; width: 60px; }
.projector .pj-ticker { display: flex; flex-direction: column; gap: 10px; }
.projector .pj-tick { display: flex; justify-content: space-between; font-size: 26px; padding: 10px 16px; border: 1px solid var(--border); border-radius: 8px; }
.projector .pj-news { margin-top: 22px; font-size: 22px; color: var(--amber); }
.projector .pj-code { font-size: 30px; letter-spacing: 6px; }
.projector .pj-books { display: flex; flex-direction: column; gap: 14px; }
.projector .pj-book { border: 1px solid var(--border); border-radius: 8px; padding: 10px 14px; position: relative; }
.projector .pj-book .pj-book-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 6px; }
.projector .pj-book .pj-book-sym { font-size: 18px; font-weight: 800; color: var(--text-bright); }
.projector .pj-book .pj-book-last { font-size: 18px; font-variant-numeric: tabular-nums; }
.projector table.depth th, .projector table.depth td { font-size: 13px; padding: 3px 10px; }
.pj-book.grayed, .pj-lb-wrap.grayed { opacity: 0.35; filter: grayscale(1); pointer-events: none; }
.stale-overlay {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,0.55); color: var(--text-bright); font-size: 13px; text-transform: uppercase;
  letter-spacing: 1px; border-radius: 8px; z-index: 5;
}

/* ---------- misc ---------- */
.empty { color: var(--text-dim); text-align: center; padding: 24px; font-style: italic; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.stat { border: 1px solid var(--border); border-radius: var(--radius); padding: 12px; background: var(--bg-panel-2); }
.stat .label { color: var(--text-dim); font-size: 10px; text-transform: uppercase; letter-spacing: 0.5px; }
.stat .value { font-size: 20px; color: var(--text-bright); font-variant-numeric: tabular-nums; margin-top: 4px; }

/* Responsive: narrow-screen sidebar/projector rules. (The terminal grid's own
   narrow-screen stacking lives with .term-grid above — this used to duplicate
   a stale, pre-ladder-refactor `.term-grid` rule referencing a "book" grid
   area that no longer exists; removed so it can't silently win the cascade
   over the current layout.) */
@media (max-width: 1000px) {
  .sidebar { width: 64px; }
  .sidebar-item span.txt { display: none; }
  .projector .pj-grid { grid-template-columns: 1fr; }
}

/* ---------- Corp-fin simulation ---------- */
.sim-shell { max-width: 1200px; margin: 0 auto; padding: 20px 24px; }

/* round / phase indicator in the top bar */
.phase-chip {
  font-size: 10px; padding: 2px 9px; border-radius: 11px; text-transform: uppercase;
  letter-spacing: 0.6px; font-weight: 600; display: inline-block;
  background: var(--bg-hover); color: var(--text-dim);
}
.phase-chip.open { background: var(--green-dim); color: var(--green); }
.phase-chip.closed { background: var(--amber-dim); color: var(--amber); }
.phase-chip.resolved { background: var(--blue-dim); color: var(--blue); }
.phase-chip.none { background: var(--bg-hover); color: var(--text-dim); }
.round-tag { font-size: 13px; color: var(--text-bright); font-weight: 700; font-variant-numeric: tabular-nums; }

/* firm state metrics */
.metric-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(112px, 1fr)); gap: 10px; }
.metric { border: 1px solid var(--border); border-radius: var(--radius); padding: 10px 12px; background: var(--bg-panel-2); }
.metric .m-label { color: var(--text-dim); font-size: 10px; text-transform: uppercase; letter-spacing: 0.5px; }
.metric .m-value { font-size: 17px; color: var(--text-bright); font-variant-numeric: tabular-nums; margin-top: 3px; }

/* sector founding cards (reuse preset-card look) */
.sector-card .blurb { color: var(--text-dim); font-size: 11px; margin: 6px 0 10px; line-height: 1.5; }
.sector-card .facts { display: flex; flex-wrap: wrap; gap: 3px 16px; font-size: 11px; font-variant-numeric: tabular-nums; }
.sector-card .facts .k { color: var(--text-dim); margin-right: 4px; }
.sector-card .facts .v { color: var(--text); }

/* decision form */
.remaining { display: flex; justify-content: space-between; align-items: baseline; padding: 8px 0; border-top: 1px solid var(--border); margin-top: 6px; }
.remaining .amt { font-size: 16px; font-variant-numeric: tabular-nums; }
.decision-status { font-size: 12px; margin-top: 10px; }

/* mini charts */
.chart-block { margin-bottom: 14px; }
.chart-block:last-child { margin-bottom: 0; }
.chart-block .c-title { color: var(--text-dim); font-size: 10px; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 4px; }
canvas.spark { width: 100%; display: block; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-panel-2); }

.row-me td { background: var(--blue-dim) !important; }
.tag-flag { font-size: 10px; padding: 1px 6px; border-radius: 8px; background: var(--red-dim); color: var(--red); text-transform: uppercase; letter-spacing: 0.4px; }
.tag-ok { color: var(--green); }
.tag-wait { color: var(--text-dim); }

/* ---------- Mode-choice cards (game creation) ---------- */
.mode-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 14px; margin-bottom: 18px; }
.mode-card { border: 1px solid var(--border); border-radius: var(--radius); padding: 18px; cursor: pointer; background: var(--bg-panel); }
.mode-card:hover { border-color: var(--blue); }
.mode-card .mtitle { color: var(--text-bright); font-weight: 700; font-size: 15px; margin-bottom: 8px; }
.mode-card .mdesc { color: var(--text-dim); font-size: 11.5px; line-height: 1.5; }

/* ---------- Sensitive-content disclosure (projector hygiene) ---------- */
.sensitive { border: 1px solid var(--red); border-radius: var(--radius); margin-top: 14px; overflow: hidden; }
.sensitive > summary {
  cursor: pointer; padding: 9px 14px; background: var(--red-dim); color: var(--red);
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.8px; font-weight: 700;
}
.sensitive > .sensitive-body { padding: 14px; border-top: 1px solid var(--red); }

/* ---------- Danger zone / lifecycle button grouping ---------- */
.lifecycle-groups { display: flex; flex-direction: column; gap: 14px; }
.lifecycle-group { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.lifecycle-group .glabel { font-size: 10px; text-transform: uppercase; letter-spacing: 0.6px; color: var(--text-dim); width: 100%; margin-bottom: 2px; }
.lifecycle-group.danger { padding-top: 12px; border-top: 1px dashed var(--border-bright); }

/* "Restart game" callout (build brief #3b): a prominent, always-visible box
   above the ordinary lifecycle groups so the reset transition — the fix for
   "I wanted to edit endowments before start but got blocked" — is easy to
   find instead of buried in the Settlement danger group. */
.restart-callout {
  display: flex; flex-direction: column; gap: 6px; padding: 12px 14px;
  border: 1px solid var(--amber); border-radius: var(--radius); background: var(--amber-dim);
}
.restart-callout .glabel { font-size: 10px; text-transform: uppercase; letter-spacing: 0.6px; color: var(--amber); }
.restart-callout .hint { color: var(--text-dim); font-size: 12px; margin-bottom: 2px; }
.btn-restart {
  align-self: flex-start; border-color: var(--amber); color: var(--amber); background: rgba(255, 204, 0, 0.14);
  font-weight: 700; padding: 9px 18px; font-size: 13px;
}
.btn-restart:hover { background: rgba(255, 204, 0, 0.3); color: var(--text-bright); }

/* ---------- Checklists (settle true-value gate) ---------- */
.checklist-row { display: flex; align-items: center; gap: 10px; padding: 6px 0; border-bottom: 1px solid var(--border); }
.checklist-row .cl-ok { color: var(--green); }
.checklist-row .cl-missing { color: var(--red); }
.checklist-row .sym { min-width: 70px; color: var(--text-bright); font-weight: 600; }
.checklist-row input { max-width: 120px; }

/* ---------- Payout-state matrix grid editor ---------- */
.matrix-scroll { overflow-x: auto; }
table.matrix { border-collapse: collapse; font-size: 12px; }
table.matrix th, table.matrix td { border: 1px solid var(--border); padding: 5px 7px; white-space: nowrap; }
table.matrix th { background: var(--bg-panel-2); color: var(--text-dim); font-weight: 500; text-transform: uppercase; font-size: 10px; }
table.matrix input { width: 90px; padding: 4px 6px; }
.matrix-sum { margin-top: 8px; font-size: 12px; }
.matrix-sum.ok { color: var(--green); }
.matrix-sum.bad { color: var(--red); }

/* ---------- Announcement drafts ---------- */
.draft-row { display: flex; justify-content: space-between; align-items: center; gap: 10px; padding: 8px 10px; border: 1px solid var(--border); border-radius: var(--radius); margin-bottom: 6px; background: var(--bg-panel-2); }
.draft-row .dtext { min-width: 0; }
.draft-row .dtext .dh { color: var(--text-bright); font-weight: 600; }
.draft-row .dtext .db { color: var(--text-dim); font-size: 11px; margin-top: 2px; }

/* ---------- Drill-down (leaderboard expand) ---------- */
.drill { background: var(--bg-panel-2); border: 1px solid var(--border); border-radius: var(--radius); padding: 10px 12px; margin: -2px 0 8px; }
.drill-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 8px; margin-bottom: 10px; }

/* ---------- Full-screen alert flash (terminal / console preview) ---------- */
.flash-overlay {
  position: fixed; inset: 0; background: var(--amber); color: #1a1400; z-index: 950;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: 40px; animation: flash-pulse 0.4s ease-in-out 3;
}
.flash-overlay .fh { font-size: 32px; font-weight: 800; margin-bottom: 12px; }
.flash-overlay .fb { font-size: 16px; }
@keyframes flash-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.75; } }
.alert-banner {
  padding: 8px 16px; background: var(--amber-dim); color: var(--amber); border-bottom: 1px solid var(--amber);
  font-size: 12px; display: flex; justify-content: space-between; align-items: center; gap: 10px;
}

/* ---------- Countdown warning state ---------- */
.clock-big.warn, .pj-clock.warn { color: var(--red) !important; }

/* ---------- Monospace JSON editor ---------- */
textarea.code-area { font-family: var(--font); font-size: 12px; min-height: 260px; white-space: pre; }
pre.code-block {
  font-family: var(--font); font-size: 11px; background: var(--bg-input); border: 1px solid var(--border-bright);
  border-radius: var(--radius); padding: 12px; overflow-x: auto; color: var(--text); white-space: pre-wrap; word-break: break-word;
}

/* ---------- Ticket / connection error page ---------- */
.fullscreen-msg { display: flex; align-items: center; justify-content: center; min-height: 100vh; padding: 24px; text-align: center; }
.fullscreen-msg .fm-inner { max-width: 460px; }
.fullscreen-msg h2 { color: var(--text-bright); margin-bottom: 10px; }
.fullscreen-msg p { color: var(--text-dim); font-size: 13px; }

/* ---------- Archive viewer ---------- */
.archive-list-row { display: flex; align-items: center; gap: 14px; padding: 12px 14px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-panel); margin-bottom: 8px; cursor: pointer; }
.archive-list-row:hover { border-color: var(--blue); }
.statement-card { border: 1px solid var(--border); border-radius: var(--radius); padding: 12px 14px; margin-bottom: 8px; background: var(--bg-panel-2); }
.statement-card .sname { color: var(--text-bright); font-weight: 700; margin-bottom: 6px; }

/* ---- corp-fin simulation control page ---- */
.control-bar {
  display: flex; align-items: center; gap: var(--gap);
  flex-wrap: wrap; margin-bottom: 1rem;
  padding: 0.75rem 1rem; background: var(--bg-panel);
  border: 1px solid var(--border); border-radius: var(--radius);
}
.control-bar .spacer { flex: 1; }
.submit-tracker {
  font-family: var(--font); color: var(--text-dim);
  padding: 0.35rem 0.7rem; border: 1px solid var(--border);
  border-radius: var(--radius); background: var(--bg-input);
}
.submit-tracker.ready { color: var(--green); border-color: var(--green); }
.sim-grid { display: grid; grid-template-columns: 1.6fr 1fr; gap: 1rem; align-items: start; }
@media (max-width: 900px) { .sim-grid { grid-template-columns: 1fr; } }
.table-scroll { overflow-x: auto; max-width: 100%; }
.data-table { width: 100%; border-collapse: collapse; font-family: var(--font); font-size: 0.86rem; }
.data-table th {
  text-align: left; color: var(--text-dim); font-weight: 500;
  padding: 0.4rem 0.6rem; border-bottom: 1px solid var(--border-bright);
  white-space: nowrap;
}
.data-table td { padding: 0.4rem 0.6rem; border-bottom: 1px solid var(--border); white-space: nowrap; }
.data-table td.num { text-align: right; }
.data-table td.strong { color: var(--text-bright); font-weight: 600; }
.data-table td.ok { color: var(--green); }
.data-table td.warn { color: var(--amber); }
.data-table tr:hover td { background: var(--bg-hover); }
.data-table.compact th, .data-table.compact td { padding: 0.28rem 0.5rem; font-size: 0.8rem; }
.strong { color: var(--text-bright); font-weight: 600; }
.sector-result { margin-bottom: 1rem; }
.sector-head { margin-bottom: 0.4rem; }

/* ==================== terminal.html (trading terminal) additions ==================== */

/* Book/portfolio pane grayed while the feed is not "live" (§7.3: a stale book
   must never look live). Wrap the panel body in `.gray-target` and toggle
   `.grayed` on it; `.reconnect-overlay` sits on top via the wrapper's
   position:relative parent. */
.gray-wrap { position: relative; min-height: 0; display: flex; flex-direction: column; flex: 1; }
.gray-target.grayed { opacity: 0.35; filter: grayscale(60%); pointer-events: none; }
.reconnect-overlay {
  position: absolute; inset: 0; display: none; align-items: center; justify-content: center;
  flex-direction: column; gap: 6px; background: rgba(10, 14, 20, 0.45); z-index: 5;
  font-size: 12px; text-transform: uppercase; letter-spacing: 1px; color: var(--amber); text-align: center;
}
.reconnect-overlay.showing { display: flex; }
.reconnect-overlay.is-stale { color: var(--red); }
.reconnect-overlay .ro-sub { font-size: 10px; text-transform: none; letter-spacing: 0; color: var(--text-dim); }

/* Order ticket header: large symbol + name, side-colored, flashes on switch. */
.ticket-head { padding: 4px 0 12px; }
.ticket-head .tk-sym { font-size: 22px; font-weight: 800; color: var(--text-bright); }
.ticket-head .tk-name { font-size: 12px; color: var(--text-dim); margin-top: 2px; }
.ticket-head.side-buy .tk-sym { color: var(--green); }
.ticket-head.side-sell .tk-sym { color: var(--red); }
.ticket-head.flash { animation: ticket-flash 0.5s ease-out; }
@keyframes ticket-flash { 0% { background: var(--blue-dim); } 100% { background: transparent; } }
.confirm-line {
  font-size: 12.5px; color: var(--text-bright); background: var(--bg-panel-2); border: 1px solid var(--border-bright);
  border-radius: var(--radius); padding: 8px 10px; margin: 10px 0; min-height: 18px; line-height: 1.4;
}
.confirm-line.incomplete { color: var(--text-dim); font-style: italic; }

/* Book level rows: clickable to prefill the opposite side; own resting orders
   marked with a dot — see .ladder rules above (terminal.html's ladder). */

/* Borrow / repay */
.debt-line { display: flex; align-items: baseline; justify-content: space-between; padding: 3px 0; }
.debt-line .k { color: var(--text-dim); font-size: 11px; }
.debt-line .v { font-variant-numeric: tabular-nums; }
.borrow-modal .projected { margin-top: 14px; padding-top: 12px; border-top: 1px dashed var(--border-bright); }

/* API keys panel */
.key-reveal {
  font-family: var(--font); font-size: 13px; letter-spacing: 0.5px; word-break: break-all;
  background: var(--bg-input); border: 1px solid var(--amber); color: var(--amber);
  border-radius: var(--radius); padding: 8px 10px; margin: 8px 0;
}
.key-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 6px 0; border-bottom: 1px solid var(--border); }
.key-row .kid { font-size: 11px; color: var(--text-dim); }

/* "Time!" full-screen overlay — persistent until dismissed (distinct from the
   auto-pulsing `.flash-overlay` used for instructor alerts). */
.time-overlay {
  position: fixed; inset: 0; background: rgba(10, 14, 20, 0.94); color: var(--text-bright); z-index: 960;
  display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; gap: 14px;
}
.time-overlay .to-title { font-size: 56px; font-weight: 800; color: var(--red); letter-spacing: 2px; }
.time-overlay .to-sub { font-size: 14px; color: var(--text-dim); max-width: 420px; }

/* Pre-join gate (team-join input lives here) */
.gate-form { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--border); }
.gate-or { text-align: center; color: var(--text-dim); font-size: 11px; margin: 14px 0; text-transform: uppercase; letter-spacing: 1px; }

.alert-banners .alert-banner + .alert-banner { border-top: 1px solid rgba(0, 0, 0, 0.2); }

/* Market-status banner (terminal.html): full-width, sits above the ticker /
   order ticket whenever the game isn't actively tradable (paused, halted,
   ended, settled, not-yet-open) — the fix for "my orders did nothing" being
   a silently-paused game. */
.market-status-banner { padding: 10px 18px; text-align: center; font-weight: 700; font-size: 13px; letter-spacing: 0.3px; border-bottom: 1px solid; }
.market-status-banner.warn { background: var(--amber-dim); color: var(--amber); border-bottom-color: var(--amber); }
.market-status-banner.info { background: var(--bg-panel-2); color: var(--text-dim); border-bottom-color: var(--border-bright); }

/* Dashboard API-key modal (key issuance lives on the dashboard, not the terminal) */
.modal-backdrop {
  position: fixed; inset: 0; background: rgba(0,0,0,0.6);
  display: flex; align-items: center; justify-content: center; z-index: 300;
}
.modal-card { max-width: 560px; width: 92%; }

/* Your Orders panel: "Your fills" sub-list under the open orders (2026-08-18) */
.panel-subhead { padding: 6px 12px 4px; font-size: 10px; text-transform: uppercase; letter-spacing: 1px; color: var(--text-dim); border-top: 1px solid var(--border); margin-top: 6px; }

/* Wizard step tabs are directly clickable (jump to any step) */
.steps .step.clickable { cursor: pointer; }
.steps .step.clickable:hover { border-color: var(--amber, #e8a33d); }
