/* PSU Quants Exchange: black trading-terminal theme. */

:root {
  --bg: #000;
  --panel: #0b0d12;
  --panel-raised: #11151c;
  --line: #1c212b;
  --text: #e8eaed;
  --muted: #8a93a3;
  --accent: #4a7fd6;        /* Penn State blue */
  --accent-soft: rgba(74, 127, 214, 0.14);
  --bid: #22c55e;
  --bid-soft: rgba(34, 197, 94, 0.12);
  --ask: #ef4444;
  --ask-soft: rgba(239, 68, 68, 0.12);
  --mono: ui-monospace, "SF Mono", "Cascadia Mono", Consolas, monospace;
  --radius: 10px;
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }  /* so layout rules below never un-hide a screen */

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 14px/1.45 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { margin: 0; font-weight: 600; }
.muted { color: var(--muted); }
.error { color: var(--ask); min-height: 1.2em; margin: 0; }
.up { color: var(--bid); }
.down { color: var(--ask); }

/* --- Wordmark ------------------------------------------------------------------------------ */

.wordmark {
  font-weight: 800;
  letter-spacing: 0.14em;
  font-size: 13px;
  color: var(--text);
  white-space: nowrap;
}
.wordmark span { color: var(--accent); }

/* --- Inputs and buttons -------------------------------------------------------------------- */

input {
  width: 100%;
  min-width: 0;
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 7px;
  padding: 8px 10px;
  font: 14px var(--mono);
  outline: none;
  transition: border-color 0.15s;
}
input::placeholder { color: #4b5363; font-family: system-ui, sans-serif; }
input:focus { border-color: var(--accent); }

button {
  cursor: pointer;
  border: none;
  border-radius: 7px;
  padding: 8px 14px;
  font: 600 13px system-ui, sans-serif;
  color: #fff;
  transition: filter 0.15s, background 0.15s;
}
button:hover { filter: brightness(1.15); }
button.primary { background: var(--accent); }
button.buy { background: var(--bid); color: #03120a; }
button.sell { background: var(--ask); }
button.ghost {
  background: transparent;
  color: var(--muted);
  border: 1px solid var(--line);
  font-weight: 500;
}
button.ghost:hover { color: var(--text); border-color: var(--muted); }
button.icon {
  background: transparent;
  color: var(--muted);
  padding: 2px 8px;
}
button.icon:hover { color: var(--ask); }

/* --- Join screen --------------------------------------------------------------------------- */

.join {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 16px;
  background: radial-gradient(ellipse at top, rgba(74, 127, 214, 0.18), transparent 60%), var(--bg);
}
.join-card {
  width: 100%;
  max-width: 360px;
  padding: 36px 32px 28px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 16px;
}
.join-card .wordmark { font-size: 16px; }
.tagline { margin: 6px 0 28px; color: var(--muted); }
/* A form with labelled boxes stacked top to bottom (join, admin login, create market). */
#join-form, .stack-form { display: flex; flex-direction: column; gap: 16px; }
#join-form label, .stack-form label {
  display: flex; flex-direction: column; gap: 6px; color: var(--muted); font-size: 12px;
}
#join-form input, .stack-form input { padding: 10px 12px; font-family: system-ui, sans-serif; }
#join-form button, .join-card .stack-form button { padding: 11px; margin-top: 4px; }

/* --- Top bar ------------------------------------------------------------------------------- */

.topbar {
  display: flex;
  align-items: center;
  gap: 24px;
  flex-wrap: wrap;
  padding: 14px 20px;
  border-bottom: 1px solid var(--line);
}
.pill {
  align-self: center;
  font: 700 10px system-ui, sans-serif;
  letter-spacing: 0.1em;
  padding: 3px 8px;
  border-radius: 999px;
  color: var(--bid);
  background: var(--bid-soft);
}
/* Green while trading; red when halted; grey before opening and after settling. */
.pill.halted { color: var(--ask); background: var(--ask-soft); }
.pill.created, .pill.settled { color: var(--muted); background: var(--panel-raised); }
/* Blue during the Trade or Tighten opening. */
.pill.auction, .pill.mm_quoting, .pill.forced_trade { color: var(--accent); background: var(--accent-soft); }
.me { display: flex; align-items: center; gap: 22px; margin-left: auto; flex-wrap: wrap; }
.me button { font-size: 12px; padding: 7px 10px; }
/* A link that looks like a ghost button (the admin page's "Review screen"). */
a.button.ghost {
  color: var(--muted);
  border: 1px solid var(--line);
  border-radius: 7px;
  padding: 6px 10px;
  font: 500 12px system-ui, sans-serif;
  text-decoration: none;
}
a.button.ghost:hover { color: var(--text); border-color: var(--muted); }
.stat { display: flex; flex-direction: column; gap: 1px; }
.stat small, .tile small {
  color: var(--muted);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.stat b { font: 600 15px var(--mono); }
.click-size input { width: 72px; padding: 4px 8px; }
/* The keyboard shortcuts hint in the top bar (Q142). */
.keys span { color: var(--muted); font-size: 12px; white-space: nowrap; }
kbd {
  font: 600 11px var(--mono);
  color: var(--text);
  border: 1px solid var(--line);
  border-bottom-width: 2px;
  border-radius: 4px;
  padding: 0 4px;
}
/* With several markets, the one B, S, Q and Esc act on has its title in blue. */
.market-area #markets > .market.active:not(:only-child) .market-head h1 { color: var(--accent); }

#message {
  margin: 0;
  padding: 0 20px;
  height: 26px;  /* always one line, so a message never pushes the book down */
  line-height: 26px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--ask);
  font-size: 13px;
}

/* The trader page's banner for errors, notices and fill alerts. It floats over the page just under the top
   bar, so the book never moves when it comes and goes. The anchor is sticky, so the banner
   stays in view (at the top of the window) when the page is scrolled down. */
.banner-anchor { position: sticky; top: 0; height: 0; z-index: 10; }
#banner {
  position: absolute;
  top: 8px;
  left: 20px;
  right: 20px;
  margin: 0;
  padding: 10px 16px;
  background: var(--ask);
  color: #fff;
  font-weight: 700;
  font-size: 15px;
  border-radius: 8px;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.6);
}
/* A short shake every time a message arrives, even the same one again. */
#banner.shake { animation: shake 0.4s ease-in-out; }
@keyframes shake {
  0%, 100% { transform: translateX(0); }
  20%, 60% { transform: translateX(-8px); }
  40%, 80% { transform: translateX(8px); }
}
/* Fill alerts (errors and sells keep the red above): green for a buy, blue when the market
   maker's buys and sells cancel out. Black text, because white on this green is hard to read. */
#banner.buy { background: var(--bid); color: #000; }
#banner.even { background: var(--accent); }

/* When I get filled, the market's column and its Position tile flash the fill's colour, then
   fade back to normal over 2 s (FILL_SECONDS in trader.js). Each animation has only a "from"
   step, so it ends on the element's usual look. */
.column.flash-buy { animation: column-flash-buy 2s ease-out; }
.column.flash-sell { animation: column-flash-sell 2s ease-out; }
.column.flash-even { animation: column-flash-even 2s ease-out; }
@keyframes column-flash-buy { from { box-shadow: 0 0 0 2px var(--bid), 0 0 28px rgba(34, 197, 94, 0.45); } }
@keyframes column-flash-sell { from { box-shadow: 0 0 0 2px var(--ask), 0 0 28px rgba(239, 68, 68, 0.45); } }
@keyframes column-flash-even { from { box-shadow: 0 0 0 2px var(--accent), 0 0 28px rgba(74, 127, 214, 0.45); } }
.tile.flash-buy { animation: tile-flash-buy 2s ease-out; }
.tile.flash-sell { animation: tile-flash-sell 2s ease-out; }
.tile.flash-even { animation: tile-flash-even 2s ease-out; }
@keyframes tile-flash-buy { from { background: rgba(34, 197, 94, 0.45); } }
@keyframes tile-flash-sell { from { background: rgba(239, 68, 68, 0.45); } }
@keyframes tile-flash-even { from { background: rgba(74, 127, 214, 0.45); } }

/* An empty box, or the form whose command was rejected, while its error is showing. */
.wrong { outline: 2px solid var(--ask); outline-offset: 2px; border-radius: 7px; }

/* --- Terminal layout ----------------------------------------------------------------------- */

/* The trading screen is exactly one window high and never scrolls: the top bar, then the
   market columns on the left and the sidebar (resting orders, positions, tape) on the right.
   The only things that scroll are the sidebar's lists, each inside its own box. On a window
   shorter than 600px the page scrolls instead of squashing the book further. (Narrow windows:
   see "Fallbacks" at the end of this part.) Nothing here hides overflow, so the ring that
   flashes around a column when I get filled is never cut off. */
#trade-screen {
  height: 100vh;
  height: 100dvh;
  min-height: 600px;
  display: flex;
  flex-direction: column;
}
#trade-screen .topbar { padding: 8px 16px; gap: 20px; }
#trade-screen .me { gap: 20px; }

.terminal {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(280px, 380px);
  grid-template-rows: minmax(0, 1fr);  /* both sides exactly fill the window's height */
  gap: 14px;
  padding: 12px 16px 16px;
}
/* (The rounded corners are only seen when a fill flashes a ring around the column.) */
.column { display: flex; flex-direction: column; gap: 14px; min-width: 0; border-radius: var(--radius); }

.market-area { display: flex; flex-direction: column; min-height: 0; }
/* One column per running market, all in one row: more markets means narrower columns.
   (Scoped to .market-area because the admin page has a different #markets: a table.) */
.market-area #markets {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr);
  gap: 14px;
  align-items: stretch;  /* every column is the full height */
}
.waiting { margin: 0; color: var(--muted); text-align: center; padding: 28px 16px; }

/* One market's column: a title bar, then the book and the controls. The column is a size
   container named "market": when it is wide (one market on screen) the controls sit to the
   right of the book; when it is narrow (several markets) they sit under it. */
.market { container: market / inline-size; gap: 10px; min-height: 0; }
/* The title bar: a status line (pill, trading clock, tick line), then the full title on up to
   2 lines, then "…" (hovering shows all of it). SPEC Q250. */
.market-head { display: flex; flex-direction: column; gap: 4px; min-width: 0; padding: 0 2px; }
.market-meta { display: flex; align-items: center; gap: 10px; min-width: 0; }
.market-head h1 {
  font-size: 16px;
  line-height: 1.25;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  overflow-wrap: anywhere;  /* a very long word still breaks rather than running off */
}
/* With several markets, every title gets room for 2 lines, so every column's book starts at
   the same height. One market alone on the screen doesn't reserve the second line. */
@container market (max-width: 759px) {
  .market-head h1 { min-height: 2.5em; }
}
.market-head .pill { flex-shrink: 0; white-space: nowrap; }
.market-head .trading-clock { flex-shrink: 0; font: 600 14px var(--mono); color: var(--accent); }
.market-head .trading-clock.done { color: var(--ask); }
.market-info {
  margin-left: auto;
  min-width: 0;
  font-size: 12px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;  /* long text ends in "…"; hovering shows all of it */
}

.market-body {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  /* The book takes whatever the controls leave, but never less than its minimum height (see
     "Order book"); below that the page scrolls rather than cutting the book off. */
  grid-template-rows: minmax(auto, 1fr) auto;
  gap: 10px;
}
@container market (min-width: 760px) {
  .market-body {
    grid-template-columns: minmax(0, 1fr) 320px;
    grid-template-rows: minmax(auto, 1fr);
  }
}
/* The controls sit straight on the page (no panel box, to save height): order entry (or Trade
   or Tighten), then my numbers under a line. */
#trade-screen .controls { display: flex; flex-direction: column; gap: 10px; }
#trade-screen .controls > .panel { background: none; border: none; border-radius: 0; padding: 0; }
#trade-screen .controls > .numbers-panel { border-top: 1px solid var(--line); padding-top: 10px; }
/* Under the book there is no room for the "Trade or Tighten" heading; the status pill in the
   title bar already says which step the market is at. */
@container market (max-width: 759px) {
  .tot-panel h2 { display: none; }
}

.panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px 16px;
  min-width: 0;
}
.panel h2 {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--muted);
  margin-bottom: 12px;
}
/* A panel heading with something on its right, e.g. the Trades panel's All / Mine. */
.panel-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.toggle { display: flex; }
.toggle button {
  background: transparent;
  color: var(--muted);
  border: 1px solid var(--line);
  border-radius: 0;
  padding: 2px 10px;
  font: 500 11px system-ui, sans-serif;
}
.toggle button:first-child { border-radius: 6px 0 0 6px; }
.toggle button:last-child { border-radius: 0 6px 6px 0; border-left: none; }
.toggle button.on { background: var(--accent-soft); color: var(--text); border-color: var(--accent); }
/* Amending a resting order: its price and size become boxes (Q133). */
#my-orders input { width: 100%; padding: 2px 6px; text-align: right; font-size: 13px; }
#my-orders td:last-child { white-space: nowrap; overflow: visible; }
#my-orders button.icon:hover { color: var(--text); }
#my-orders button.icon.cancel:hover { color: var(--ask); }
.panel h3 { font-size: 12px; color: var(--muted); font-weight: 500; margin: 14px 0 8px; }
/* Tighter panels on the trading screen, so everything fits. */
#trade-screen .panel { padding: 10px 12px; }
#trade-screen .panel h2 { margin-bottom: 8px; }

/* The sidebar: Resting orders is only as tall as its orders (up to 30% of the height),
   Positions and Trades share the rest. Each list scrolls inside its box, under its heading. */
.sidebar { gap: 12px; min-height: 0; }
.sidebar .panel { display: flex; flex-direction: column; min-height: 0; }
.sidebar .orders-panel { flex: 0 1 auto; max-height: 30%; }
.sidebar .grow { flex: 1 1 0; }
.sidebar .scroll {
  flex: 1 1 auto;
  min-height: 0;
  max-height: none;
  scrollbar-width: thin;                         /* dark scrollbars, to match the page */
  scrollbar-color: var(--line) transparent;
}

/* --- Order entry --------------------------------------------------------------------------- */

.entry {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 76px 76px;
  gap: 8px;
  margin-bottom: 8px;
}
.entry.quote { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) 76px; }
.entry.quote button { grid-column: 1 / -1; }
.entry.single { grid-template-columns: minmax(0, 1fr) auto; }
/* The market maker's quote: bid, offer, then the button on its own line. */
.entry.pair { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.entry.pair button { grid-column: 1 / -1; }

/* In a market's column: smaller boxes, and the two-sided quote on one line (bid, offer, size,
   button) unless the column is very narrow or the controls are in their own side column. */
.market input { padding: 6px 8px; }
.market button { padding: 7px 10px; white-space: nowrap; }
.market .entry { gap: 6px; margin-bottom: 6px; }
.market .entry:last-child { margin-bottom: 0; }
.market .entry.quote { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) 60px 76px; }
.market .entry.quote button { grid-column: auto; }
@container market (max-width: 280px) {
  .market .entry { grid-template-columns: minmax(0, 1fr) 52px 60px; }
  .market .entry.quote { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) 52px; }
  .market .entry.quote button { grid-column: 1 / -1; }
}
@container market (min-width: 760px) {
  .market .entry.quote { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) 76px; }
  .market .entry.quote button { grid-column: 1 / -1; }
}
/* The width form and the market maker's quote keep their own shapes (the rules above are for
   the Bid and Offer forms). */
.market .entry.single { grid-template-columns: minmax(0, 1fr) auto; }
.market .entry.pair { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }

/* --- Trade or Tighten ---------------------------------------------------------------------- */

.tot-line { margin: 0 0 8px; }
.tot-line b { font-family: var(--mono); }
.hint { margin: 4px 0 0; color: var(--muted); font-size: 12px; }
.forced-buttons { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.market .forced-buttons button { padding: 10px 8px; font-size: 14px; }
.forced-buttons button span { font-family: var(--mono); }
/* Once a side is chosen, the other one fades (it can still be clicked to switch). */
.forced-buttons.decided button:not(.chosen) { opacity: 0.35; }
.forced-buttons button.chosen { outline: 2px solid var(--text); outline-offset: 2px; }
#tape tr.forced td:first-child { box-shadow: inset 3px 0 0 var(--accent); }

/* --- My numbers ---------------------------------------------------------------------------- */

/* Four tiles in one row under the book; 2 x 2 in a very narrow column, or when the controls
   have their own side column. */
.tiles { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; }
@container market (max-width: 360px) {
  .tiles { grid-template-columns: 1fr 1fr; }
}
@container market (min-width: 760px) {
  .tiles { grid-template-columns: 1fr 1fr; }
}
.tile {
  background: var(--panel-raised);
  border-radius: 8px;
  padding: 5px 10px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  line-height: 1.2;
}
.tile b { font: 600 16px/1.2 var(--mono); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* The average price next to my position: smaller and grey, so the position still stands out. */
.tile .average { font-size: 12px; font-weight: 500; color: var(--muted); }

/* --- Tables -------------------------------------------------------------------------------- */

table { width: 100%; border-collapse: collapse; }
th {
  text-align: left;
  font-weight: 500;
  font-size: 11px;
  color: var(--muted);
  padding: 0 8px 8px;
  border-bottom: 1px solid var(--line);
}
td {
  padding: 6px 8px;
  border-bottom: 1px solid rgba(28, 33, 43, 0.6);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
tbody tr:last-child td { border-bottom: none; }
.num, td.num { text-align: right; font-family: var(--mono); }
.right { text-align: right; }
.price { text-align: center; }
.empty td { color: var(--muted); text-align: center; padding: 18px; }
/* Shorter rows in the sidebar's lists. */
.sidebar td { padding: 4px 8px; line-height: 1.3; }
.sidebar .empty td { padding: 10px; }

/* My resting orders, in the sidebar. Long market titles end in "…" (full title on hover). */
#my-orders { table-layout: fixed; }
#my-orders th:nth-child(2) { width: 56px; }  /* side */
#my-orders th:nth-child(3) { width: 84px; }  /* price */
#my-orders th:nth-child(4) { width: 52px; }  /* size */
#my-orders th:nth-child(5) { width: 64px; }  /* amend and cancel */
#my-orders td:first-child { color: var(--muted); }
#my-orders td:last-child { text-align: right; }

.cancel-all { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.cancel-all button { font-size: 12px; padding: 6px 8px; }

/* Positions: one column per market. Long market titles end in "…" (full title on hover). */
#positions { table-layout: fixed; }
#positions th:first-child { width: 34%; }
#positions th { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#positions tr.mine td { background: var(--accent-soft); }
#positions tr.mine td:first-child { box-shadow: inset 3px 0 0 var(--accent); }

.scroll { max-height: 420px; overflow-y: auto; }
.scroll th { position: sticky; top: 0; z-index: 1; background: var(--panel); }
#tape { table-layout: fixed; }
#tape td { font-size: 13px; padding: 4px 6px; }
#tape th:nth-child(1) { width: 70px; }  /* time */
#tape th:nth-child(2) { width: 22%; }   /* market */
#tape th:nth-child(5) { width: 72px; }  /* price */
#tape th:nth-child(6) { width: 44px; }  /* size */
/* "Mine": Time | Market | Side | Price | Size | With */
#tape.mine th:nth-child(2) { width: 15%; }   /* market (narrower, to make room for "With") */
#tape.mine th:nth-child(3) { width: 44px; }  /* side */
#tape.mine th:nth-child(4) { width: 72px; }  /* price */
#tape.mine th:nth-child(5) { width: 44px; }  /* size */
#tape.mine th:nth-child(6) { width: auto; }  /* with */
#tape td:nth-child(2) { color: var(--muted); }
#tape td:first-child { color: var(--muted); font-family: var(--mono); font-size: 12px; }
#tape tr.fresh td { animation: flash 1.6s ease-out; }
@keyframes flash { from { background: var(--accent-soft); } to { background: transparent; } }

/* --- Order book ---------------------------------------------------------------------------- */

/* The book's panel is a size container named "book", so its rows can share its height. It is
   never shorter than its rows at their smallest (20px each, --book-rows is set by renderBook). */
.book-panel {
  container: book / size;
  min-height: calc(var(--book-rows, 22) * 20px + 10px);
  overflow: hidden;
}
#trade-screen .book-panel { padding: 4px 8px; }
/* Every row is exactly one line and the same height, so the book never changes shape and the
   best bid and offer stay put (see renderBook in trader.js). The rows share the panel's whole
   height equally (--book-rows, set by renderBook: both sides, the divider and the heading),
   never less than 20px each.
   The text grows with the space. --font is the size of the prices: as big as the row height
   allows (so text never stretches a row) and as the book's width allows (so the names keep
   about 40% of it), between 12px and 26px. Sizes are a little smaller, and names smaller
   still, so more of them fit. The price and size columns are as wide as their numbers need at
   that size (prices up to "-123,000", sizes up to "1,250"), and the names get the rest. Names
   that don't fit end in "…"; hovering the row shows them all. */
.book {
  table-layout: fixed;
  --pad: 10px;  /* space at each side of a cell */
  --row: calc((100cqh - 4px) / var(--book-rows, 22));
  --font: clamp(12px, min(var(--row) * 0.62, (60cqw - 6 * var(--pad)) / 10.2), 26px);
}
.book th:nth-child(2), .book th:nth-child(4) { width: calc(var(--font) * 2.6 + 2 * var(--pad)); }
.book th:nth-child(3) { width: calc(var(--font) * 5 + 2 * var(--pad)); }
.book tr { height: max(20px, var(--row)); }
.book th {
  padding: 0 var(--pad);
  font-size: max(11px, var(--font) * 0.6);
  line-height: 1.2;
  vertical-align: middle;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.book td {
  padding: 0 var(--pad);
  font-size: calc(var(--font) * 0.85);
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.book td.names { color: var(--muted); font-size: max(12px, var(--font) * 0.65); }
.book td.price { font: 700 var(--font)/1.2 var(--mono); }
.book tr.bid td.price { color: var(--bid); }
.book tr.ask td.price { color: var(--ask); }

/* Depth bars: the size cell fills in proportion to the size resting at that level. */
.book tr.bid td.depth {
  background: linear-gradient(to left, var(--bid-soft) var(--depth), transparent var(--depth));
}
.book tr.ask td.depth {
  background: linear-gradient(to right, var(--ask-soft) var(--depth), transparent var(--depth));
}

/* The best bid and offer are the clickable rows. */
.book tr.clickable { cursor: pointer; }
.book tr.clickable td { color: var(--text); font-weight: 600; }
.book tr.clickable.bid td { background-color: var(--bid-soft); }
.book tr.clickable.ask td { background-color: var(--ask-soft); }
.book tr.clickable:hover td { background-color: transparent; }
.book tr.clickable.bid:hover { outline: 1px solid var(--bid); outline-offset: -1px; }
.book tr.clickable.ask:hover { outline: 1px solid var(--ask); outline-offset: -1px; }
/* Deeper levels: clicking one copies its price into the Bid or Offer box (Q139). */
.book tr.fillable { cursor: pointer; }
.book tr.fillable:hover { outline: 1px dashed var(--muted); outline-offset: -1px; }
.book { user-select: none; }  /* so a shift-click doesn't select text */

/* My own orders get a blue edge. */
.book tr.mine td:first-child { box-shadow: inset 3px 0 0 var(--accent); }

/* The divider between offers and bids: last price and mark. */
.book tr.spread td {
  text-align: center;
  font: max(12px, var(--font) * 0.65)/1.2 var(--mono);
  color: var(--muted);
  padding: 0 var(--pad);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.book tr.spread b { color: var(--text); font-weight: 600; }

/* A narrow book (several markets side by side, or a phone): less space around each cell, so
   the names still fit. */
@container book (max-width: 480px) {
  .book { --pad: 5px; }
}

/* --- Fallbacks ----------------------------------------------------------------------------- */

/* Narrow windows (Q84): markets one under another (full width), then the sidebar, and the
   page scrolls like a normal web page. Rows go back to a fixed height and lists to a fixed
   box height, because there is no window height to share out. */
@media (max-width: 1100px) {
  #trade-screen { height: auto; min-height: 0; }
  .terminal { grid-template-columns: 1fr; grid-template-rows: none; }
  .market-area #markets { grid-auto-flow: row; grid-template-rows: none; }
  .market-body { grid-template-rows: auto; }
  .book-panel { container-type: inline-size; }
  .book { --row: 30px; }
  .sidebar .orders-panel { max-height: none; }
  .sidebar .grow { flex: none; }  /* no window height to share, so each list is its own height */
  .sidebar .scroll { max-height: 420px; }
}

@media (max-width: 600px) {
  .topbar, .terminal, #trade-screen .topbar { padding-left: 16px; padding-right: 16px; }
  #banner { left: 16px; right: 16px; }
}

/* --- Admin page ---------------------------------------------------------------------------- */

.room-code { flex: 1; display: flex; align-items: baseline; gap: 10px; }
.room-code small {
  color: var(--muted);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.room-code b { font: 700 28px var(--mono); letter-spacing: 0.12em; color: var(--accent); }

.admin {
  display: grid;
  grid-template-columns: minmax(280px, 360px) minmax(0, 1fr);
  gap: 14px;
  padding: 0 20px 20px;
  align-items: start;
}
@media (max-width: 900px) {
  .admin { grid-template-columns: 1fr; }
}

/* The true value entered in advance: dots, not digits, in case the admin page is projected. */
input.secret { -webkit-text-security: disc; }
.action-row .trading-clock { font-family: var(--mono); min-width: 3.5em; }
.bot-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 10px; }
.bot-row .hint { margin-top: 2px; }
.bot-row button { padding: 5px 12px; font-size: 12px; flex-shrink: 0; }
.stat.airtable span { font-size: 11px; max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.form-buttons { display: flex; gap: 8px; }
.form-buttons button { flex: 1; }

.entry.info { grid-template-columns: minmax(0, 1fr) auto; }
#info-drops td:last-child { white-space: normal; }

.scroll-x { overflow-x: auto; }
#markets td.title { max-width: 260px; }
.action-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.action-row button { padding: 5px 10px; font-size: 12px; }
.settle-value { width: 110px; padding: 4px 8px; }
.action-row .tot-status { color: var(--muted); font-size: 12px; }
.action-row .tot-status b { color: var(--text); font-family: var(--mono); }
th.market-head-cell {
  max-width: 160px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-align: center;
  color: var(--text);
}
#traders tr.kicked td { color: var(--muted); }

/* --- Review page (the projector) ----------------------------------------------------------- */

.picker { display: flex; flex-direction: column; gap: 2px; }
.picker small {
  color: var(--muted);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
select {
  min-width: 180px;
  max-width: 320px;
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 7px;
  padding: 6px 8px;
  font: 14px system-ui, sans-serif;
}
select:focus { outline: none; border-color: var(--accent); }

.review { display: flex; flex-direction: column; gap: 14px; padding: 0 20px 20px; }
.chart-head { display: flex; align-items: baseline; gap: 18px; flex-wrap: wrap; }
.legend { display: flex; gap: 16px; flex-wrap: wrap; color: var(--muted); font-size: 12px; margin-bottom: 12px; }
.legend span { display: flex; align-items: center; gap: 6px; }
.chart-range { display: flex; gap: 12px; margin-left: auto; margin-bottom: 12px; }
.chart-range label { display: flex; align-items: center; gap: 6px; color: var(--muted); font-size: 12px; }
.chart-range input { width: 110px; }
.key { display: inline-block; width: 18px; height: 0; border-top: 2px solid; }
.key.mark { border-color: var(--accent); }
.key.last { border-color: var(--muted); border-top-style: dashed; }
.key.drop { border-color: #eab308; border-top-style: dashed; }
.key.settle { border-color: var(--text); }

#chart { width: 100%; }
.chart { display: block; }
.chart .grid { stroke: var(--line); }
.chart .axis { fill: var(--muted); font: 11px var(--mono); }
.chart .line { fill: none; stroke-linejoin: round; }
.chart .line.mark { stroke: var(--accent); stroke-width: 2.5; }
.chart .line.last { stroke: var(--muted); stroke-width: 1.5; stroke-dasharray: 5 4; }
.chart .fill.buy { fill: var(--bid); }
.chart .fill.sell { fill: var(--ask); }
.chart .fill { stroke: var(--bg); stroke-width: 1; }
.chart .drop { stroke: #eab308; stroke-width: 1.5; stroke-dasharray: 4 4; }
.chart .drop-note { fill: #eab308; font-size: 11px; }
.chart .settle { stroke: var(--text); stroke-width: 1.5; }
.chart .settle-note { fill: var(--text); font: 600 12px var(--mono); }

/* Bigger text than the trading pages, for reading from the back of the room. */
#fills td { font-size: 15px; padding: 8px 10px; }
#fills th { font-size: 12px; padding: 0 10px 8px; }
#fills tr.forced td:first-child { box-shadow: inset 3px 0 0 var(--accent); }
#fills tr.drop td { color: #eab308; background: rgba(234, 179, 8, 0.08); white-space: normal; }
#fills tr.total td { font-weight: 700; border-top: 1px solid var(--line); }

/* The Review | Leaderboard switch (SPEC Q156): <body> gets the class "leaderboard-view" when
   the leaderboard is on, which hides the review's pickers, chart and trades. The pickers keep
   their space, so the top bar (and the switch) don't move. */
.view-switch button { padding: 5px 14px; font-size: 13px; }
.leaderboard-view main.review-only { display: none; }
.leaderboard-view .topbar .review-only { visibility: hidden; }
body:not(.leaderboard-view) .leaderboard-only { display: none; }
#leaderboard td { font-size: 18px; padding: 8px 12px; }
#leaderboard th { font-size: 12px; padding: 0 12px 8px; }
#leaderboard tr.kicked td { color: var(--muted); }

@media (max-width: 600px) {
  .review { padding-left: 16px; padding-right: 16px; }
  select { min-width: 0; }
}

/* --- Member games (SPEC Q253-Q261) --------------------------------------------------------- */

/* "Start your own game" under the join form. */
.start-game { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--line); text-align: center; }
.start-game-heading {
  margin: 0 0 10px; color: var(--text); font-size: 12px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.08em;
}
/* Blue like "Join the market", but outlined, so the two buttons don't compete. */
button.host {
  width: 100%;
  padding: 11px;
  background: var(--accent-soft);
  color: #8fb4f0;
  border: 1px solid var(--accent);
  font-size: 14px;
}
button.host:hover { background: var(--accent); color: #fff; filter: none; }
.start-game .hint { margin-top: 8px; }
.tagline.connecting { margin-bottom: 0; }
.stat.member-game span { font-size: 11px; }
