/* ═══════════════════════════════════════════════════════════════
   MarketCompass — Matt Edition
   Dark theme, palette borrowed from the v2 dashboard. No framework,
   no build step, no remote assets.
═══════════════════════════════════════════════════════════════ */

:root {
  --bg-base:        #0f1117;
  --bg-panel:       #161b27;
  --bg-card:        #1c2333;
  --bg-card-hover:  #212b3d;
  --bg-input:       #1a2030;
  --bg-chart:       #131722;

  --border:         #2a3349;
  --border-light:   #1f2d44;

  /* Chart-card surface. Taken from v2's .screener-card, which sits at the chart
     canvas's OWN colour (--bg-chart) behind a darker hairline rather than the
     lighter --bg-card. That is what makes a card read as one continuous dark
     surface with a chart inside it; at --bg-card the frame is perceptibly
     lighter and bluer than the canvas and the charts stand out against it.
     Everything else here — base, panel, header, borders, text — already matches
     v2's token block value for value. */
  --border-chart:   #1e2438;

  --text-primary:   #e8edf4;
  --text-secondary: #8b97ad;
  --text-muted:     #5a6478;

  --accent:         #4a7fd4;
  --accent-hover:   #5a8fe4;
  --green:          #3ddc84;
  --red:            #e05252;
  /* v2's --yellow. Used by the stats block for a low relative-strength rating
     and a near-term earnings date — a caution, not a loss, so not --red. */
  --yellow:         #f5c842;

  --font:      -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --font-mono: 'SF Mono', 'SFMono-Regular', Menlo, Consolas, monospace;

  --radius-sm: 4px;
  --radius-md: 8px;
}

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

html, body {
  height: 100%;
  overflow: hidden;               /* rail and grid scroll on their own */
}

body {
  display: flex;
  flex-direction: column;
  background: var(--bg-base);
  color: var(--text-primary);
  font-family: var(--font);
  font-size: 13px;
  -webkit-font-smoothing: antialiased;
}

/* ── Shared controls ─────────────────────────────────────────── */

.btn {
  background: var(--bg-input);
  color: var(--text-primary);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 4px 10px;
  font: inherit;
  cursor: pointer;
}
.btn:hover:not(:disabled) { background: var(--bg-card-hover); border-color: var(--accent); }
.btn:disabled { opacity: 0.4; cursor: default; }
.btn-icon { padding: 4px 8px; line-height: 1; }
.btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn-primary:hover { background: var(--accent-hover); }

/* ── Header ──────────────────────────────────────────────────── */

.topbar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 8px 14px;
  background: var(--bg-panel);
  border-bottom: 1px solid var(--border);
}

.brand { font-size: 15px; font-weight: 600; white-space: nowrap; }
.brand-tag {
  margin-left: 7px;
  padding: 2px 6px;
  border-radius: var(--radius-sm);
  background: rgba(74, 127, 212, 0.15);
  color: var(--accent);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.market-pill {
  padding: 3px 9px;
  border-radius: 999px;
  background: rgba(139, 151, 173, 0.14);
  color: var(--text-secondary);
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
}
.market-pill.open { background: rgba(61, 220, 132, 0.14); color: var(--green); }

.data-age {
  color: var(--text-muted);
  font-size: 11px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.data-age.historical { color: #f5c842; }

/* The list switch moved into the rail, so the date navigation carries the auto
   margin again and travels against the right edge on its own. */
.date-nav { display: flex; align-items: center; gap: 6px; margin-left: auto; }
.date-input {
  background: var(--bg-input);
  color: var(--text-primary);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 3px 6px;
  font: inherit;
  color-scheme: dark;             /* native picker follows the dark theme */
}

.topbar-right { display: flex; align-items: center; gap: 12px; }
.logout-link { color: var(--text-muted); font-size: 11px; text-decoration: none; }
.logout-link:hover { color: var(--text-secondary); text-decoration: underline; }

/* ── Layout ──────────────────────────────────────────────────── */

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

.rail {
  flex: 0 0 350px;
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: var(--bg-panel);
  border-right: 1px solid var(--border);
}
/* List switch — six row sets in three rows, sitting above the symbol table it
   chooses the contents of. Never scrolls with the list: it is the control that
   says what the list IS, so scrolling it out of sight would leave no answer on
   screen to "what am I looking at". */
.rail-lists {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 8px 10px;
  border-bottom: 1px solid var(--border);
}

/* Each row fills the rail and splits it evenly, so all three line up on their
   outer edges however many buttons a row holds. Labels ellipsise rather than
   wrap — a two-line button would break the row rhythm, and every label here is
   short enough that truncation is a safety net rather than the normal case. */
.rail-lists .segmented { display: flex; }
.rail-lists .segmented button {
  flex: 1 1 0;
  min-width: 0;
  padding: 4px 6px;
  font-size: 11px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.rail-scroll { flex: 1 1 auto; overflow-y: auto; overflow-x: hidden; }
.rail-footer {
  flex: 0 0 auto;
  padding: 6px 10px;
  border-top: 1px solid var(--border);
  color: var(--text-muted);
  font-size: 11px;
}
.rail-footer-row { display: flex; align-items: baseline; gap: 8px; }

/* Transient status line — a clipboard confirmation, or a star that failed to
   save. Kept in flow with its space reserved by the row's gap, so a message
   appearing never nudges the count or the buttons. */
.rail-status {
  margin-left: auto;
  opacity: 0;
  transition: opacity 0.35s ease;
  color: var(--text-secondary);
}
.rail-status.visible { opacity: 1; }

/* A failed write. Red because it is the only thing on screen saying the change
   did not happen — a grey line beside a star that has just snapped back would
   read as decoration rather than as the explanation for it. */
.rail-status.error { color: var(--red); font-weight: 600; }

.rail-copy { display: flex; gap: 6px; margin-top: 6px; }
.rail-copy .btn-mini { flex: 1 1 0; min-width: 0; }

/* Compact variant of .btn for the two rail-footer actions. Flex so the icon
   sits on the label's optical centre rather than its text baseline, which is
   where an inline SVG would otherwise land. */
.btn-mini {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  padding: 3px 6px;
  font-size: 10px;
  color: var(--text-secondary);
}

/* Truncation moved off the button and onto the label. Once the button is a flex
   container its bare text is an anonymous flex item, and text-overflow cannot
   ellipsise one of those — a narrow rail would clip mid-letter instead. */
.btn-mini-label {
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Stroke-drawn in the button's own colour, so the icon follows the hover and
   disabled states with no rule of its own. Never shrinks: at these widths the
   label is what gives way, since it is the part that can still be read
   truncated. */
.btn-mini-icon {
  flex: 0 0 auto;
  width: 12px;
  height: 12px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Geometry store only — never rendered itself. */
.icon-sprite { display: none; }

/* ── Ranking table ───────────────────────────────────────────── */

.rank-table { width: 100%; border-collapse: collapse; }

.rank-table th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--bg-panel);
  border-bottom: 1px solid var(--border);
  padding: 7px 4px;
  color: var(--text-secondary);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  text-align: left;
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}
.rank-table th:hover { color: var(--text-primary); }
.rank-table th.sorted { color: var(--accent); }
.rank-table th.sorted::after { content: ' ▲'; font-size: 8px; }
.rank-table th.sorted-desc::after { content: ' ▼'; }

/* 4px of horizontal padding, not 8: eight columns have to fit a 350px rail
   without the table's min-content width pushing the rail wider and stealing
   the chart grid's space. The first and last cells get their outer edge back
   below, so the list still breathes against the panel edges. */
.rank-table td {
  padding: 5px 4px;
  border-bottom: 1px solid var(--border-light);
  white-space: nowrap;
}
.rank-table th:first-child, .rank-table td:first-child { padding-left: 8px; }
.rank-table th:last-child,  .rank-table td:last-child  { padding-right: 8px; }
.rank-row { cursor: pointer; }
.rank-row:hover td { background: var(--bg-card-hover); }

.col-rank   { width: 34px; color: var(--text-muted); font-family: var(--font-mono); }
.col-symbol { font-weight: 600; }
.col-num    { text-align: right; font-family: var(--font-mono); font-size: 12px; }
.col-star   { width: 28px; text-align: center; }

/* Relative volume. Neutral — unlike v2's rail, which tints it at 1.5x and 3x;
   here Chg% is the only coloured measure, and a second one competes with it. */
.col-rvol   { color: var(--text-secondary); }
th.col-num  { text-align: right; }  /* .rank-table th outranks .col-num above */
th.col-star { text-align: center; }

/* Gap-dot column — a visual anchor, not a data column, so it is given the
   narrowest width that still fits a 6px dot and its own padding is cut to the
   minimum. The header glyph stands in for a word that would not fit. */
.col-dot    { width: 10px; padding-left: 2px; padding-right: 2px; text-align: center; }
th.col-dot  { padding-left: 2px; padding-right: 2px; text-align: center; font-size: 8px; }
/* The shared .gap-dot carries a left margin for sitting AFTER a symbol; in its
   own centred column that margin would push it off centre. */
.col-dot .gap-dot { margin-left: 0; }
.pos { color: var(--green); }
.neg { color: var(--red); }

.star-btn {
  background: none;
  border: none;
  padding: 0 2px;
  color: var(--text-muted);
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
}
.star-btn:hover   { color: var(--text-secondary); }
.star-btn.starred { color: #f5c842; }

/* "Gapped down, recovered" marker — v2's .stock-row-gap-dot, value for value.
   Shared by the ranking table and the chart card header, like .star-btn above.
   In the table it sits in its own column (see .col-dot); on a card it lives
   INSIDE the symbol span, so it is never a flex item of .card-head and cannot
   be the thing that gives way when a long company name runs out of room. */
.gap-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-left: 5px;
  border-radius: 50%;
  background: var(--green);
  vertical-align: middle;
}

/* ── Chart grid ──────────────────────────────────────────────── */

.grid-pane { flex: 1 1 auto; display: flex; flex-direction: column; min-width: 0; min-height: 0; }

.grid-toolbar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 7px 12px;
  background: var(--bg-panel);
  border-bottom: 1px solid var(--border);
}

.segmented { display: inline-flex; border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: hidden; }
.segmented button {
  background: var(--bg-input);
  color: var(--text-secondary);
  border: none;
  border-right: 1px solid var(--border);
  padding: 4px 12px;
  font: inherit;
  cursor: pointer;
}
.segmented button:last-child { border-right: none; }
.segmented button:hover:not(:disabled) { color: var(--text-primary); }
.segmented button.active { background: var(--accent); color: #fff; }

/* The five current-day lists off the newest date. Matches .btn:disabled's
   treatment, so a dead control reads the same wherever it appears; the :hover
   rule above is guarded rather than overridden here, since a hover colour that
   has to be undone is a hover colour that should not have applied. */
.segmented button:disabled { color: var(--text-muted); opacity: 0.4; cursor: default; }

.grid-scroll { flex: 1 1 auto; overflow-y: auto; overflow-x: hidden; padding: 12px; }

.chart-grid {
  display: grid;
  /* minmax(0, 1fr) is what keeps a wide chart from forcing a page-wide scroll */
  grid-template-columns: repeat(var(--grid-columns, 2), minmax(0, 1fr));
  gap: 12px;
}

.grid-message { padding: 24px; color: var(--text-secondary); }

/* Chart cards live in cards.css. */

/* ── Narrow laptops ──────────────────────────────────────────── */

@media (max-width: 1200px) {
  /* 290px until the RVOL column landed, which the table can no longer honour:
     eight columns of worst-case values have a min-content width of ~341px, and
     a flex item cannot shrink below that, so the old value was quietly
     overridden by the layout rather than applied. Stated at what it actually
     resolves to, so the stylesheet does not describe a width nothing uses. */
  .rail { flex-basis: 342px; }
  .brand-tag { display: none; }
}
