:root {
  --bg: #0e1116;
  --panel: #161b22;
  --panel-2: #1c2430;
  --border: #2a323d;
  --text: #e6edf3;
  --muted: #8b98a5;
  --accent: #4c8bf5;
  --ok: #3fb950;
  --warn: #d29922;
  --bad: #f85149;
  --mono: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  -webkit-font-smoothing: antialiased;
  line-height: 1.45;
}

/* ---- top bar ---- */
.topbar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 22px;
  border-bottom: 1px solid var(--border);
  background: linear-gradient(180deg, #12171e, #0e1116);
  position: sticky;
  top: 0;
  z-index: 20;
  box-shadow: 0 2px 10px #00000040;
}
.brand { display: flex; align-items: center; gap: 10px; font-weight: 650; letter-spacing: .3px; }
.brand .rune { color: var(--accent); font-size: 20px; }
.topbar .status-dot { font-size: 12px; color: var(--muted); }

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

/* ---- swipeable column board (dashboard only, body.dash) ----
   The page itself doesn't scroll; the board is a horizontal row of columns and
   each column scrolls vertically on its own. Swipe / horizontal-scroll (or the
   arrow keys) moves between columns; scroll-snap gives a gentle per-column feel. */
body.dash { height: 100vh; height: 100dvh; overflow: hidden;
  display: flex; flex-direction: column; }
.board {
  flex: 1 1 auto; min-height: 0;          /* let the columns own the scrolling */
  display: flex; gap: 18px; padding: 18px 22px;
  overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x proximity;
  overscroll-behavior-x: contain;
}
.column {
  flex: 0 0 auto;
  width: min(380px, 88vw);                 /* several fit on desktop; ~1 per screen on mobile */
  display: flex; flex-direction: column; gap: 18px;
  overflow-y: auto; min-height: 0;         /* independent up/down scroll */
  scroll-snap-align: center;               /* snapped column sits centered on screen */
  padding-bottom: 6px;
  -webkit-overflow-scrolling: touch;
}
.column > .panel { flex: 0 0 auto; }

body.dash .cred-banner { margin: 14px 22px 0; }
body.dash .foot { flex: none; margin: 0; padding: 8px 22px 12px; }
/* thin, unobtrusive scrollbars for the board + columns */
.board::-webkit-scrollbar, .column::-webkit-scrollbar { height: 8px; width: 8px; }
.board::-webkit-scrollbar-thumb, .column::-webkit-scrollbar-thumb {
  background: var(--border); border-radius: 4px; }

.panel {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 18px 20px;
  min-width: 0;
}
.panel h2 {
  margin: 0 0 14px;
  font-size: 13px; text-transform: uppercase; letter-spacing: .8px;
  color: var(--muted); font-weight: 600;
  display: flex; align-items: center; justify-content: space-between;
}

/* ---- stat rows ---- */
.pf-headline { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.sparkline { height: 100px; margin: 12px 0 2px; position: relative; }
.sparkline svg { width: 100%; height: 100%; display: block; overflow: hidden; }
#arm-spark, #nv-spark, #ap-spark, #gl-spark, #ms-spark, #az-spark { height: 60px; }   /* short, with a top strip for session labels */
.spark-lbl { position: absolute; top: 0; transform: translateX(-50%);
  font-size: 9px; line-height: 12px; color: var(--muted); letter-spacing: .6px;
  pointer-events: none; white-space: nowrap; }
.spark-cap { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .5px; margin-bottom: 10px; }

/* Airthings sensor rows: label | value | inline history sparkline */
.at-row { display: grid; grid-template-columns: 1fr auto 96px; gap: 10px;
          align-items: center; padding: 7px 0; border-bottom: 1px solid #ffffff08; }
.at-row:last-child { border-bottom: 0; }
.at-row .k { color: var(--muted); font-size: 13px; }
.at-row .v { font-family: var(--mono); font-size: 14px; text-align: right; white-space: nowrap; }
.at-row .v .unit { color: var(--muted); font-size: 11px; margin-left: 3px; }
.at-spark { height: 26px; }
.at-spark svg { width: 100%; height: 100%; display: block; overflow: hidden; }
.at-spark .at-nodata { color: var(--muted); font-size: 9px; opacity: .6; white-space: nowrap; line-height: 26px; }
.at-row .v.at-good { color: #3fb950; }
.at-row .v.at-fair { color: #d29922; }
.at-row .v.at-poor { color: #f85149; }
/* shared timeframe pills, pinned to the top of the Airthings column while it scrolls */
.at-tf-tabs {
  position: sticky; top: 0; z-index: 3;
  margin: 0 0 14px; padding: 8px 0 10px;
  background: var(--bg); border-bottom: 1px solid var(--border);
}
/* NAV timeframe selector: click a label to jump; the graph also cycles on click.
   Label over %-change, centered, so the pills are narrow enough to fit one row. */
.spark-tabs { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 10px; }
.spark-tab { display: flex; flex-direction: column; align-items: center; gap: 1px;
  padding: 3px 5px; border: 1px solid var(--border); border-radius: 8px;
  cursor: pointer; user-select: none; line-height: 1.15; }
.spark-tab-label { font-size: 11px; font-weight: 600; letter-spacing: .3px; color: var(--muted); }
.spark-tab-chg { font-size: 10px; font-weight: 600; }
/* Only the Universe timeframe row has 7 pills — shrink just its % so they fit
   one row; the asset row (5 pills) keeps the normal size. */
#univ-tf-tabs .spark-tab-chg { font-size: 7.5px; letter-spacing: -.3px; }
#univ-asset-tabs .spark-tab-chg { font-size: 8.5px; letter-spacing: -.2px; }
.spark-tab-chg.muted { color: var(--muted); }
.spark-tab:hover { border-color: var(--muted); }
.spark-tab:hover .spark-tab-label { color: var(--text); }
.spark-tab.active { border-color: var(--accent); background: #4c8bf51a; }
.spark-tab.active .spark-tab-label { color: var(--accent); }

/* ---- Spending panel ---- */
.sp-badge {
  font-size: 11px; font-weight: 600; color: var(--warn);
  border: 1px solid var(--warn); border-radius: 5px; padding: 1px 6px; margin-left: 8px;
}
.sp-pie-wrap { display: flex; justify-content: center; margin: 12px 0 10px; }
#sp-pie, #in-pie { width: 180px; height: 180px; max-width: 70%; }
#sp-pie path, #sp-pie circle, #in-pie path, #in-pie circle { stroke: var(--panel); stroke-width: 0.6; }
.sp-period { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
#sp-slider, #in-slider { flex: 1; accent-color: var(--accent); cursor: pointer; min-width: 0; }
#sp-slider:disabled, #in-slider:disabled { opacity: .4; cursor: default; }
.sp-period-lbl { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums;
  white-space: nowrap; text-align: right; min-width: 92px; }
.sp-legend { display: flex; flex-direction: column; gap: 5px; }
.sp-leg-row { display: flex; align-items: center; gap: 8px; font-size: 12px; }
.sp-swatch { width: 10px; height: 10px; border-radius: 2px; flex: none; }
.sp-leg-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sp-leg-val { font-family: var(--mono); color: var(--muted); }
.sp-leg-pct { font-family: var(--mono); width: 46px; text-align: right; font-variant-numeric: tabular-nums; }
.sp-caret { width: 10px; flex: none; color: var(--muted); font-size: 9px; text-align: center; }
.sp-leg-row[data-cat], .sp-leg-row[data-other] { cursor: pointer; }
.sp-leg-row[data-cat]:hover .sp-leg-name,
.sp-leg-row[data-other]:hover .sp-leg-name { color: var(--text); }
.sp-leg-row.sp-merch { font-size: 11px; }
.sp-leg-row.sp-merch .sp-leg-name, .sp-leg-row.sp-merch .sp-leg-pct { color: var(--muted); }
.big { font-family: var(--mono); font-size: 30px; font-weight: 650; letter-spacing: -.5px; }
.roi-badge { font-family: var(--mono); font-size: 16px; font-weight: 650; }
.roi-badge.pos { color: var(--ok); }
.roi-badge.neg { color: var(--bad); }
.regime-tag { font-family: var(--sans); font-size: 11px; text-transform: uppercase; letter-spacing: .5px; font-weight: 700; }
.regime-tag.pos { color: var(--ok); }
.regime-tag.neg { color: var(--bad); }
.regime-tag.neutral { color: var(--muted); }
.warn-t { color: var(--warn); }
.big .unit { font-size: 15px; color: var(--muted); font-weight: 500; margin-left: 4px; }
.sub { color: var(--muted); font-size: 13px; margin-top: 2px; }

.rows { display: flex; flex-direction: column; gap: 2px; margin-top: 6px; }
.row {
  display: flex; align-items: baseline; justify-content: space-between;
  padding: 7px 0; border-bottom: 1px solid #ffffff08;
}
.row:last-child { border-bottom: 0; }
.row .k { color: var(--muted); font-size: 13px; }
.row .v { font-family: var(--mono); font-size: 14px; text-align: right; }

.pos { color: var(--ok); } .neg { color: var(--bad); } .neutral { color: var(--muted); }

.pill {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; font-weight: 600; padding: 2px 9px; border-radius: 999px;
  border: 1px solid var(--border);
}
.pill .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--muted); }
.pill.ok .dot { background: var(--ok); } .pill.ok { color: var(--ok); border-color: #3fb95040; }
.pill.warn .dot { background: var(--warn); } .pill.warn { color: var(--warn); border-color: #d2992240; }
.pill.bad .dot { background: var(--bad); } .pill.bad { color: var(--bad); border-color: #f8514940; }

.units { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }
.unit-chip {
  font-family: var(--mono); font-size: 12px; padding: 3px 8px; border-radius: 6px;
  border: 1px solid var(--border); background: var(--panel-2); color: var(--muted);
}
.unit-chip.up { color: var(--ok); border-color: #3fb95033; }
.unit-chip.down { color: var(--bad); border-color: #f8514955; }

/* ---- holdings table ---- */
.tablewrap { overflow-x: auto; }
table.holdings { width: 100%; border-collapse: collapse; font-size: 13px; }
table.holdings th, table.holdings td {
  padding: 8px 12px; text-align: left; white-space: nowrap;
  border-bottom: 1px solid #ffffff0d;
}
table.holdings th {
  color: var(--muted); font-weight: 600; font-size: 11px;
  text-transform: uppercase; letter-spacing: .5px;
}
table.holdings td { font-family: var(--mono); }
table.holdings td:first-child { font-weight: 650; }
table.holdings .num { text-align: right; }
table.holdings tbody tr:last-child td { border-bottom: 0; }
/* Net Worth: collapsible category rows over indented account rows. Smaller name
   font so long account names + the value both fit the narrow column. */
table.nw-table td:first-child { font-size: 12px; }
table.nw-table tr.nw-cat td { font-weight: 650; }
table.nw-table tr.nw-cat td:first-child { font-size: 13px; }
table.nw-table tr.nw-acct td {
  border-bottom: 0; padding-top: 3px; padding-bottom: 3px; font-size: 10px;
}
table.nw-table tr.nw-acct td:first-child {
  font-weight: 400; color: var(--muted); padding-left: 26px;
}
.nw-caret {
  color: var(--muted); font-size: 9px; display: inline-block;
  width: 12px; margin-left: -2px;
}
.nw-pie-wrap { display: flex; justify-content: center; margin: 12px 0 4px; }
#nw-pie { width: 172px; height: 172px; max-width: 66%; }
.nw-swatch {
  display: inline-block; width: 8px; height: 8px; border-radius: 2px;
  margin-right: 7px; vertical-align: middle; flex: none;
}
table.holdings .venue-chip {
  font-family: var(--sans); font-size: 11px; color: var(--muted);
  border: 1px solid var(--border); border-radius: 5px; padding: 1px 7px;
}
.muted { color: var(--muted); }
/* Credential health banner — sits directly in <body class="dash"> above the
   board (its margins are set by body.dash .cred-banner). display:none when all
   OK = zero layout footprint. Multiple failures stack compactly in ONE banner. */
.cred-banner { display: flex; flex-direction: column; gap: 4px;
  padding: 10px 14px; margin-bottom: 18px; border-radius: 10px;
  font-size: 14px; font-weight: 600; line-height: 1.35; }
.cred-banner.urgent { background: #f8514922; border: 1px solid var(--bad); color: var(--bad); }
.cred-banner.warn { background: #d2992222; border: 1px solid var(--warn); color: var(--warn); }
.cred-banner .cred-item { display: flex; gap: 8px; align-items: baseline; }
.cred-banner .cred-item .cred-ico { flex: none; }
/* Holdings grouped ROI headers (Total | Unrealized), centered over their pairs */
table.holdings th.grp { text-align: center; padding-bottom: 4px; }
table.holdings th.grp-l, table.holdings td:nth-child(9) { border-left: 1px solid var(--border); }

.foot { margin-top: 18px; color: var(--muted); font-size: 12px; text-align: center; }
.foot a { color: var(--accent); text-decoration: none; }

/* ---- auth pages ---- */
.center { min-height: 100vh; display: grid; place-items: center; padding: 20px; }
.card {
  background: var(--panel); border: 1px solid var(--border); border-radius: 14px;
  padding: 34px; width: 100%; max-width: 380px; text-align: center;
}
.card .rune { font-size: 40px; color: var(--accent); }
.card h1 { font-size: 22px; margin: 12px 0 4px; }
.card p { color: var(--muted); font-size: 14px; margin: 0 0 22px; }
button.primary {
  width: 100%; padding: 12px 16px; font-size: 15px; font-weight: 600;
  color: #fff; background: var(--accent); border: 0; border-radius: 9px; cursor: pointer;
}
button.primary:hover { filter: brightness(1.08); }
button.primary:disabled { opacity: .6; cursor: default; }
.msg { margin-top: 16px; font-size: 13px; min-height: 18px; }
.msg.err { color: var(--bad); } .msg.ok { color: var(--ok); }
.ghost { background: transparent; border: 1px solid var(--border); color: var(--muted);
  padding: 8px 12px; border-radius: 8px; font-size: 13px; cursor: pointer; }
.ghost:hover { color: var(--text); }
.ghost.wide { width: 100%; }
button.wide { width: 100%; }
/* auth form fields */
.field { width: 100%; padding: 11px 13px; margin: 0 0 10px; font-size: 15px;
  color: var(--text); background: var(--panel-2); border: 1px solid var(--border);
  border-radius: 9px; }
.field:focus { outline: none; border-color: var(--accent); }
.reveal { display: block; text-align: left; color: var(--muted); font-size: 12px;
  margin: -2px 0 12px; cursor: pointer; }
.reveal input { vertical-align: middle; margin-right: 5px; }
#form .primary, #pwform .wide { margin-top: 4px; }
.or { display: flex; align-items: center; gap: 10px; color: var(--muted);
  font-size: 12px; text-transform: uppercase; letter-spacing: .5px; margin: 18px 0; }
.or::before, .or::after { content: ""; flex: 1; height: 1px; background: var(--border); }
