/* ==========================================================================
   TERMINAL — reset, typography and the application shell
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--void);
  color: var(--text);
  font-family: var(--f-ui);
  font-size: var(--fs-base);
  font-variation-settings: "wdth" 100;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow: hidden;                 /* the shell scrolls its panes, not the page */
}

h1, h2, h3, h4, p, figure, ul, ol, dl, dd { margin: 0; }
ul, ol { padding: 0; list-style: none; }
button, input, select, textarea { font: inherit; color: inherit; }
a { color: inherit; text-decoration: none; }
svg { display: block; }

/* A size floor for every inline icon.

   An <svg> carrying only a viewBox has no intrinsic size, so it falls back to
   the replaced-element default of 300x150 and, in a flex row, stretches to the
   row. The kill-switch banner shipped that way: a 163px alert triangle filling
   a quarter of the screen. Sizing was being applied per container -- `.btn svg`,
   `.nav-item svg` -- which works right up until a container nobody wrote a rule
   for. Those rules are all more specific than this one and still win; this only
   catches the containers that were forgotten. */
.icon { width: 15px; height: 15px; flex-shrink: 0; }

/* Class-based display rules (.grid, .row, .col) otherwise win over the hidden
   attribute, which silently reveals conditionally-hidden fields. */
[hidden] { display: none !important; }

::selection { background: var(--accent-edge); color: var(--text-hi); }

/* Scrollbars are part of a dense UI's texture — make them deliberate. */
* { scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: var(--line-strong);
  border: 3px solid var(--base);
  border-radius: 6px;
}
*::-webkit-scrollbar-thumb:hover { background: var(--text-dim); }

/* Two pixels, not one. WCAG 2.2 asks for a focus indicator with real area,
   and a hairline on a dark ground is easy to lose -- particularly on the dense
   tables, which is exactly where keyboard navigation matters most. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

/* Skip link. Off-screen until focused, then the first thing in the tab order. */
.skip-link {
  position: absolute;
  left: var(--s3);
  top: -100px;
  z-index: 200;
  padding: var(--s2) var(--s3);
  background: var(--accent);
  color: var(--accent-text);
  border-radius: var(--r);
  font-size: var(--fs-sm);
  font-weight: 600;
  text-decoration: none;
  transition: top var(--t-fast) var(--ease);
}
.skip-link:focus { top: var(--s3); }

/* --------------------------------------------------------------------------
   Type roles
   -------------------------------------------------------------------------- */

/* Uppercase micro-labels. Used for every column header and section eyebrow —
   the repetition is what makes the interface feel like one instrument. */
.label {
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--text-lo);
  font-variation-settings: "wdth" 92;
}

.title {
  font-size: var(--fs-lg);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--text-hi);
  font-variation-settings: "wdth" 105;
}

.display {
  font-family: var(--f-num);
  font-size: var(--fs-3xl);
  font-weight: 500;
  letter-spacing: -0.03em;
  color: var(--text-hi);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

/* Every number in this application is monospaced and tabular. Columns of
   figures that do not align are the fastest way to look amateur. */
.num, td.num, .mono {
  font-family: var(--f-num);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "zero" 1;
  letter-spacing: -0.01em;
}

.pos { color: var(--pos); }
.neg { color: var(--neg); }
.flat { color: var(--flat); }
.dim { color: var(--text-lo); }
.hi  { color: var(--text-hi); }

/* Direction glyph carries the same meaning as the colour, for the ~8% of men
   with colour vision deficiency who would otherwise see only grey numbers. */
.delta::before { font-family: var(--f-num); margin-right: 3px; }
.delta.pos::before { content: "\25B2"; font-size: 0.7em; }
.delta.neg::before { content: "\25BC"; font-size: 0.7em; }
.delta.flat::before { content: "\2013"; }

/* --------------------------------------------------------------------------
   Shell layout
   -------------------------------------------------------------------------- */

.shell {
  display: grid;
  grid-template-columns: var(--rail-w) 1fr;
  grid-template-rows: var(--topbar-h) 1fr var(--statusbar-h);
  grid-template-areas:
    "rail topbar"
    "rail main"
    "status status";
  height: 100vh;
  transition: grid-template-columns var(--t) var(--ease);
}

.shell[data-rail="collapsed"] { grid-template-columns: var(--rail-w-collapsed); }

/* ---- left rail ---- */

.rail {
  grid-area: rail;
  background: var(--base);
  border-right: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}

.rail-brand {
  height: var(--topbar-h);
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: 0 var(--s4);
  border-bottom: 1px solid var(--line);
  flex-shrink: 0;
}

.brand-mark {
  width: 22px; height: 22px;
  flex-shrink: 0;
  border: 1px solid var(--accent-edge);
  border-radius: var(--r-sm);
  background: var(--accent-wash);
  display: grid;
  place-items: center;
  color: var(--accent);
}

.brand-name {
  font-weight: 700;
  font-size: var(--fs-sm);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-hi);
  font-variation-settings: "wdth" 88;
  white-space: nowrap;
}

.brand-mode {
  font-family: var(--f-num);
  font-size: 9px;
  letter-spacing: 0.12em;
  color: var(--accent);
  text-transform: uppercase;
}

.rail-nav {
  flex: 1;
  overflow-y: auto;
  padding: var(--s3) var(--s2);
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.nav-group + .nav-group { margin-top: var(--s4); }

.nav-group > .label {
  padding: 0 var(--s3) var(--s2);
  display: block;
}

.nav-item {
  display: flex;
  align-items: center;
  gap: var(--s3);
  height: 30px;
  padding: 0 var(--s3);
  border-radius: var(--r);
  color: var(--text-lo);
  font-size: var(--fs-base);
  font-weight: 500;
  white-space: nowrap;
  position: relative;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}

.nav-item svg { width: 15px; height: 15px; flex-shrink: 0; stroke-width: 1.6; }

.nav-item:hover { background: var(--raised); color: var(--text); }

.nav-item[aria-current="page"] {
  background: var(--accent-wash);
  color: var(--accent);
}

/* The active marker is a bar on the rail edge, not a filled pill — it reads as
   a physical indicator light rather than a web button. */
.nav-item[aria-current="page"]::before {
  content: "";
  position: absolute;
  left: calc(var(--s2) * -1);
  top: 6px; bottom: 6px;
  width: 2px;
  background: var(--accent);
  border-radius: 0 2px 2px 0;
}

.nav-count {
  margin-left: auto;
  font-family: var(--f-num);
  font-size: var(--fs-micro);
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}

.nav-item[aria-current="page"] .nav-count { color: var(--accent); }

.nav-dot {
  margin-left: auto;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--neg);
  box-shadow: 0 0 0 3px var(--neg-wash);
}

.shell[data-rail="collapsed"] .brand-name,
.shell[data-rail="collapsed"] .brand-mode,
.shell[data-rail="collapsed"] .nav-item span,
.shell[data-rail="collapsed"] .nav-count,
.shell[data-rail="collapsed"] .nav-group > .label,
.shell[data-rail="collapsed"] .rail-foot-text { display: none; }

.shell[data-rail="collapsed"] .nav-item { justify-content: center; padding: 0; }

.rail-foot {
  border-top: 1px solid var(--line);
  padding: var(--s3);
  display: flex;
  align-items: center;
  gap: var(--s3);
  flex-shrink: 0;
}

/* ---- topbar ---- */

.topbar {
  grid-area: topbar;
  background: var(--base);
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: center;
  gap: var(--s4);
  padding: 0 var(--s4);
  min-width: 0;
}

.crumb {
  display: flex;
  align-items: center;
  gap: var(--s2);
  min-width: 0;
}

.crumb-title {
  font-size: var(--fs-md);
  font-weight: 600;
  color: var(--text-hi);
  letter-spacing: -0.005em;
  white-space: nowrap;
}

.crumb-sub {
  font-size: var(--fs-tiny);
  color: var(--text-dim);
  white-space: nowrap;
}

.topbar-spacer { flex: 1; min-width: var(--s4); }

/* The right-hand cluster. Pages add their own controls here through
   `page_actions`, and the workspace adds seven of them -- a four-way layout
   switch plus three panel toggles -- which at 1280px made the cluster 745px
   wide and pushed the entire page 59px sideways. The design notes say wide
   content scrolls inside its own container and the body never does.

   `min-width: 0` lets it shrink below its content, and the overflow scrolls
   within the bar. `scrollbar-width: none` because a scrollbar inside a 40px
   toolbar is worse than the scroll being discovered by dragging. */
.topbar-actions {
  display: flex;
  align-items: center;
  gap: var(--s2);
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
}
.topbar-actions::-webkit-scrollbar { display: none; }
/* Controls keep their size rather than being squeezed into unreadability --
   a shrunken button is a worse answer than one you scroll to. */
.topbar-actions > * { flex-shrink: 0; }

/* Global search doubles as the command palette trigger. */
.omni {
  display: flex;
  align-items: center;
  gap: var(--s2);
  height: 28px;
  min-width: 260px;
  padding: 0 var(--s2) 0 var(--s3);
  background: var(--inset);
  border: 1px solid var(--line);
  border-radius: var(--r);
  color: var(--text-dim);
  font-size: var(--fs-sm);
  cursor: pointer;
  transition: border-color var(--t-fast) var(--ease);
}

.omni:hover { border-color: var(--line-strong); }
.omni svg { width: 13px; height: 13px; }
/* The label wrapped. `.omni` is 28px tall and its text had no `nowrap`, so on
   any screen whose page actions crowd the topbar -- the workspace's layout
   switch, the tax screen's six year chips -- "Search instruments, orders,
   commands" broke onto a second line and spilled out of the control. Truncated
   instead, which needs `nowrap` to work at all: `text-overflow` does nothing
   without it, which is the same pairing `layout_check` checks for. */
.omni > span:not(.omni-hint) {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.omni-hint {
  margin-left: auto;
  display: flex;
  gap: 2px;
}

/* ---- main ---- */

.main {
  grid-area: main;
  overflow: auto;
  background: var(--void);
  min-width: 0;
  min-height: 0;
}

/* Fill the scroll area even when the content is short. A page that stops
   two-thirds of the way down reads as a half-loaded page; giving it the full
   height lets a panel marked .fill take the slack instead of leaving a band of
   bare background under the last panel. */
.page {
  padding: var(--s5);
  display: flex;
  flex-direction: column;
  gap: var(--s4);
  max-width: 1800px;
  min-height: 100%;
}

.page-wide { max-width: none; }

/* ---- status bar: the thing that makes it feel like an instrument ---- */

.statusbar {
  grid-area: status;
  background: var(--base);
  border-top: 1px solid var(--line);
  display: flex;
  align-items: center;
  gap: 0;
  padding: 0 var(--s3);
  font-family: var(--f-num);
  font-size: var(--fs-micro);
  color: var(--text-lo);
  overflow-x: auto;
  overflow-y: hidden;
  white-space: nowrap;
}

.status-cell {
  display: flex;
  align-items: center;
  gap: var(--s2);
  padding: 0 var(--s3);
  height: 100%;
  border-right: 1px solid var(--line-soft);
  flex-shrink: 0;
}

.status-cell:last-child { border-right: 0; }
.status-cell.push { margin-left: auto; border-left: 1px solid var(--line-soft); border-right: 0; }

.status-key { color: var(--text-dim); letter-spacing: 0.06em; text-transform: uppercase; }
.status-val { color: var(--text); font-variant-numeric: tabular-nums; }
.status-val.ok { color: var(--pos); }
.status-val.warn { color: var(--warn); }
.status-val.bad { color: var(--neg); }

.led {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--flat);
  flex-shrink: 0;
}
.led.ok   { background: var(--pos); box-shadow: 0 0 6px var(--pos); }
.led.warn { background: var(--warn); box-shadow: 0 0 6px var(--warn); }
.led.bad  { background: var(--neg); box-shadow: 0 0 6px var(--neg); }
.led.live { background: var(--crit); box-shadow: 0 0 6px var(--crit); animation: pulse 2s var(--ease) infinite; }
/* The one thing on screen asking to be acted on. Amber would read as a warning
   -- four amber dots on a brand new account says something is wrong when
   nothing is -- and green and red are for money (DESIGN.md rule 4). */
.led.todo { background: var(--accent); box-shadow: 0 0 6px var(--accent); }
/* Done and blocked are both "nothing to do here", and they must still differ:
   filled reads as settled, hollow reads as not yet. */
.led.settled { background: var(--text-dim); box-shadow: none; }
.led.idle    { background: transparent; border: 1px solid var(--line-strong); box-shadow: none; }

@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.35; } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}
