/* ===========================================================================
   THE TERMINAL, AS A PAGE.
   
   /city and /civ are the same screen as the exchange's floor terminal, and
   they were each carrying their own copy of it. Two copies of a design is a
   design that has already started to drift: the first thing that happens is
   somebody nudges a hairline on one page, and from then on the two screens are
   almost the same, which reads worse than either of them alone.

   So the chrome lives here and both pages link it. Every colour, face and
   hairline is still a token out of css/palette.css by way of css/casefile.css
   — nothing in this file invents a value. What stays on each page is only what
   that page has and the other does not: /city's listings and price moves,
   /civ's map, graph and census.

   ON THE MONO FACE: casefile.css reaches for var(--gr-mono) in fifteen places
   and for a long time nothing defined it, so the in-game terminals' "mono" text
   rendered in the body sans. The token exists now (css/palette.css), but these
   pages still name --cf-mono directly, because that is the variable the case
   file's own rules are written against and one page should not depend on which
   of two aliases happens to resolve.
   ======================================================================== */

*{box-sizing:border-box}
html,body{margin:0;background:var(--gr-bg);color:var(--cf-ink);font-family:var(--cf-body)}
body{padding:18px 20px 28px;-webkit-font-smoothing:antialiased}
a{color:inherit}

.ct-screen{max-width:1680px;margin:0 auto;background:var(--cf-card);
  border:1px solid var(--cf-edge-lit);box-shadow:0 30px 90px rgba(0,0,0,.66);
  padding:14px 16px 12px;display:flex;flex-direction:column;gap:10px}

/* ---- the framed header ---- */
.ct-head{display:flex;align-items:baseline;gap:14px;flex-wrap:wrap;padding-top:4px}
.ct-night{font-family:var(--cf-mono);font-size:11px;letter-spacing:.2em;color:var(--cf-ink-faint)}
.ct-night b{color:var(--cf-ink-dim)}
.ct-live{margin-left:auto;display:flex;align-items:center;gap:7px;
  font-family:var(--cf-mono);font-size:9px;letter-spacing:.22em;color:var(--cf-ink-faint)}
.ct-dot{width:7px;height:7px;border-radius:50%;background:var(--cf-accent);
  box-shadow:0 0 8px var(--gr-accent-a4);animation:ctp 2.4s ease-in-out infinite}
.ct-dot.off{background:var(--cf-ink-4);box-shadow:none;animation:none}
@keyframes ctp{0%,100%{opacity:1}50%{opacity:.35}}

/* ---- the tape ---- */
.ct-tape{display:flex;align-items:center;gap:12px;min-width:0;
  border-top:1px solid var(--cf-edge);border-bottom:1px solid var(--cf-edge);padding:8px 0}
.ct-tapelab{flex:none;font-family:var(--cf-mono);font-size:9px;letter-spacing:.22em;color:var(--cf-ink-faint)}
.ct-tapeline{font-family:var(--cf-mono);font-size:12px;letter-spacing:.05em;color:var(--cf-ink-dim);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.ct-tapeline b{color:var(--cf-ink);font-weight:700}
.ct-tapeline .who{color:var(--cf-accent)}

/* ---- the two-column body ---- */
.ct-body{display:grid;grid-template-columns:400px 1fr;gap:18px;min-height:0}
.ct-body.even{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
.ct-col{min-width:0;display:flex;flex-direction:column;gap:10px}

/* ---- the field grid (the exchange's .ft-pos) ---- */
/* EACH FIELD IS ITS OWN CELL. The first cut pinned the label, value and note
   to grid-row 1, 2 and 3 — which makes grid lay eight items along row one
   whatever the column count says, inventing implicit columns and running
   straight off the side of a phone. A cell that carries its own three lines
   wraps at any width. */
.ct-fields{display:grid;grid-template-columns:repeat(8,minmax(0,1fr));gap:12px 14px}
.ct-fields.six{grid-template-columns:repeat(6,minmax(0,1fr))}
.ct-f{min-width:0;display:flex;flex-direction:column;gap:3px}
.ct-f .k{font-family:var(--cf-mono);font-size:8.5px;letter-spacing:.18em;color:var(--cf-ink-faint)}
.ct-f .v{font-family:var(--cf-mono);font-size:19px;line-height:1;color:var(--cf-ink)}
.ct-f .v.lit{color:var(--cf-accent)}
.ct-f .s{font-family:var(--cf-mono);font-size:8.5px;letter-spacing:.1em;color:var(--cf-ink-faint)}

/* ---- tables ---- */
.ct-tablewrap{max-height:340px;overflow:auto;border-top:1px solid var(--cf-edge)}
table.ct-t{width:100%;border-collapse:collapse;font-size:12px}
.ct-t th{position:sticky;top:0;background:var(--cf-card);text-align:left;
  font-family:var(--cf-mono);font-size:8.5px;letter-spacing:.2em;font-weight:600;
  color:var(--cf-ink-faint);padding:7px 9px;border-bottom:1px solid var(--cf-edge)}
.ct-t td{padding:6px 9px;border-bottom:1px solid rgba(237,230,214,.05);color:var(--cf-ink-dim);vertical-align:top}
.ct-t tr:hover td{background:var(--cf-card-hi)}
.ct-t .nm{font-family:var(--cf-mono);font-size:11.5px;letter-spacing:.06em;color:var(--cf-ink);white-space:nowrap}
.ct-t .num{font-family:var(--cf-mono);text-align:right;color:var(--cf-ink);white-space:nowrap}
.ct-t .mono{font-family:var(--cf-mono);font-size:10.5px;letter-spacing:.08em;white-space:nowrap}
.ct-t .why{color:var(--cf-ink);font-size:12px;line-height:1.35}

/* ---- where somebody is, in the venue's own colour ---- */
.ct-where{font-family:var(--cf-mono);font-size:9.5px;letter-spacing:.14em;padding:1px 6px;border:1px solid var(--cf-edge)}
.ct-where.bar{color:#d8b45a;border-color:rgba(216,180,90,.32)}
.ct-where.gym{color:#7fb069;border-color:rgba(127,176,105,.32)}
.ct-where.casino{color:#b07fc9;border-color:rgba(176,127,201,.32)}
.ct-where.yard{color:#d98a5a;border-color:rgba(217,138,90,.32)}
.ct-where.market{color:#ff5fa8;border-color:rgba(255,95,168,.32)}
.ct-where.stall{color:#4fd8ff;border-color:rgba(79,216,255,.32)}
.ct-stalls{width:100%;border-collapse:collapse;margin-top:8px;font-family:var(--cf-mono);font-size:11px}
.ct-stalls th{text-align:left;font-weight:600;letter-spacing:.12em;font-size:9px;color:var(--cf-ink-dim);padding:3px 6px;border-bottom:1px solid var(--cf-edge)}
.ct-stalls td{padding:4px 6px;border-bottom:1px solid var(--cf-edge)}
.ct-stalls td.num{text-align:right;font-variant-numeric:tabular-nums}
.ct-stalls td.nm{color:var(--cf-ink)}
.ct-where.work{color:var(--cf-ink-dim);border-color:var(--cf-edge-lit);border-style:dashed}
.ct-where.in{color:var(--cf-ink-faint)}

/* ---- charts ---- */
/* EVERY AXIS SAYS WHAT IT COUNTS. A chart whose vertical is unlabelled is a
   shape, not a measurement, and the reader has to guess the unit from the
   caption — which is the same as not having one. */
.ct-chart{margin-top:4px}
.ct-chart svg{width:100%;height:170px;display:block;overflow:visible}
.ct-ax{font-family:var(--cf-mono);font-size:8.5px;letter-spacing:.14em;fill:var(--cf-ink-faint)}
.ct-axname{font-family:var(--cf-mono);font-size:8.5px;letter-spacing:.2em;fill:var(--cf-ink-dim)}
.ct-gl{stroke:var(--cf-edge);stroke-width:1;vector-effect:non-scaling-stroke}
.ct-ln{fill:none;stroke-width:1.6;vector-effect:non-scaling-stroke}
.ct-ln.turn{stroke:var(--cf-accent)}
.ct-ln.px{stroke:var(--cf-ink-3);stroke-dasharray:3 3}
.ct-bar{fill:var(--cf-ink-3)}
.ct-bar.lit{fill:var(--cf-accent)}
.ct-key{display:flex;gap:16px;margin-top:6px;font-family:var(--cf-mono);font-size:9px;letter-spacing:.14em;color:var(--cf-ink-faint)}
.ct-key i{display:inline-block;width:14px;height:0;border-top:2px solid currentColor;vertical-align:middle;margin-right:6px}
.ct-key .turn{color:var(--cf-accent)}
.ct-key .px{color:var(--cf-ink-3)}
.ct-key .sw{width:9px;height:9px;border-top:none;border-radius:50%;background:currentColor;vertical-align:-1px}

/* ---- A QUOTED BLOCK AND THE EVIDENCE UNDER IT ----------------------------
   Both pages have one: /city's price move with the sentences residents wrote
   about it, /civ's chronicle with the ledger lines each claim is cited to. The
   shape is the same because the rule is the same — a claim never appears
   without what it was read off. */
/* ---- a price move, and the evidence it actually has ---- */
.ct-move{border:1px solid var(--cf-edge);border-left:3px solid var(--cf-edge-lit);padding:10px 12px;margin-top:4px}
.ct-move .h{font-family:var(--cf-mono);font-size:12px;letter-spacing:.06em;color:var(--cf-ink)}
.ct-move .said{font-family:var(--cf-mono);font-size:9px;letter-spacing:.16em;color:var(--cf-accent);margin:7px 0 5px}
.ct-move .counts{font-family:var(--cf-mono);font-size:9px;letter-spacing:.12em;color:var(--cf-ink-faint);
  border-top:1px solid var(--cf-edge);margin-top:8px;padding-top:7px}
.ct-move .counts b{color:var(--cf-ink-dim)}

/* ---- quoted reactions ---- */
.ct-react{display:flex;flex-direction:column;gap:7px;margin-top:2px}
.ct-q{border-left:2px solid var(--cf-edge-lit);padding:2px 0 2px 10px}
.ct-q .n{font-family:var(--cf-mono);font-size:10px;letter-spacing:.12em;color:var(--cf-accent)}
.ct-q .t{font-size:12.5px;line-height:1.4;color:var(--cf-ink)}
.ct-q .m{font-family:var(--cf-mono);font-size:9px;letter-spacing:.1em;color:var(--cf-ink-faint)}


/* ---- the footer strip, and the empty state ---- */
.ct-foot{display:flex;gap:20px;flex-wrap:wrap;font-family:var(--cf-mono);font-size:9px;
  letter-spacing:.2em;color:var(--cf-ink-faint);border-top:1px solid var(--cf-edge);padding-top:9px}
.ct-foot b{color:var(--cf-ink-dim)}
.ct-foot .ok{color:var(--cf-accent)}
.ct-foot .bad{color:var(--cf-warn)}
/* NOTHING YET IS A SENTENCE, NOT A BLANK. A panel with no data says what it is
   waiting for, because an empty frame reads as a page that is broken. */
.ct-quiet{font-family:var(--cf-mono);font-size:10px;letter-spacing:.14em;color:var(--cf-ink-faint);padding:10px 0}

@media (max-width:1400px){ .ct-fields,.ct-fields.six{grid-template-columns:repeat(4,minmax(0,1fr))} }
@media (max-width:1100px){ .ct-body,.ct-body.even{grid-template-columns:1fr} }
@media (max-width:620px){
  .ct-fields,.ct-fields.six{grid-template-columns:repeat(2,minmax(0,1fr))}
  body{padding:10px 8px 20px}
  .ct-screen{padding:10px 10px 10px}
  .ct-t .hide-s{display:none}
  .ct-tablewrap{max-height:none}
}
body.film .ct-screen{max-width:1880px}
