/* Tokens from the validated reference palette; dark values swap under both the
   OS preference and the explicit data-theme toggle. */
:root {
  color-scheme: light;
  --surface-1: #fcfcfb;
  --page: #f9f9f7;
  --text-primary: #0b0b0b;
  --text-secondary: #52514e;
  --muted: #898781;
  --grid: #e1e0d9;
  --baseline: #c3c2b7;
  --border: rgba(11, 11, 11, 0.10);
  --accent: #2a78d6;
  --pos: #2a78d6;   /* bullish / heating (diverging blue pole) */
  --neg: #e34948;   /* bearish / cooling (diverging red pole) */
  --mid: #f0efec;
  --up: #006300;
}
@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) {
    color-scheme: dark;
    --surface-1: #1a1a19;
    --page: #0d0d0d;
    --text-primary: #ffffff;
    --text-secondary: #c3c2b7;
    --muted: #898781;
    --grid: #2c2c2a;
    --baseline: #383835;
    --border: rgba(255, 255, 255, 0.10);
    --accent: #3987e5;
    --pos: #3987e5;
    --neg: #e66767;
    --mid: #383835;
    --up: #0ca30c;
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --surface-1: #1a1a19;
  --page: #0d0d0d;
  --text-primary: #ffffff;
  --text-secondary: #c3c2b7;
  --muted: #898781;
  --grid: #2c2c2a;
  --baseline: #383835;
  --border: rgba(255, 255, 255, 0.10);
  --accent: #3987e5;
  --pos: #3987e5;
  --neg: #e66767;
  --mid: #383835;
  --up: #0ca30c;
}

* { box-sizing: border-box; }
body {
  margin: 0;
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  background: var(--page);
  color: var(--text-primary);
}
header {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  padding: 14px 20px 8px;
}
h1 { font-size: 20px; margin: 0; letter-spacing: -0.02em; }
h2 { font-size: 15px; margin: 0 0 8px; }
.filters { display: flex; gap: 8px; align-items: center; }
.scan-info { margin-left: auto; color: var(--muted); font-size: 12px; }
/* Second header row: the muted metadata the site links displaced — the scan
   line and the standing disclaimer. Inside it the scan line is just the first
   item, so it gives up the auto margin that pins it right on the scans page. */
.header-meta {
  flex-basis: 100%;
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 14px;
  padding-top: 2px;
}
/* The scan line sits at the right of this row, directly under the site links;
   the standing disclaimer takes the left. */
.header-meta .scan-info { margin-left: auto; }
.header-meta .muted { font-size: 12.5px; }

.seg { display: inline-flex; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
.seg button {
  border: 0; background: var(--surface-1); color: var(--text-secondary);
  padding: 6px 12px; cursor: pointer; font: inherit; font-size: 13px;
}
.seg button.active { background: var(--accent); color: #fff; }
select, #theme-toggle, #cookie-sync {
  background: var(--surface-1); color: var(--text-primary);
  border: 1px solid var(--border); border-radius: 8px;
  padding: 6px 10px; font: inherit; font-size: 13px; cursor: pointer;
}
/* Used by the session button and by the dashboard's Scans link, which carries
   the warning now that the button itself lives on the scans page. */
.warn { color: var(--neg); border-color: var(--neg); }

.tabs { display: flex; gap: 4px; padding: 6px 20px 0; border-bottom: 1px solid var(--grid); }
.tabs button {
  border: 0; background: none; color: var(--text-secondary);
  padding: 8px 14px; cursor: pointer; font: inherit; font-size: 14px;
  border-bottom: 2px solid transparent;
}
.tabs button.active { color: var(--text-primary); border-bottom-color: var(--accent); }

main { padding: 12px 20px 40px; }
.chart-row { display: flex; gap: 14px; align-items: stretch; }
.chart-host {
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: 12px;
  min-height: 480px;
  flex: 1;
  min-width: 0;
  position: relative; /* anchors the zoom-reset button */
}

/* Appears only while a chart is drag-zoomed; one click back to the full view */
.zoom-reset {
  position: absolute; top: 8px; right: 8px; z-index: 7;
  display: flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 8px; padding: 0;
  background: var(--surface-1); color: var(--text-secondary);
  border: 1px solid var(--border); cursor: pointer;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
}
.zoom-reset:hover { color: var(--text-primary); border-color: var(--accent); }
.zoom-reset[hidden] { display: none; }

/* dashboard preview panel — step 1 of ticker drill-down */
.preview {
  width: 340px; flex: 0 0 340px;
  background: var(--surface-1); border: 1px solid var(--border);
  border-radius: 12px; padding: 14px; display: flex; flex-direction: column;
}
/* display:flex above beats the browser's own [hidden]{display:none}, so an
   empty 340px shell sat beside the chart whenever nothing was selected */
.preview[hidden] { display: none; }
@media (max-width: 900px) {
  .chart-row { flex-direction: column; }
  .preview { width: auto; flex: 1 1 auto; }
}
.preview-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; }
.preview-title {
  font-size: 16px; font-weight: 600; color: var(--text-primary);
  text-decoration: none; line-height: 1.25;
}
.preview-title:hover { color: var(--accent); text-decoration: underline; }
.preview-head button { border: 0; background: none; color: var(--muted); font-size: 14px; cursor: pointer; }
.preview-chart { height: 190px; margin: 8px 0 4px; }
.preview-stats {
  display: grid; grid-template-columns: auto 1fr; gap: 4px 12px;
  font-size: 12.5px; margin-top: 4px;
}
.preview-stats .k { color: var(--muted); }
.preview-stats .v { color: var(--text-primary); text-align: right; font-variant-numeric: tabular-nums; }
.preview-stats .sep {
  grid-column: 1 / -1; border-top: 1px solid var(--grid); margin: 6px 0 2px;
}
.preview-links {
  margin-top: auto; padding-top: 10px;
  display: flex; justify-content: space-between; gap: 10px;
}
.preview-hint { font-size: 12px; color: var(--accent); text-decoration: none; }
.preview-hint:hover { text-decoration: underline; }

/* compact range picker (price history), used in the panel and ticker page */
.range-seg { display: flex; flex-wrap: wrap; gap: 3px; margin: 8px 0 2px; }
.range-seg button {
  border: 1px solid var(--border); background: var(--surface-1);
  color: var(--text-secondary); border-radius: 6px;
  padding: 3px 7px; font: inherit; font-size: 11px; cursor: pointer;
}
.range-seg button:hover { color: var(--text-primary); }
.range-seg button.active { background: var(--accent); color: #fff; border-color: var(--accent); }
.board-sentinel { height: 1px; }
.board-status { padding: 10px 12px; color: var(--muted); font-size: 12px; }
.empty-state {
  padding: 60px 20px; text-align: center; color: var(--muted);
  background: var(--surface-1); border: 1px solid var(--border); border-radius: 12px;
}

.board { margin-top: 20px; }
/* Column explainers. Rendered on <body> with position:fixed because
   .table-wrap has overflow-x:auto, which would clip an in-table tooltip. */
th[data-tip] { cursor: help; }
th[data-tip]:hover { color: var(--text-primary); }
#col-tip {
  position: fixed; z-index: 60; max-width: 300px;
  background: var(--surface-1); color: var(--text-secondary);
  border: 1px solid var(--border); border-radius: 8px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.18);
  padding: 8px 10px; font-size: 12px; font-weight: 400; line-height: 1.45;
  text-align: left; white-space: normal; pointer-events: none;
}
#col-tip b { color: var(--text-primary); display: block; margin-bottom: 3px; }

.linkish {
  border: 0; background: none; color: var(--accent);
  font: inherit; font-size: 12px; font-weight: 500; cursor: pointer; padding: 0 6px;
}
.linkish:hover { text-decoration: underline; }
.filter-row th {
  padding: 4px 6px 8px; border-bottom: 1px solid var(--grid);
  background: var(--surface-1); position: sticky; top: 29px;
}
.filter-row .fpair { display: flex; gap: 3px; }
.filter-row input {
  width: 100%; min-width: 42px; max-width: 62px;
  background: var(--page); color: var(--text-primary);
  border: 1px solid var(--border); border-radius: 5px;
  padding: 2px 4px; font: inherit; font-size: 11px; text-align: right;
  font-variant-numeric: tabular-nums;
}
.filter-row input:focus { outline: 1px solid var(--accent); outline-offset: -1px; }
.filter-row input.set { border-color: var(--accent); color: var(--accent); }
.table-wrap {
  overflow-x: auto; background: var(--surface-1);
  border: 1px solid var(--border); border-radius: 12px;
}
table { border-collapse: collapse; width: 100%; font-size: 13px; }
th, td { padding: 8px 12px; text-align: left; white-space: nowrap; }
th {
  color: var(--muted); font-weight: 600; font-size: 12px;
  border-bottom: 1px solid var(--grid); position: sticky; top: 0;
  background: var(--surface-1);
}
th.sortable { cursor: pointer; }
th.sortable:hover, th.sorted { color: var(--text-primary); }
/* direction arrow on the active sort column */
th.sorted-desc::after, th.sorted-asc::after {
  font-size: 8px; color: var(--accent); vertical-align: 1px; padding-left: 3px;
}
th.sorted-desc::after { content: "▼"; }
th.sorted-asc::after { content: "▲"; }
td { border-bottom: 1px solid var(--grid); color: var(--text-secondary); }
tr:last-child td { border-bottom: 0; }
tbody tr { cursor: pointer; }
tr:hover td { background: color-mix(in srgb, var(--accent) 6%, transparent); }
tbody tr.selected td { background: color-mix(in srgb, var(--accent) 13%, transparent); }
tbody tr.selected td:first-child { box-shadow: inset 3px 0 0 var(--accent); }
.num { text-align: right; font-variant-numeric: tabular-nums; }
td.num { text-align: right; }
.sym { color: var(--text-primary); font-weight: 600; cursor: pointer; }
.sym:hover { color: var(--accent); }
.dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 6px; vertical-align: 1px; }
.trend-up { color: var(--up); }
.trend-down { color: var(--neg); }
.spark { vertical-align: middle; }

/* ticker page */
/* flex-basis + min-width so the box wraps to its own line on narrow screens
   rather than shrinking to an unusable stub */
.search-wrap { position: relative; flex: 1 1 220px; min-width: 200px; max-width: 340px; }
.search-wrap input {
  width: 100%; background: var(--surface-1); color: var(--text-primary);
  border: 1px solid var(--border); border-radius: 8px;
  padding: 7px 12px; font: inherit; font-size: 13px;
}
.search-wrap input:focus { outline: 2px solid var(--accent); outline-offset: -1px; }
.search-results {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 40;
  list-style: none; margin: 0; padding: 4px;
  background: var(--surface-1); border: 1px solid var(--border); border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.2); max-height: 320px; overflow-y: auto;
}
.search-results li {
  padding: 7px 10px; border-radius: 6px; cursor: pointer; font-size: 13px;
  display: flex; gap: 8px; align-items: baseline;
}
.search-results li.selected, .search-results li:hover {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}
.search-results .s { font-weight: 600; color: var(--text-primary); min-width: 52px; }
.search-results .n { color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; }
.search-results .m { color: var(--muted); font-size: 11px; }
.search-results li.head {
  display: flex; justify-content: space-between; align-items: center; cursor: default;
  color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em;
}
.search-results li.head:hover { background: transparent; }
.search-results li.head .clear {
  background: none; border: 0; color: var(--accent); font: inherit; cursor: pointer; padding: 0;
  text-transform: none; letter-spacing: 0;
}

.items li { cursor: pointer; }
.items li:hover { background: color-mix(in srgb, var(--accent) 5%, transparent); }
.contrib {
  display: inline-flex; gap: 10px; margin-top: 3px; font-size: 12px;
  color: var(--muted); font-variant-numeric: tabular-nums;
}
.contrib b { color: var(--text-secondary); font-weight: 600; }

/* The prose pages carry the toggle in the header itself (the dashboard keeps
   its own in the filter row), so push it to the far end of that first line. */
header > #theme-toggle { margin-left: auto; }

.back { color: var(--muted); text-decoration: none; font-size: 14px; }
.back:hover { color: var(--accent); }
.stat-row {
  display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 14px;
}
.stat {
  background: var(--surface-1); border: 1px solid var(--border); border-radius: 10px;
  padding: 10px 16px; min-width: 110px;
}
.stat .k { color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; }
.stat .v { font-size: 20px; font-variant-numeric: tabular-nums; margin-top: 2px; }
.two-col {
  display: grid; grid-template-columns: minmax(280px, 5fr) minmax(320px, 7fr);
  gap: 16px; margin-top: 20px; align-items: start;
}
@media (max-width: 900px) { .two-col { grid-template-columns: 1fr; } }
.col-card {
  background: var(--surface-1); border: 1px solid var(--border); border-radius: 12px;
  padding: 16px;
}
.muted { color: var(--muted); font-weight: 400; font-size: 12px; }
.tv-link { float: right; font-size: 12px; font-weight: 400; color: var(--accent); text-decoration: none; }
.tv-link:hover { text-decoration: underline; }
#chart-tabs { padding-left: 0; margin-top: 4px; }

.detail {
  position: fixed; top: 0; right: 0; bottom: 0; width: min(440px, 92vw);
  background: var(--surface-1); border-left: 1px solid var(--border);
  box-shadow: -8px 0 30px rgba(0, 0, 0, 0.15);
  padding: 18px; overflow-y: auto; z-index: 30;
}
.detail-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,0.25); z-index: 20; }
.detail-head { display: flex; justify-content: space-between; align-items: center; }
.detail-head button { border: 0; background: none; color: var(--muted); font-size: 16px; cursor: pointer; }
.profile-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 6px 14px;
  margin: 10px 0; font-size: 13px;
}
.profile-grid .k { color: var(--muted); }
.profile-grid .v { color: var(--text-primary); font-variant-numeric: tabular-nums; }
.desc { font-size: 13px; color: var(--text-secondary); line-height: 1.5; }
.items { list-style: none; padding: 0; margin: 12px 0 0; }
.items li { padding: 8px 0; border-bottom: 1px solid var(--grid); font-size: 13px; }
.items a { color: var(--text-primary); text-decoration: none; }
.items a:hover { color: var(--accent); }
.items .meta { color: var(--muted); font-size: 12px; margin-top: 2px; }
.badge {
  font-size: 11px; padding: 1px 7px; border-radius: 10px;
  border: 1px solid var(--border); color: var(--text-secondary);
}
.badge.bullish { color: var(--up); }
.badge.bearish { color: var(--neg); }

/* ---------- scans console (local only) ---------- */
.schedule-detail {
  display: grid; grid-template-columns: max-content 1fr; gap: 6px 18px;
  align-items: baseline; font-size: 13px;
  border: 1px solid var(--border); border-radius: 10px; padding: 12px 14px;
}
.schedule-detail .k { color: var(--muted); }
.schedule-detail .v { color: var(--text-primary); }
.schedule-detail code { font-size: 12px; }
#run-scan:disabled { opacity: 0.55; cursor: default; }

/* ---------- price move across the selected range ---------- */
.preview-change { font-size: 13px; margin: 2px 0 6px; font-variant-numeric: tabular-nums; }
.preview-change .abs { opacity: 0.75; font-size: 12px; }
.badge.kind-recommendation { color: var(--pos); border-color: var(--pos); }
.badge.kind-analysis { color: var(--text-secondary); }
.badge.kind-news { color: var(--muted); }
.badge.kind-question { color: var(--muted); font-style: italic; }
.stat .v .sub { display: block; font-size: 11px; color: var(--muted); margin-top: 2px; }
/* Where the ticker actually appears, when the headline above doesn't show it */
#items .excerpt, .preview-items .excerpt {
  font-size: 12px; color: var(--text-secondary); margin-top: 3px;
  padding-left: 8px; border-left: 2px solid var(--grid); line-height: 1.45;
}
.badge.kind-position { color: var(--muted); }
/* Spectacle: loud but weightless. Warm-toned so it reads as a caveat. */
.badge.theater {
  color: var(--neg); border-color: var(--neg);
  background: color-mix(in srgb, var(--neg) 8%, transparent);
}
/* leaderboard company/industry columns: informative but never dominant */
td.co-name, td.industry {
  max-width: 170px; overflow: hidden; text-overflow: ellipsis;
  color: var(--text-secondary); font-size: 12px;
}

/* ---------- about/contact prose + shared footer ---------- */
.prose { max-width: 760px; }
.prose .board {
  background: var(--surface-1); border: 1px solid var(--border);
  border-radius: 12px; padding: 16px 20px; margin-bottom: 14px;
}
.prose p { line-height: 1.6; color: var(--text-secondary); margin: 8px 0; }
.prose b, .prose h2 { color: var(--text-primary); }
.site-footer {
  padding: 18px 20px 30px; font-size: 12.5px; color: var(--text-secondary);
}
.site-footer a { color: var(--accent); text-decoration: none; }
.site-footer a:hover { text-decoration: underline; }
/* two-line company blurb in the preview panel; click-through for the rest.
   Same size as the stat rows, tight margin — it should read as one more row of
   panel information, not a paragraph that reflows the layout. */
.preview-desc {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; margin: 4px 0 0; font-size: 12.5px; line-height: 1.45;
  color: var(--muted); cursor: pointer;
}
.preview-desc:hover { color: var(--text-secondary); }

/* ---------- load-time skeletons ---------- */
@keyframes shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }
.skel-line, .skel-block {
  border-radius: 8px;
  background: linear-gradient(90deg, var(--grid) 25%, var(--surface-1) 50%, var(--grid) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.4s linear infinite;
}
.skel-line { height: 14px; width: 100%; }
.skel-chart { padding: 26px; display: flex; flex-direction: column; gap: 18px; height: 100%; }
.skel-chart .skel-block { flex: 1; min-height: 320px; }
.skel-row td { padding: 12px; }

/* ---------- in-flight spinners ---------- */
/* The HTML skeletons cover the very first paint; these cover every re-fetch
   (window switch, sort, filters, preview loads). The old content stays visible
   under a frosted veil with a centred ring, and both fade in after a short
   delay so cache-fast responses never flash a spinner. */
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes spinner-in { to { opacity: 1; } }
.panel-loading { position: relative; }
.panel-loading::after {
  content: ""; position: absolute; inset: 0; z-index: 8; border-radius: inherit;
  background: color-mix(in srgb, var(--surface-1) 55%, transparent);
  opacity: 0; animation: spinner-in 0.18s ease 0.15s forwards;
}
.panel-loading::before {
  content: ""; position: absolute; z-index: 9;
  /* centred in short panels, pinned near the top of tall ones (the table) */
  top: min(50%, 220px); left: 50%; margin: -12px 0 0 -12px;
  width: 24px; height: 24px; border-radius: 50%;
  border: 2.5px solid var(--grid); border-top-color: var(--accent);
  opacity: 0;
  animation: spin 0.7s linear infinite, spinner-in 0.18s ease 0.15s forwards;
}
/* standalone variant for slots that swap content (infinite-scroll footer) */
.spinner {
  width: 20px; height: 20px; margin: 2px auto; border-radius: 50%;
  border: 2.5px solid var(--grid); border-top-color: var(--accent);
  animation: spin 0.7s linear infinite;
}

/* ---------- mobile ---------- */
@media (max-width: 640px) {
  header { padding: 10px 12px 6px; gap: 10px; }
  h1 { font-size: 18px; }
  .search-wrap { order: 3; flex-basis: 100%; }
  .scan-info { flex-basis: 100%; margin-left: 0; }
  .tabs { padding: 4px 12px 0; }
  main { padding: 10px 12px 30px; }
  /* Company and Industry are the widest, least essential columns on a phone.
     Structural positions 3 and 4 across header, filter row and body rows. */
  #leaderboard th:nth-child(3), #leaderboard td:nth-child(3),
  #leaderboard th:nth-child(4), #leaderboard td:nth-child(4) { display: none; }
  th, td { padding: 6px 8px; }
  table { font-size: 12px; }
  .range-seg button { padding: 5px 9px; font-size: 12px; }
  .site-footer { padding: 14px 12px 24px; }
}
/* Portrait phones lose the evidence columns too — Mentions (10), Upvotes (11)
   and Trend (13) — leaving market data plus the headline scores. Rotating to
   landscape brings them back. */
@media (max-width: 640px) and (orientation: portrait) {
  #leaderboard th:nth-child(10), #leaderboard td:nth-child(10),
  #leaderboard th:nth-child(11), #leaderboard td:nth-child(11),
  #leaderboard th:nth-child(13), #leaderboard td:nth-child(13) { display: none; }
}
/* Landscape phones are ~800-900px wide, past the 640px breakpoint, so they're
   matched by their short viewport instead. Every column fits except Industry,
   the widest of the low-signal ones — Company stays. */
@media (max-height: 480px) and (orientation: landscape) {
  #leaderboard th:nth-child(4), #leaderboard td:nth-child(4) { display: none; }
}

/* ---------- methodology page: formulas and definition lists ---------- */
.formula {
  background: var(--page); border: 1px solid var(--grid); border-radius: 8px;
  padding: 10px 14px; margin: 10px 0; overflow-x: auto;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13px; color: var(--text-primary); white-space: nowrap;
}
.formula .note { color: var(--muted); font-size: 12px; white-space: normal; }
.defs { margin: 0; }
.defs dt { font-weight: 600; color: var(--text-primary); margin-top: 12px; font-size: 14px; }
.defs dt:first-child { margin-top: 0; }
.defs dd { margin: 3px 0 0; color: var(--text-secondary); line-height: 1.55; font-size: 14px; }
table.consts { font-size: 13px; margin-top: 8px; }
table.consts td:first-child { color: var(--text-primary); font-weight: 500; }
table.consts td:nth-child(2) { font-variant-numeric: tabular-nums; white-space: nowrap; }
table.consts td:last-child { color: var(--text-secondary); white-space: normal; }

/* ---------- contact form ---------- */
.cform { display: flex; flex-direction: column; gap: 4px; margin-top: 14px; }
.cform label { font-size: 13px; color: var(--text-primary); margin-top: 10px; font-weight: 500; }
.cform input[type="text"], .cform input[type="email"], .cform textarea {
  background: var(--page); color: var(--text-primary);
  border: 1px solid var(--border); border-radius: 8px;
  padding: 8px 11px; font: inherit; font-size: 14px; width: 100%;
}
.cform textarea { resize: vertical; min-height: 110px; line-height: 1.5; }
.cform input:focus, .cform textarea:focus { outline: 2px solid var(--accent); outline-offset: -1px; }
.cform .hp { position: absolute; left: -9999px; opacity: 0; }
.cform-foot { display: flex; align-items: center; gap: 12px; margin-top: 14px; flex-wrap: wrap; }
.cform button {
  background: var(--accent); color: #fff; border: 0; border-radius: 8px;
  padding: 9px 20px; font: inherit; font-size: 14px; font-weight: 500; cursor: pointer;
}
.cform button:hover { filter: brightness(1.08); }
.cform button:disabled { opacity: 0.55; cursor: default; }
.cform-status { font-size: 13px; color: var(--muted); }
.cform-status.good { color: var(--up); }
.cform-status.bad { color: var(--neg); }

/* brief acknowledgement that the board refreshed itself */
.scan-info.just-updated { color: var(--accent); transition: color 0.2s; }

/* leaderboard price column: sparkline and its percentage read as one unit */
.pspark { display: inline-flex; align-items: center; gap: 6px; }
.pspark svg { vertical-align: middle; }

/* ---------- site navigation ----------
   In the header, not a footer: the leaderboard loads more rows as you scroll,
   so a footer is unreachable on the one page most people land on — and with
   it the About and Privacy links, which is where a reader looks to decide
   whether to trust any of this. */
.site-nav {
  /* Top right of the header, on the first row: these are the way around the
     site, and were previously buried under a line of scan statistics. */
  margin-left: auto;
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 14px;
  font-size: 12.5px;
}
.site-nav a { color: var(--accent); text-decoration: none; }
.site-nav a:hover { text-decoration: underline; }
@media (max-width: 640px) {
  /* No room to ride beside the title on a phone: the links take their own
     line, ahead of the metadata row. */
  .site-nav { flex-basis: 100%; margin-left: 0; gap: 0 12px; font-size: 12px; }
  /* The scan statistics go on a phone — three lines of counts above a screen
     that has none to spare, and the scans page has them in full. The standing
     disclaimer stays, on one compact line. */
  .header-meta .scan-info { display: none; }
  .header-meta .muted { flex-basis: 100%; padding-top: 0; font-size: 11.5px; }
}

/* ---------- phone: swipeable panes, and the selected-ticker card ----------

   On a phone the preview panel and the leaderboard used to stack, so reading
   the table meant scrolling past a chart panel that was often taller than the
   screen. They become two pages of one horizontally snapping deck instead —
   swipe, or use the tabs. Both are inert above 640px, where the panels sit
   where they always have. */

.pane-dots { display: none; }
.panes { display: contents; } /* desktop: the panels stay where they were */

.ticker-card { display: none; }

@media (max-width: 640px) {
  /* The deck's whole navigation: swipe, with three dots saying which page you
     are on and offering a tap as the alternative. They sit above the chart's
     own view tabs, where they read as belonging to the deck rather than to
     whatever page happens to be showing. */
  .pane-dots { display: flex; justify-content: center; gap: 8px; padding: 8px 0 2px; }
  .pane-dots button {
    width: 7px; height: 7px; padding: 0; border-radius: 50%; cursor: pointer;
    border: 0; background: var(--baseline); opacity: 0.55;
  }
  .pane-dots button.active { background: var(--accent); opacity: 1; }

  /* The chart's own view switcher rides inside the chart's page, so it swipes
     away with the chart instead of vanishing and shifting everything up. */
  .chart-pane .tabs { padding: 0 4px 0; margin-bottom: 10px; }
  /* A pane is a page of the deck: it carries its own height rather than the
     min-height that let the chart push the page down on a phone. */
  .panes .chart-host { min-height: 0; }

  /* The full ticker page is what this page has become on a phone */
  .panes #preview-link { display: none; }
  .preview-pane > .preview-metrics { margin: 0; padding-top: 14px; border-top: 1px solid var(--border); }
  .preview-items h3 { font-size: 13px; margin: 0; color: var(--text-primary); }
  .preview-items .items { margin-top: 6px; }

  .panes {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    /* The deck scrolls sideways; the page still scrolls down inside a page. */
    overscroll-behavior-x: contain;
    gap: 12px;
    scrollbar-width: none;
  }
  .panes::-webkit-scrollbar { display: none; }
  .panes > * {
    flex: 0 0 100%; min-width: 0; scroll-snap-align: start; margin: 0;
    /* Each page scrolls inside itself. Without this the deck would be as tall
       as the leaderboard — hundreds of rows — so the graph page would end in a
       screen of nothing and the dots would sit a thousand pixels down. */
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }
  /* Room at the foot of a page for the pinned card to sit over */
  main.has-card .panes > * { padding-bottom: 88px; }
  /* The selection's page: three cards stacked, each its own square */
  .preview-pane { display: flex; flex-direction: column; gap: 12px; }
  .preview-pane > .preview-metrics,
  .preview-pane > .preview-items {
    background: var(--surface-1); border: 1px solid var(--border);
    border-radius: 12px; padding: 14px;
  }
  .preview-pane > .preview-metrics[hidden],
  .preview-pane > .preview-items[hidden] { display: none; }
  /* A pane the deck owns is never also hidden: an empty preview shows its own
     placeholder rather than collapsing the page it lives on. */
  .preview-pane > .preview[hidden] { display: flex; }
  .preview-pane > .preview[hidden]::before {
    content: "Tap a ticker on the graph or in the table to see it here.";
    color: var(--muted); font-size: 13px; line-height: 1.5; padding: 6px 2px;
  }

  /* Room for the pinned card so the last table row is never under it */
  main.has-card { padding-bottom: calc(96px + env(safe-area-inset-bottom, 0px)); }

  .ticker-card {
    display: block;
    position: fixed; left: 8px; right: 8px; z-index: 40;
    bottom: calc(8px + env(safe-area-inset-bottom, 0px));
    background: var(--surface-1); border: 1px solid var(--border);
    border-radius: 12px; padding: 8px 10px;
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.28);
  }
  .ticker-card[hidden] { display: none; }
  .ticker-card .card-head {
    display: flex; align-items: baseline; gap: 8px; margin-bottom: 6px;
  }
  .ticker-card .card-sym { font-size: 15px; font-weight: 600; color: var(--text-primary); }
  .ticker-card .card-name {
    color: var(--muted); font-size: 12px; flex: 1;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .ticker-card .card-close {
    border: 0; background: none; color: var(--muted); font-size: 14px;
    cursor: pointer; padding: 0 2px;
  }
  /* The leaderboard's own columns, wrapped to the width of a phone. Shared by
     the pinned card and the inline copy at the foot of the preview page. */
  .card-grid {
    display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px 4px;
  }
  .card-grid div { min-width: 0; }
  .card-k {
    display: block; color: var(--muted); font-size: 10px; text-transform: uppercase;
    letter-spacing: 0.03em;
  }
  .card-v {
    display: block; color: var(--text-primary); font-size: 13px;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
}
