/* ============================================================================
   Pool monitor — design system
   ============================================================================
   Hand-written, no framework and no build step: the panel is served as plain
   static files and the project carries five runtime dependencies on purpose.

   The layout is a fixed sidebar plus a scrolling main column. Sections are shown
   and hidden client-side rather than being separate pages, so navigating never
   re-authenticates and never re-fetches the census.
   ========================================================================== */

:root {
  /* Violet ground, lifted rather than flat black. Cards sit above it on a
     gradient so the surface reads as depth instead of as a grey box. */
  --paper:      #0e0b1e;
  --paper-2:    #141031;
  --surface:    #191333;
  --surface-2:  #221a45;
  --surface-3:  #2c2258;
  --rule:       #342a63;
  --rule-soft:  #2a2150;

  --ink:        #f2eefc;
  --ink-2:      #bcb0e4;
  --ink-3:      #8f83c2;

  --ok:      #4ade80;  --ok-bg:      rgba(74, 222, 128, 0.12);
  --warn:    #fbbf24;  --warn-bg:    rgba(251, 191, 36, 0.12);
  --crit:    #fb7185;  --crit-bg:    rgba(251, 113, 133, 0.14);
  --info:    #a78bfa;  --info-bg:    rgba(167, 139, 250, 0.14);

  --violet:  #8b5cf6;
  --violet-2:#a78bfa;
  --pink:    #e879f9;
  --cyan:    #22d3ee;
  --accent:  var(--violet);
  --accent-2:var(--pink);

  /* Reused everywhere so the family stays one family. */
  --grad-brand: linear-gradient(135deg, var(--violet), var(--pink));
  --grad-card:  linear-gradient(160deg, rgba(139, 92, 246, 0.10), rgba(232, 121, 249, 0.03) 55%, transparent);
  --glow:       0 0 0 1px rgba(139, 92, 246, 0.3), 0 16px 44px -14px rgba(139, 92, 246, 0.7);
  --glow-soft:  0 8px 26px -10px rgba(139, 92, 246, 0.75);

  --mono: ui-monospace, "Cascadia Mono", "SF Mono", Menlo, Consolas, monospace;
  --sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  --radius:   16px;
  --radius-s: 10px;
  --sidebar:  15.5rem;
}

* { box-sizing: border-box; }

/* The type scale lives on `html`, and that is the whole point.
   `rem` resolves against the ROOT font size, never against `body`, so the
   `font-size: 14px` that used to sit on `body` only ever reached text with no
   size of its own. Everything built from rem — table cells at 0.8rem, column
   headers and pills at 0.64rem — stayed pinned to the browser's 16px default
   and rendered at 12.8px and 10.2px. On a wide screen that is unreadable.

   Scaling here moves the type, the sidebar and `--measure` together, so the
   column grows with the text instead of squeezing it. The breakpoints are in
   px on purpose: a media query in rem would be evaluated against the initial
   root size and would not follow these declarations. */
html { font-size: 17px; }
@media (min-width: 1500px) { html { font-size: 18px; } }
@media (min-width: 1900px) { html { font-size: 19px; } }
@media (min-width: 2400px) { html { font-size: 20px; } }

/* The `hidden` attribute is only `display: none` in the UA stylesheet, so any
   author rule that sets `display` beats it — and several below do. Restating it
   here fixes every case at once. This is a regression guard: a registration
   field once showed up because of exactly this. */
[hidden] { display: none !important; }

body {
  margin: 0;
  /* Two soft lights behind everything: the "aurora" the mock leans on, done with
     radial gradients rather than an image, so it costs nothing to ship. */
  background:
    radial-gradient(1100px 620px at 12% -8%, rgba(139, 92, 246, 0.34), transparent 60%),
    radial-gradient(900px 520px at 92% 4%, rgba(232, 121, 249, 0.24), transparent 62%),
    var(--paper);
  background-attachment: fixed;
  color: var(--ink);
  font-family: var(--sans);
  font-size: 0.95rem;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--accent); }

/* ── shell ────────────────────────────────────────────────────────────────── */

.shell { display: flex; min-height: 100vh; }

.sidebar {
  width: var(--sidebar);
  flex: none;
  background: linear-gradient(180deg, rgba(25, 19, 51, 0.92), rgba(14, 11, 30, 0.92));
  backdrop-filter: blur(12px);
  border-right: 1px solid var(--rule-soft);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
}

.brand {
  display: flex; align-items: center; gap: 0.65rem;
  padding: 1.15rem 1.1rem;
  border-bottom: 1px solid var(--rule);
}
.brand-mark {
  width: 2.1rem; height: 2.1rem; flex: none;
  border-radius: var(--radius-s);
  background: var(--grad-brand);
  box-shadow: var(--glow-soft);
  display: grid; place-items: center;
  font-weight: 700; color: #0b0e17; font-size: 0.95rem;
}
.brand-text { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.brand-name { font-weight: 650; letter-spacing: -0.01em; }
.brand-sub { font-size: 0.75rem; color: var(--ink-3); font-family: var(--mono); }

.nav { padding: 0.75rem 0.6rem; display: flex; flex-direction: column; gap: 0.15rem; flex: 1; }
.nav-label {
  font-size: 0.68rem; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ink-3); padding: 0.9rem 0.5rem 0.35rem;
}
.nav-item {
  display: flex; align-items: center; gap: 0.65rem;
  padding: 0.5rem 0.6rem;
  border-radius: var(--radius-s);
  color: var(--ink-2);
  background: none; border: none; width: 100%;
  font: inherit; text-align: left; cursor: pointer;
}
.nav-item:hover { background: var(--surface-2); color: var(--ink); }
.nav-item.active {
  background: var(--grad-brand);
  color: #fff; font-weight: 600;
  box-shadow: var(--glow-soft);
}
.nav-item.active .nav-icon { color: #fff; }
.nav-icon { width: 1.1rem; height: 1.1rem; flex: none; color: var(--ink-3); }

/* Sections that arrive with PLAN 5 and PLAN 6. Shown so the shape of the product
   is visible, disabled so nobody mistakes them for something that works. */
.nav-item[disabled] { opacity: 0.45; cursor: not-allowed; }
.nav-item[disabled]:hover { background: none; color: var(--ink-2); }

.sidebar-foot {
  padding: 0.85rem 1.1rem; border-top: 1px solid var(--rule);
  font-size: 0.76rem; color: var(--ink-3); font-family: var(--mono);
  display: flex; flex-direction: column; gap: 0.3rem;
}

/* ── main column ──────────────────────────────────────────────────────────── */

.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }

/* The measure every section is laid out on.
   `max()` collapses to the plain gutter on a narrow window and centres the
   column on a wide one, so there is one number to change and nothing to keep
   in sync. Only the headline card used to be capped, which is what left it
   floating between two empty margins while everything else ran wall to wall.

   The indent sits on each SECTION rather than on `.content`, so a section can
   opt out — and the pools table does. Twelve columns squeezed into a reading
   measure while the window had room to spare is a scrollbar the screen did not
   need. `100%` resolves against `.content`, which now has no inline padding of
   its own, so these line up with the topbar to the pixel. */
:root { --measure: 90rem; --gutter: 1.5rem; }
.topbar, .content > * {
  padding-inline: max(var(--gutter), calc((100% - var(--measure)) / 2));
}
/* Wide by choice: the table decides the width, not the prose. */
.content > .full-bleed { padding-inline: var(--gutter); }

.topbar {
  display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
  padding-block: 1.1rem;
  border-bottom: 1px solid var(--rule-soft);
  background: rgba(14, 11, 30, 0.72);
  backdrop-filter: blur(12px);
  position: sticky; top: 0; z-index: 20;
}
.topbar h1 { margin: 0; font-size: 1.55rem; letter-spacing: -0.025em; font-weight: 680; }
.topbar .sub { margin: 0; font-size: 0.83rem; color: var(--ink-3); }
.topbar-spacer { flex: 1; }
.topbar-actions { display: flex; align-items: center; gap: 0.6rem; }

.content { padding-block: 1.5rem; display: flex; flex-direction: column; gap: 1.25rem; }
/* `min-width: 0` so a wide table scrolls inside its card instead of stretching
   the flex column and pushing the whole page sideways. */
.content > * { min-width: 0; }

/* ── controls ─────────────────────────────────────────────────────────────── */

.chip {
  font-family: var(--mono); font-size: 0.74rem; letter-spacing: 0.05em;
  color: var(--ink-3); border: 1px solid var(--rule); border-radius: 999px;
  padding: 0.2rem 0.6rem; white-space: nowrap;
}
.chip.tiny { font-size: 0.68rem; padding: 0.1rem 0.45rem; }
.chip-warn { color: var(--warn); border-color: var(--warn); }

.btn {
  font-family: var(--sans); font-size: 0.8rem; font-weight: 600;
  background: var(--grad-brand); color: #fff;
  box-shadow: var(--glow-soft);
  border: none; border-radius: var(--radius-s);
  padding: 0.45rem 0.9rem; cursor: pointer;
}
.btn:hover { filter: brightness(1.1); }
.btn:disabled { opacity: 0.5; cursor: progress; }
.btn.ghost { background: transparent; color: var(--ink-2); border: 1px solid var(--rule); box-shadow: none; }
.btn.ghost:hover { color: var(--ink); border-color: var(--ink-3); filter: none; }
.btn:focus-visible, input:focus-visible, .nav-item:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}

input[type="search"], input[type="text"], input[type="number"],
input[type="email"], input[type="password"] {
  background: var(--surface-2); border: 1px solid var(--rule); border-radius: var(--radius-s);
  color: var(--ink); padding: 0.4rem 0.7rem;
  font-family: var(--mono); font-size: 0.78rem;
}
input[type="search"] { min-width: 15rem; }

.dot { width: 0.55rem; height: 0.55rem; border-radius: 50%; background: var(--crit); flex: none; }
.dot.on { background: var(--ok); box-shadow: 0 0 0 3px rgba(52, 211, 153, 0.15); }

.user { display: flex; align-items: center; gap: 0.5rem; }
.user-email { font-family: var(--mono); font-size: 0.74rem; color: var(--ink-2); }

/* ── cards ────────────────────────────────────────────────────────────────── */

.card {
  background: var(--surface), var(--grad-card);
  background: linear-gradient(160deg, rgba(139, 92, 246, 0.14), rgba(232, 121, 249, 0.04) 55%, transparent 75%), var(--surface);
  border: 1px solid var(--rule-soft);
  border-radius: var(--radius);
  box-shadow: 0 10px 30px -22px rgba(0, 0, 0, 0.9);
}
.card:hover { border-color: var(--rule); }
.card-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
  padding: 0.85rem 1.1rem;
  border-bottom: 1px solid var(--rule);
}
.card-head h2 { margin: 0; font-size: 0.92rem; font-weight: 650; }
.card-head .sub { margin: 0; font-size: 0.72rem; color: var(--ink-3); }
.card-body { padding: 1.1rem; }

.grid { display: grid; gap: 1.25rem; }
.grid-kpi { grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); }
.grid-2-1 { grid-template-columns: 2fr 1fr; }
@media (max-width: 62rem) { .grid-2-1 { grid-template-columns: 1fr; } }

/* KPI tile. The accent bar carries the meaning; the number stays plain. */
.kpi { position: relative; overflow: hidden; padding: 1.1rem; }
.kpi::before {
  content: ""; position: absolute; inset: 0 auto 0 0; width: 3px;
  background: var(--ink-3);
}
.kpi::after {
  content: ""; position: absolute; right: -30%; top: -60%;
  width: 16rem; height: 16rem; border-radius: 50%;
  background: radial-gradient(circle, rgba(139, 92, 246, 0.28), transparent 70%);
  pointer-events: none;
}
.kpi.crit::after { background: radial-gradient(circle, rgba(251, 113, 133, 0.18), transparent 70%); }
.kpi.ok::after   { background: radial-gradient(circle, rgba(74, 222, 128, 0.14), transparent 70%); }
.kpi.ok::before   { background: var(--ok); }
.kpi.warn::before { background: var(--warn); }
.kpi.crit::before { background: var(--crit); }
.kpi.info::before { background: var(--info); }
.kpi-label {
  font-size: 0.68rem; letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--ink-3);
}
.kpi-figure {
  font-family: var(--sans); font-weight: 660; letter-spacing: -0.02em; font-size: 2rem; line-height: 1.15;
  font-variant-numeric: tabular-nums; margin-top: 0.35rem;
}
.kpi-figure .sub { font-size: 0.85rem; color: var(--ink-3); }
.kpi-note { font-size: 0.72rem; color: var(--ink-3); margin-top: 0.3rem; }
.kpi.crit .kpi-figure { color: var(--crit); }
.kpi.ok .kpi-figure { color: var(--ok); }

/* ── charts, all hand-drawn SVG: no chart library, no dependency ──────────── */

.ring { display: flex; align-items: center; gap: 1.1rem; }
.ring svg { flex: none; }
.ring-track { stroke: var(--surface-3); }
.ring-value { stroke: var(--ok); transition: stroke-dasharray 0.4s ease; }
.ring-value.warn { stroke: var(--warn); }
.ring-value.crit { stroke: var(--crit); }
.ring-centre { font-family: var(--mono); font-size: 0.95rem; fill: var(--ink); }
.ring-legend { display: flex; flex-direction: column; gap: 0.3rem; font-size: 0.76rem; }
.ring-legend .row { display: flex; justify-content: space-between; gap: 1.5rem; color: var(--ink-2); }
.ring-legend .row b { font-family: var(--mono); color: var(--ink); font-weight: 500; }

.chart { width: 100%; height: 10rem; }
.chart-line { fill: none; stroke: var(--accent-2); stroke-width: 2; stroke-linejoin: round; }
.chart-area { fill: url(#chartFade); }
.chart-grid { stroke: var(--rule); stroke-width: 1; }
.chart-dot { fill: var(--accent-2); }
.chart-label { font-family: var(--mono); font-size: 0.7rem; fill: var(--ink-3); }
.chart-empty {
  display: grid; place-items: center; height: 10rem;
  color: var(--ink-3); font-size: 0.8rem; text-align: center; padding: 0 2rem;
}

.spark { width: 4.5rem; height: 1.4rem; vertical-align: middle; }
.spark polyline { fill: none; stroke: var(--ink-3); stroke-width: 1.5; }

/* ── tables ───────────────────────────────────────────────────────────────── */

.scroll { overflow-x: auto; }
table { border-collapse: collapse; width: 100%; font-size: 0.9rem; min-width: 52rem; }
th, td { text-align: left; padding: 0.65rem 1rem; border-bottom: 1px solid var(--rule); white-space: nowrap; }
thead th {
  font-size: 0.76rem; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--ink-3); font-weight: 600;
  background: var(--surface-2); position: sticky; top: 0; z-index: 1;
}
tbody tr:last-child td { border-bottom: none; }
tbody tr:hover { background: var(--surface-2); }
.num { text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; }
th.num { text-align: right; }
.addr { font-family: var(--mono); font-size: 0.79rem; color: var(--ink-2); }
.pair { font-family: var(--mono); font-weight: 500; }

/* Capital behind a dead feed: the row has to catch the eye on its own. */
tbody tr.stranded { background: var(--crit-bg); }
tbody tr.stranded:hover { background: var(--crit-bg); filter: brightness(1.2); }

.stack { display: flex; flex-direction: column; line-height: 1.3; }
.stack .sub { font-size: 0.8em; color: var(--ink-3); }

/* Zero liquidity is a reading, not a gap. Dim, but present. */
.empty-fig { color: var(--ink-3); }

/* ── pills ────────────────────────────────────────────────────────────────── */

.pill {
  display: inline-flex; align-items: center; gap: 0.35em;
  font-family: var(--mono); font-size: 0.74rem; letter-spacing: 0.04em;
  text-transform: uppercase; padding: 0.15em 0.5em;
  border-radius: 999px; border: 1px solid currentColor;
  color: var(--ink-3);
}
.pill::before { content: ""; width: 0.4em; height: 0.4em; border-radius: 50%; background: currentColor; }
.pill.ok   { color: var(--ok);   background: var(--ok-bg); }
.pill.warn { color: var(--warn); background: var(--warn-bg); }
.pill.crit { color: var(--crit); background: var(--crit-bg); }
.pill.info { color: var(--info); background: var(--info-bg); }

.cov { font-family: var(--mono); font-size: 0.78rem; color: var(--ink-2); }
.muted { color: var(--ink-3); font-size: 0.78rem; }
td .muted { font-size: 0.78rem; }

.filters { display: flex; align-items: center; gap: 0.9rem; flex-wrap: wrap; }
.check { font-size: 0.76rem; color: var(--ink-2); display: flex; align-items: center; gap: 0.35rem; cursor: pointer; }

.empty { padding: 1.6rem 1.1rem; color: var(--ink-3); margin: 0; }

.notice {
  margin: 0; padding: 0.7rem 1.1rem;
  border: 1px solid var(--warn); background: var(--warn-bg); color: var(--warn);
  border-radius: var(--radius); font-size: 0.82rem;
}

/* ── candidates ───────────────────────────────────────────────────────────── */

.candidate {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 0.6rem 0; border-bottom: 1px solid var(--rule);
}
.candidate:last-child { border-bottom: none; }
.candidate-name { font-family: var(--mono); font-size: 0.8rem; }
.candidate-why { font-size: 0.72rem; color: var(--ink-3); }

/* ── operations ───────────────────────────────────────────────────────────── */

.ops-form, .ops-approve { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.ops-form { padding: 0.85rem 1.1rem; border-bottom: 1px solid var(--rule); }
.ops-form input, .ops-approve input { width: 8rem; }
.ops-enrol {
  padding: 1rem 1.1rem; border-bottom: 1px solid var(--rule);
  display: flex; flex-direction: column; gap: 0.6rem;
}
.totp-uri {
  font-family: var(--mono); font-size: 0.7rem; color: var(--ink-2); word-break: break-all;
  background: var(--surface-2); border: 1px solid var(--rule);
  border-radius: var(--radius-s); padding: 0.6rem; user-select: all;
}

/* ── login ────────────────────────────────────────────────────────────────── */

body.centered { display: flex; min-height: 100vh; align-items: center; justify-content: center; padding: 1.5rem; }
.auth { display: flex; flex-direction: column; gap: 1rem; width: 100%; max-width: 25rem; }
.auth-head { display: flex; align-items: center; gap: 0.7rem; padding-bottom: 0.2rem; }
.auth-form { display: flex; flex-direction: column; gap: 0.95rem; padding: 1.2rem; }
.field { display: flex; flex-direction: column; gap: 0.3rem; }
.field > span { font-size: 0.66rem; letter-spacing: 0.09em; text-transform: uppercase; color: var(--ink-3); }
.field > small { font-size: 0.72rem; color: var(--ink-3); }
.field input { width: 100%; }
.form-note { margin: 0; font-size: 0.8rem; color: var(--ink-2); }
.form-error { margin: 0; font-size: 0.8rem; color: var(--crit); }
.auth-foot { margin: 0; font-size: 0.8rem; color: var(--ink-3); text-align: center; }

/* ── accessibility ────────────────────────────────────────────────────────── */

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

@media (prefers-reduced-motion: reduce) { * { transition: none !important; animation: none !important; } }

@media (max-width: 52rem) {
  .shell { flex-direction: column; }
  .sidebar { width: 100%; height: auto; position: static; flex-direction: row; align-items: center; overflow-x: auto; }
  .nav { flex-direction: row; padding: 0.4rem; }
  .nav-label, .sidebar-foot { display: none; }
  .content { padding: 1rem; }
}

/* ── hero ─────────────────────────────────────────────────────────────────────
   The mock leads with one big number over an aurora. Ours is the number the
   project turns on: how many pools are quoting. The chart sits behind it rather
   than beside it, so the figure and its trend are read as one thing. */

.hero {
  position: relative; overflow: hidden;
  border-radius: 26px;
  border: 1px solid rgba(196, 151, 255, 0.45);
  background:
    radial-gradient(520px 300px at 12% 8%,  rgba(139, 92, 246, 0.30), transparent 62%),
    radial-gradient(560px 320px at 88% 6%,  rgba(232, 121, 249, 0.26), transparent 62%),
    radial-gradient(700px 380px at 50% 118%, rgba(139, 92, 246, 0.30), transparent 66%),
    linear-gradient(160deg, #1a1140 0%, #120b2c 55%, #0c0722 100%);
  box-shadow:
    inset 0 0 0 1px rgba(196, 151, 255, 0.14),
    0 0 0 1px rgba(196, 151, 255, 0.32),
    0 0 70px -10px rgba(196, 151, 255, 0.45),
    0 30px 80px -30px rgba(139, 92, 246, 1);
  padding: 1.6rem 1.8rem 1.4rem;
}

/* The bloom in the corners of the reference. Purely decorative, so it is
   pointer-transparent and carries no text. */
.hero::before, .hero::after {
  content: ""; position: absolute; width: 24rem; height: 24rem; border-radius: 50%;
  pointer-events: none; filter: blur(40px); opacity: 0.5;
}
.hero::before { left: -8rem; top: -6rem;  background: radial-gradient(circle, rgba(139, 92, 246, 0.55), transparent 65%); }
.hero::after  { right: -9rem; bottom: -8rem; background: radial-gradient(circle, rgba(232, 121, 249, 0.40), transparent 65%); }
.hero > * { position: relative; z-index: 1; }

/* ── header row ── */
.hero-top {
  display: flex; align-items: center; gap: 1rem;
  padding-bottom: 1.1rem; margin-bottom: 1.3rem;
  border-bottom: 1px solid rgba(167, 139, 250, 0.22);
}
.hero-logo {
  width: 3.4rem; height: 3.4rem; flex: none; border-radius: 50%;
  display: grid; place-items: center;
  background: radial-gradient(circle at 30% 25%, rgba(167, 139, 250, 0.35), rgba(20, 12, 46, 0.9));
  border: 1px solid rgba(196, 151, 255, 0.55);
  box-shadow: inset 0 0 22px rgba(167, 139, 250, 0.4), 0 0 26px -6px rgba(196, 151, 255, 0.9);
}
.hero-logo svg { width: 1.7rem; height: 1.7rem; }
.hero-title {
  font-size: 1.5rem; font-weight: 800; letter-spacing: 0.02em; color: #fff;
  text-transform: uppercase; line-height: 1.05;
  text-shadow: 0 0 26px rgba(196, 151, 255, 0.55);
}
.hero-subtitle {
  font-size: 0.74rem; letter-spacing: 0.2em; font-weight: 600;
  color: var(--ink-2); margin-top: 0.3rem;
}
.hero-pill {
  margin-left: auto; display: inline-flex; align-items: center; gap: 0.5rem;
  padding: 0.55rem 1.15rem; border-radius: 999px; white-space: nowrap;
  font-size: 0.7rem; font-weight: 700; letter-spacing: 0.14em; color: #f2eefc;
  background: rgba(139, 92, 246, 0.14);
  border: 1px solid rgba(196, 151, 255, 0.5);
  box-shadow: inset 0 0 20px rgba(167, 139, 250, 0.22), 0 0 24px -8px rgba(196, 151, 255, 0.9);
}
.hero-pill svg { width: 0.95rem; height: 0.95rem; color: var(--violet-2); }

/* ── ring left, trend right ── */
.hero-main {
  display: grid; grid-template-columns: minmax(14rem, 21rem) minmax(0, 1fr);
  gap: 2.4rem; align-items: center;
}
@media (max-width: 62rem) { .hero-main { grid-template-columns: 1fr; } }

.hero-ring-wrap { position: relative; display: grid; place-items: center; }
.hero-ring { display: flex; flex-direction: column; align-items: center; gap: 0.55rem; }
.hero-ring svg { width: 100%; max-width: 23.5rem; height: auto; display: block; }

/* The label stack lives in HTML on top of the SVG, not inside it: SVG text
   cannot wrap or letterspace reliably across browsers, and this stack has five
   lines that all have to stay centred inside the ring. */
.hero-ring-text {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 0.1rem; text-align: center;
  pointer-events: none; padding: 0 26%;
}
.hero-ring-eyebrow {
  font-size: 0.72rem; letter-spacing: 0.24em; font-weight: 700; color: var(--violet-2);
}
.hero-ring-value {
  font-size: clamp(2.4rem, 5vw, 3.5rem); font-weight: 800; color: #fff; line-height: 1;
  letter-spacing: -0.02em; text-shadow: 0 0 34px rgba(196, 151, 255, 0.75);
}
.hero-ring-state {
  font-size: 0.78rem; letter-spacing: 0.2em; font-weight: 700; color: #f0abfc;
  text-shadow: 0 0 20px rgba(232, 121, 249, 0.9); margin-top: 0.1rem;
}
.hero-ring-rule {
  display: flex; align-items: center; gap: 0.5rem;
  width: 80%; margin: 0 auto 0.4rem;
}
.hero-ring-rule i {
  flex: 1; height: 1px; background: linear-gradient(90deg, transparent, rgba(196, 151, 255, 0.65), transparent);
}
.hero-ring-rule b {
  width: 0.4rem; height: 0.4rem; border-radius: 50%; background: #e879f9;
  box-shadow: 0 0 10px 2px rgba(232, 121, 249, 0.9);
}
.hero-ring-caption {
  font-size: 0.72rem; letter-spacing: 0.11em; font-weight: 600; color: var(--ink-3);
  line-height: 1.5; max-width: 18rem; margin-inline: auto;
}
.hero-ring-caption.crit { color: #ff8fa3; }

/* ── the trend column ── */
.hero-quote { min-width: 0; }
.hero-quote-head {
  display: flex; align-items: center; gap: 0.5rem;
  font-size: 0.82rem; letter-spacing: 0.16em; font-weight: 700; color: var(--violet-2);
}
.hero-info {
  width: 1.05rem; height: 1.05rem; border-radius: 50%; display: inline-grid; place-items: center;
  border: 1px solid rgba(196, 151, 255, 0.55); color: var(--violet-2);
  font-size: 0.68rem; font-weight: 700; font-style: normal; cursor: help;
}
.hero-quote-label {
  font-size: 0.72rem; letter-spacing: 0.16em; font-weight: 600;
  color: var(--ink-2); margin-top: 0.7rem;
}
.hero-quote-value {
  font-size: clamp(1.9rem, 4vw, 2.7rem); font-weight: 800; color: #fff; line-height: 1.05;
  letter-spacing: -0.02em; text-shadow: 0 0 30px rgba(196, 151, 255, 0.6); margin-top: 0.1rem;
}
.hero-quote-value .unit { font-size: 0.5em; font-weight: 700; color: var(--ink-2); margin-left: 0.15em; }
.hero-quote-delta {
  display: flex; align-items: baseline; gap: 0.6rem; flex-wrap: wrap;
  font-size: 0.78rem; margin-top: 0.35rem;
}
.hero-quote-delta .up   { color: #5ef2a0; font-weight: 700; }
.hero-quote-delta .down { color: #ff8fa3; font-weight: 700; }
.hero-quote-delta .flat { color: var(--ink-2); font-weight: 600; }
.hero-quote-delta .since { color: var(--ink-3); letter-spacing: 0.12em; font-size: 0.74rem; font-weight: 600; }

.hero-chart { width: 100%; height: auto; max-height: 22rem; display: block; margin-top: 0.6rem; }

/* ── the three cards ── */
.hero-cards {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: 1rem; margin-top: 1.4rem;
}
.hero-card {
  padding: 0.95rem 1.1rem; border-radius: 18px;
  background: linear-gradient(155deg, rgba(139, 92, 246, 0.16), rgba(139, 92, 246, 0.04));
  border: 1px solid rgba(167, 139, 250, 0.3);
  box-shadow: inset 0 0 26px rgba(139, 92, 246, 0.12);
}
.hero-card-head {
  display: flex; align-items: center; gap: 0.55rem;
  font-size: 0.72rem; letter-spacing: 0.16em; font-weight: 700; color: #e2d8fb;
}
.hero-card-head svg { width: 1.25rem; height: 1.25rem; flex: none; }
.hero-card-body { display: flex; align-items: flex-end; justify-content: space-between; gap: 0.8rem; margin-top: 0.5rem; }
.hero-card-value {
  font-size: 1.6rem; font-weight: 800; color: #fff; line-height: 1;
  letter-spacing: -0.02em; text-shadow: 0 0 22px rgba(167, 139, 250, 0.5);
}
.hero-card-value .unit { font-size: 0.55em; color: var(--ink-2); margin-left: 0.1em; }
.hero-card-delta { font-size: 0.82rem; font-weight: 700; margin-top: 0.4rem; }
.hero-card-delta.up   { color: #5ef2a0; }
.hero-card-delta.down { color: #ff8fa3; }
.hero-card-delta.flat { color: var(--ink-2); font-weight: 600; }
.hero-card-note { font-size: 0.68rem; letter-spacing: 0.11em; color: var(--ink-3); font-weight: 600; margin-top: 0.25rem; }
.hero-card-spark { width: 7.5rem; flex: none; height: auto; }
@media (max-width: 30rem) { .hero-card-spark { display: none; } }

/* ── footer ──
   In the reference this strip is decoration. Here it carries the caveat, because
   a pool that quotes is not necessarily one we can use and that sentence has to
   survive the redesign. */
.hero-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  flex-wrap: wrap; margin-top: 1.2rem; padding-top: 1rem;
  border-top: 1px solid rgba(167, 139, 250, 0.2);
  font-size: 0.76rem; color: var(--ink-2);
}
.hero-foot span { display: flex; align-items: center; gap: 0.5rem; }
.hero-foot svg { width: 1rem; height: 1rem; flex: none; color: var(--violet-2); }

.live-badge {
  display: inline-flex; align-items: center; gap: 0.4rem;
  font-size: 0.7rem; font-weight: 700; letter-spacing: 0.1em;
  padding: 0.25rem 0.7rem; border-radius: 999px;
  background: rgba(74, 222, 128, 0.14); color: #5ef2a0;
  border: 1px solid rgba(94, 242, 160, 0.45);
  box-shadow: 0 0 16px -4px rgba(94, 242, 160, 0.6);
}

/* ── segmented donut ────────────────────────────────────────────────────────
   One arc per chain, drawn as stroke-dasharray offsets on concentric circles.
   No chart library: this is four `<circle>` elements and some arithmetic. */

.donut { display: flex; align-items: center; gap: 1.4rem; flex-wrap: wrap; }
.donut svg { flex: none; filter: drop-shadow(0 8px 24px rgba(139, 92, 246, 0.6)); }
.donut-centre-value { font-size: 1.35rem; font-weight: 680; fill: var(--ink); }
.donut-centre-label { font-size: 0.68rem; fill: var(--ink-3); letter-spacing: 0.08em; }
.donut-legend { display: flex; flex-direction: column; gap: 0.5rem; flex: 1; min-width: 11rem; }
.donut-row { display: flex; align-items: center; gap: 0.6rem; font-size: 0.8rem; }
.donut-swatch { width: 0.6rem; height: 0.6rem; border-radius: 3px; flex: none; }
.donut-row .name { color: var(--ink-2); flex: 1; }
.donut-row .val { font-family: var(--mono); color: var(--ink); }
.donut-row .pct { font-family: var(--mono); color: var(--ink-3); width: 3.2rem; text-align: right; }

/* ── progress rows ──────────────────────────────────────────────────────────
   The mock's holdings list. Ours is coverage per chain, which is the number that
   decides whether the census beside it can be believed. */

.bars { display: flex; flex-direction: column; gap: 0.9rem; }
.bar-row { display: grid; grid-template-columns: 6rem 1fr auto; gap: 0.8rem; align-items: center; }
.bar-name { font-size: 0.82rem; }
.bar-track { height: 0.42rem; border-radius: 999px; background: var(--surface-3); overflow: hidden; }
.bar-fill { height: 100%; border-radius: 999px; background: var(--grad-brand);
  box-shadow: 0 0 12px rgba(167, 139, 250, 0.7); transition: width 0.5s ease; }
.bar-fill.warn { background: linear-gradient(90deg, #f59e0b, #fbbf24); }
.bar-fill.crit { background: linear-gradient(90deg, #e11d48, #fb7185); }
.bar-value { font-family: var(--mono); font-size: 0.78rem; color: var(--ink-2); min-width: 6.5rem; text-align: right; }

/* ── small feature tiles ────────────────────────────────────────────────────── */

.tile { display: flex; gap: 0.8rem; padding: 1rem 1.1rem; align-items: flex-start; }
.tile-icon {
  width: 2.1rem; height: 2.1rem; flex: none; border-radius: var(--radius-s);
  display: grid; place-items: center; color: #fff;
  background: var(--grad-brand); box-shadow: var(--glow-soft);
}
.tile-icon.ok   { background: linear-gradient(135deg, #10b981, #4ade80); }
.tile-icon.warn { background: linear-gradient(135deg, #d97706, #fbbf24); }
.tile-icon.crit { background: linear-gradient(135deg, #e11d48, #fb7185); }
.tile-icon svg { width: 1.1rem; height: 1.1rem; }
.tile-body { min-width: 0; }
.tile-title { font-size: 0.84rem; font-weight: 620; }
.tile-text { font-size: 0.75rem; color: var(--ink-2); margin-top: 0.2rem; }

/* ============================================================================
   Visual pass: glow, saturation and contrast
   ============================================================================
   Six changes, all cosmetic. Nothing here alters a number, a threshold or what
   any state means — the semantics from MS6 and MS10 are untouched.
   ========================================================================== */

/* 1 · KPI tiles were flat: give them an icon, a glowing frame and a bigger figure. */
.kpi {
  display: flex; gap: 0.9rem; align-items: flex-start;
  border: 1px solid rgba(167, 139, 250, 0.28);
  box-shadow: 0 0 0 1px rgba(139, 92, 246, 0.10), 0 18px 44px -28px rgba(139, 92, 246, 0.9);
  transition: border-color 0.25s ease, box-shadow 0.25s ease, transform 0.25s ease;
}
.kpi:hover {
  border-color: rgba(196, 151, 255, 0.55);
  box-shadow: 0 0 0 1px rgba(139, 92, 246, 0.2), 0 22px 50px -26px rgba(139, 92, 246, 1);
  transform: translateY(-1px);
}
.kpi-icon {
  width: 2.6rem; height: 2.6rem; flex: none; border-radius: 13px;
  display: grid; place-items: center; color: var(--violet-2);
  background: rgba(139, 92, 246, 0.15);
  border: 1px solid rgba(196, 151, 255, 0.38);
  box-shadow: inset 0 0 18px rgba(167, 139, 250, 0.3), 0 0 18px -6px rgba(167, 139, 250, 0.6);
}
.kpi-icon svg { width: 1.25rem; height: 1.25rem; }
.kpi.ok   .kpi-icon { color: #5ef2a0; border-color: rgba(94, 242, 160, 0.4);
  background: rgba(74, 222, 128, 0.13); box-shadow: inset 0 0 18px rgba(94, 242, 160, 0.25), 0 0 18px -6px rgba(94, 242, 160, 0.6); }
.kpi.crit .kpi-icon { color: #ff8fa3; border-color: rgba(255, 143, 163, 0.45);
  background: rgba(251, 113, 133, 0.14); box-shadow: inset 0 0 18px rgba(255, 143, 163, 0.28), 0 0 18px -6px rgba(255, 143, 163, 0.7); }
.kpi-figure {
  font-size: 2.4rem; font-weight: 720; color: #fff;
  text-shadow: 0 0 26px rgba(167, 139, 250, 0.55);
}
.kpi.crit .kpi-figure { color: #ff8fa3; text-shadow: 0 0 26px rgba(255, 143, 163, 0.6); }
.kpi.ok   .kpi-figure { color: #5ef2a0; text-shadow: 0 0 26px rgba(94, 242, 160, 0.5); }
.kpi-note { color: var(--ink-2); }

/* Coverage bars were flat: a lit track and a lit fill. */
.bar-track {
  background: rgba(139, 92, 246, 0.12);
  border: 1px solid rgba(167, 139, 250, 0.25);
  height: 0.55rem;
}
.bar-fill { box-shadow: 0 0 14px rgba(196, 151, 255, 0.9); }
.bar-fill.warn { box-shadow: 0 0 14px rgba(251, 191, 36, 0.8); }
.bar-fill.crit { box-shadow: 0 0 14px rgba(251, 113, 133, 0.85); }
.bar-value { color: var(--ink); }

/* 6 · Donut: saturated arcs and a stronger halo. */
.donut svg { filter: drop-shadow(0 0 26px rgba(167, 139, 250, 0.75)); }
.donut-swatch { box-shadow: 0 0 10px currentColor; }
.donut-centre-value { font-size: 1.6rem; font-weight: 720; }
.donut-row .val { color: #fff; }

/* Section headings, lifted so cards do not read as one grey mass. */
.card-head h2 { font-size: 0.98rem; color: #fff; }

/* ============================================================================
   Tables: Pools, Sweeps, Operations
   ========================================================================== */

/* Section KPI strip, reused by all three tabs. */
.strip { display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); gap: 1rem; margin-bottom: 1.25rem; }

/* Pair avatar: initials on a colour derived from the symbol, so the same token
   is always the same colour without shipping an icon set. */
.avatar {
  width: 2.1rem; height: 2.1rem; flex: none; border-radius: 50%;
  display: grid; place-items: center;
  font-size: 0.66rem; font-weight: 700; color: #fff; letter-spacing: -0.02em;
  border: 1px solid rgba(255, 255, 255, 0.18);
  box-shadow: 0 0 14px -4px currentColor;
}
.cell-pair { display: flex; align-items: center; gap: 0.6rem; }
.cell-pair-text { display: flex; flex-direction: column; line-height: 1.25; }
.cell-pair-name { font-family: var(--mono); font-weight: 600; color: var(--ink); }
.cell-pair-sub { font-size: 0.74rem; color: var(--ink-3); }

.chain-badge { display: inline-flex; align-items: center; gap: 0.45rem; }
.chain-dot { width: 0.6rem; height: 0.6rem; border-radius: 50%; flex: none; box-shadow: 0 0 8px currentColor; }

/* Freshness: a lit dot for a recent reading, a dim one for a stale one. */
.freshness { display: inline-flex; align-items: center; gap: 0.45rem; }
.freshness .dot { width: 0.45rem; height: 0.45rem; }
.freshness .dot.stale { background: var(--ink-3); box-shadow: none; }

/* Sortable headers. */
th.sortable { cursor: pointer; user-select: none; }
th.sortable:hover { color: var(--ink); }
th.sortable::after { content: " ⇅"; opacity: 0.35; font-size: 0.8em; }
th.sortable.asc::after  { content: " ↑"; opacity: 1; color: var(--violet-2); }
th.sortable.desc::after { content: " ↓"; opacity: 1; color: var(--violet-2); }

/* Row emphasis, from the reference: a lit left edge on hover. */
tbody tr { position: relative; transition: background 0.15s ease; }
tbody tr:hover { background: rgba(139, 92, 246, 0.10); }
tbody tr:hover td:first-child { box-shadow: inset 3px 0 0 var(--violet); }

/* Coverage bar inside a table cell. */
.cell-progress { display: flex; align-items: center; gap: 0.6rem; min-width: 9rem; }
.cell-progress .bar-track { flex: 1; height: 0.4rem; }
.cell-progress .pct { font-family: var(--mono); font-size: 0.74rem; color: var(--ink); min-width: 3.2rem; text-align: right; }

/* Summary tiles under the sweeps table. */
.summary { display: grid; grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); gap: 1rem; padding: 1.1rem; border-top: 1px solid var(--rule-soft); }
.summary-tile { display: flex; align-items: center; gap: 0.8rem; }
.summary-icon {
  width: 2.4rem; height: 2.4rem; flex: none; border-radius: 12px; display: grid; place-items: center;
  background: rgba(139, 92, 246, 0.15); border: 1px solid rgba(196, 151, 255, 0.35);
  color: var(--violet-2); box-shadow: inset 0 0 16px rgba(167, 139, 250, 0.28);
}
.summary-icon.ok   { color: #5ef2a0; border-color: rgba(94,242,160,.4); background: rgba(74,222,128,.12); }
.summary-icon.crit { color: #ff8fa3; border-color: rgba(255,143,163,.4); background: rgba(251,113,133,.12); }
.summary-icon svg { width: 1.15rem; height: 1.15rem; }
.summary-label { font-size: 0.68rem; letter-spacing: 0.13em; color: var(--ink-2); font-weight: 600; }
.summary-value { font-size: 1.3rem; font-weight: 700; color: #fff; text-shadow: 0 0 18px rgba(167,139,250,.5); }
.summary-sub { font-size: 0.76rem; color: var(--ink-3); }

/* Params rendered verbatim, in a box. What the approver reads has to be what
   the signer executes, so this is never prettified into a summary. */
.params-box {
  font-family: var(--mono); font-size: 0.74rem; line-height: 1.5; color: var(--ink-2);
  background: rgba(139, 92, 246, 0.08); border: 1px solid rgba(167, 139, 250, 0.22);
  border-radius: 8px; padding: 0.5rem 0.7rem; max-width: 34rem;
  /* `pre`, not `pre-wrap` with `break-all`. Breaking mid-token split addresses
     and wei amounts across lines, which is the one place on this screen where a
     digit read wrong costs money — the approver is checking these against what
     the signer will execute. Long values scroll inside the box instead. */
  white-space: pre; overflow-x: auto;
}

.table-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  flex-wrap: wrap; padding: 0.85rem 1.1rem; border-top: 1px solid var(--rule-soft);
  font-size: 0.76rem; color: var(--ink-3);
}

/* ============================================================================
   Focus page — the pools the pilot is aimed at
   ==========================================================================
   Requested by the boss: show every Arbitrum ETH/USDC pool with its range and
   who controls its oracle, and DO NOT filter or exclude anything on the basis
   of that control. So nothing here ranks, hides or greys out a pool; the
   oracle block reports and stops. */

.focus-note {
  display: flex; align-items: flex-start; gap: 0.6rem;
  padding: 0.85rem 1.1rem; margin-bottom: 1.25rem;
  border-radius: var(--radius); font-size: 0.82rem; color: var(--ink-2);
  background: rgba(139, 92, 246, 0.10);
  border: 1px solid rgba(167, 139, 250, 0.28);
}
.focus-note svg { width: 1.1rem; height: 1.1rem; flex: none; color: var(--violet-2); margin-top: 0.1rem; }

.focus-card { margin-bottom: 1.25rem; }
.focus-head {
  display: flex; align-items: center; gap: 0.9rem; flex-wrap: wrap;
  padding: 1.1rem 1.3rem; border-bottom: 1px solid var(--rule-soft);
}
.focus-title { font-size: 1.15rem; font-weight: 700; color: #fff; letter-spacing: -0.01em; }
.focus-addr { font-family: var(--mono); font-size: 0.78rem; color: var(--ink-3); }
.focus-chosen {
  margin-left: auto; display: inline-flex; align-items: center; gap: 0.4rem;
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.1em;
  padding: 0.3rem 0.8rem; border-radius: 999px;
  background: rgba(74, 222, 128, 0.14); color: #5ef2a0;
  border: 1px solid rgba(94, 242, 160, 0.5);
  box-shadow: 0 0 18px -6px rgba(94, 242, 160, 0.8);
}

.focus-body {
  display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  gap: 1.5rem; padding: 1.3rem;
}
@media (max-width: 66rem) { .focus-body { grid-template-columns: 1fr; } }

.focus-sub {
  font-size: 0.7rem; letter-spacing: 0.14em; font-weight: 700;
  color: var(--violet-2); margin-bottom: 0.7rem;
}

/* The bin ladder. Each bin is a segment; the cursor marks where the oracle
   price sits right now. */
.ladder { display: flex; gap: 2px; align-items: flex-end; height: 3.2rem; }
.ladder i {
  flex: 1; min-width: 2px; border-radius: 2px; height: 55%;
  background: rgba(167, 139, 250, 0.30);
}
.ladder i.cursor {
  height: 100%;
  background: linear-gradient(180deg, #f0abfc, #a855f7);
  box-shadow: 0 0 14px 2px rgba(232, 121, 249, 0.85);
}
.ladder-scale {
  display: flex; justify-content: space-between;
  font-family: var(--mono); font-size: 0.7rem; color: var(--ink-3); margin-top: 0.4rem;
}

.focus-facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); gap: 0.9rem; margin-top: 1.2rem; }
.focus-fact-label { font-size: 0.66rem; letter-spacing: 0.13em; color: var(--ink-3); font-weight: 600; }
.focus-fact-value { font-size: 1.05rem; font-weight: 700; color: #fff; margin-top: 0.15rem; }
.focus-fact-value.small { font-size: 0.85rem; font-family: var(--mono); font-weight: 600; }

/* Oracle control. Reported, never used as a gate. */
.oracle-row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
  padding: 0.55rem 0; border-bottom: 1px solid var(--rule-soft);
}
.oracle-row:last-child { border-bottom: none; }
.oracle-key { font-size: 0.78rem; color: var(--ink-2); }
.oracle-val { font-family: var(--mono); font-size: 0.78rem; color: var(--ink); text-align: right; }
.oracle-val.crit { color: #ff8fa3; }
.oracle-val.ok   { color: #5ef2a0; }

/* ── copyable hashes ────────────────────────────────────────────────────────
   A truncated hash is unusable: it cannot be pasted into an explorer and it
   cannot be compared against anything. So every one carries its full value and
   two ways to get at it — a link out, and one click to the clipboard. */
.hashcell { display: inline-flex; align-items: center; gap: 0.4rem; }
.hashcell a {
  font-family: var(--mono); font-size: 0.79rem; color: var(--violet-2);
  text-decoration: none; border-bottom: 1px dashed rgba(167, 139, 250, 0.45);
}
.hashcell a:hover { color: #f0abfc; border-bottom-color: #f0abfc; }
.copy-btn {
  flex: none; width: 1.4rem; height: 1.4rem; padding: 0; cursor: pointer;
  display: grid; place-items: center; border-radius: 6px;
  background: rgba(139, 92, 246, 0.12); border: 1px solid rgba(167, 139, 250, 0.3);
  color: var(--ink-2); font: inherit; font-size: 0.7rem; line-height: 1;
}
.copy-btn:hover { background: rgba(139, 92, 246, 0.25); color: #fff; }
.copy-btn.done { background: rgba(74, 222, 128, 0.2); border-color: rgba(94, 242, 160, 0.6); color: #5ef2a0; }
.copy-btn svg { width: 0.8rem; height: 0.8rem; }

/* ── our position ──────────────────────────────────────────────────────────
   Same shell as the hero, because it carries the same weight: this is the only
   thing on the page that is our own money. Everything inside is a measurement,
   so nothing here is allowed to be decorative at the expense of a number. */
.posn {
  position: relative; overflow: hidden;
  border-radius: 22px;
  border: 1px solid rgba(196, 151, 255, 0.38);
  background:
    radial-gradient(420px 240px at 10% 6%, rgba(139, 92, 246, 0.26), transparent 62%),
    radial-gradient(460px 260px at 90% 8%, rgba(232, 121, 249, 0.20), transparent 62%),
    linear-gradient(160deg, #1a1140 0%, #120b2c 60%, #0c0722 100%);
  box-shadow:
    inset 0 0 0 1px rgba(196, 151, 255, 0.12),
    0 0 50px -14px rgba(196, 151, 255, 0.35),
    0 24px 60px -34px rgba(139, 92, 246, 0.9);
  padding: 1.35rem 1.5rem 1.2rem;
}

.posn-top { display: flex; align-items: flex-start; gap: 0.9rem; flex-wrap: wrap; }
.posn-mark {
  width: 2.4rem; height: 2.4rem; border-radius: 12px; flex: none;
  display: grid; place-items: center;
  background: var(--grad-brand); color: #fff;
  font-size: 0.68rem; font-weight: 700; letter-spacing: 0.04em;
}
.posn-title { margin: 0; font-size: 1rem; font-weight: 650; letter-spacing: -0.01em; }
.posn-where { margin: 0.15rem 0 0; font-size: 0.72rem; color: var(--ink-3); }
.posn-spacer { flex: 1 1 6rem; }

/* The two figures that answer the question, side by side and unmissable. */
.posn-figures { display: flex; gap: 2.2rem; flex-wrap: wrap; align-items: flex-end; }
.posn-label {
  font-size: 0.68rem; letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--ink-3); font-weight: 600;
}
.posn-worth {
  font-size: 2.1rem; font-weight: 700; letter-spacing: -0.02em; line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.posn-delta {
  font-size: 1.5rem; font-weight: 700; line-height: 1.15;
  font-variant-numeric: tabular-nums;
}
.posn-delta.up   { color: var(--ok); }
.posn-delta.down { color: var(--crit); }
.posn-delta.flat { color: var(--ink-2); }
.posn-note { font-size: 0.68rem; color: var(--ink-3); margin-top: 0.2rem; }

/* Composition. The story this position tells is that its mix drifts as the pool
   trades against it, so the two bars are stacked to be compared directly. */
.posn-mix { margin-top: 1.25rem; }
.posn-bar {
  display: flex; height: 0.6rem; border-radius: 999px; overflow: hidden;
  background: var(--surface-2); margin: 0.3rem 0 0.15rem;
}
.posn-bar i { display: block; height: 100%; }
.posn-bar .a { background: linear-gradient(90deg, var(--violet), var(--violet-2)); }
.posn-bar .b { background: linear-gradient(90deg, var(--cyan), #67e8f9); }
.posn-bar-row + .posn-bar-row { margin-top: 0.6rem; }
.posn-bar-key {
  display: flex; justify-content: space-between; gap: 1rem;
  font-size: 0.68rem; color: var(--ink-2); font-variant-numeric: tabular-nums;
}
.posn-bar-name { font-size: 0.68rem; letter-spacing: 0.07em; text-transform: uppercase; color: var(--ink-3); }

.posn-swatch { display: inline-block; width: 0.5rem; height: 0.5rem; border-radius: 2px; margin-right: 0.35rem; }
.posn-swatch.a { background: var(--violet-2); }
.posn-swatch.b { background: var(--cyan); }

/* The reading history. Flat is the expected shape at this size, and a flat line
   that is honestly flat beats a chart rescaled until it looks eventful. */
.posn-spark { margin-top: 1.2rem; }
.posn-spark svg { width: 100%; height: 3.4rem; display: block; }
.posn-spark .ln { fill: none; stroke: var(--accent-2); stroke-width: 1.6; stroke-linejoin: round; }
.posn-spark .zero { stroke: var(--rule); stroke-width: 1; stroke-dasharray: 3 3; }
.posn-spark .fillup { fill: rgba(74, 222, 128, 0.14); }
.posn-spark .filldn { fill: rgba(251, 113, 133, 0.14); }

.posn-foot {
  margin-top: 1.1rem; padding-top: 0.85rem; border-top: 1px solid var(--rule-soft);
  display: flex; gap: 1.6rem; flex-wrap: wrap;
  font-size: 0.68rem; color: var(--ink-3);
}
.posn-foot b { color: var(--ink-2); font-weight: 600; }

@media (max-width: 40rem) {
  .posn-worth { font-size: 1.6rem; }
  .posn-delta { font-size: 1.2rem; }
  .posn-figures { gap: 1.2rem; }
}

/* ── the profit chart's hover readout and range switches ───────────────────
   The readout snaps to a real reading; the dot marks it exactly and the pill
   pins to the top of the frame so it never covers the line it describes. All
   three are pointer-transparent, or they would flicker under their own mouse. */
.spark-head { display: flex; justify-content: space-between; align-items: center; gap: 1rem; }
.spark-ranges { display: flex; gap: 0.3rem; }
.spark-range {
  font: inherit; font-size: 0.68rem; line-height: 1;
  padding: 0.28rem 0.6rem; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--rule); background: var(--surface-2); color: var(--ink-2);
}
.spark-range:hover { border-color: var(--accent); color: var(--ink); }
.spark-range.active { background: var(--grad-brand); color: #fff; border-color: transparent; }

.spark-frame { position: relative; }
.spark-cross {
  position: absolute; top: 0; bottom: 0; width: 1px;
  background: var(--ink-3); opacity: 0.55; pointer-events: none;
}
.spark-dot {
  position: absolute; width: 0.55rem; height: 0.55rem; border-radius: 50%;
  background: var(--accent-2); border: 2px solid var(--paper);
  transform: translate(-50%, -50%); pointer-events: none;
}
.spark-tip {
  position: absolute; top: -0.35rem; transform: translate(-50%, -100%);
  white-space: nowrap; pointer-events: none; z-index: 5;
  font-size: 0.68rem; font-variant-numeric: tabular-nums;
  padding: 0.28rem 0.65rem; border-radius: 9px;
  background: var(--surface-3); border: 1px solid var(--rule); color: var(--ink);
  box-shadow: 0 6px 18px -8px rgba(0, 0, 0, 0.7);
}
.spark-tip.up { color: var(--ok); }
.spark-tip.down { color: var(--crit); }

/* ── the overview's market monitors ──────────────────────────────────────── */
.market-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(22rem, 1fr));
  gap: 1.25rem; margin-bottom: 1.25rem;
}
.price-big { font-size: 1.85rem; font-weight: 700; letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums; line-height: 1.1; }

/* Coin logos in the market cards: same footprint as the OURS mark, brand color
   behind an inline glyph — the panel ships its own pixels, nobody's CDN. */
.coin-mark { display: grid; place-items: center; }
.coin-mark svg { display: block; }

/* The deposit register folds its history away.
   Every position ever opened stays in the table, but the withdrawn ones sit behind one row so the
   list answers "what is deposited right now" before it answers "what have we ever done". */
.deposit-fold { cursor: pointer; }
.deposit-fold > td {
  padding: 0.7rem 0.9rem;
  color: var(--ink-2);
  font-size: 0.82rem;
  background: rgba(148, 163, 184, 0.06);
  border-top: 1px solid var(--rule-soft);
}
.deposit-fold:hover > td { background: rgba(167, 139, 250, 0.1); color: #fff; }
.deposit-fold:focus-visible { outline: 2px solid var(--accent, #a78bfa); outline-offset: -2px; }
.fold-arrow {
  display: inline-block; width: 0.5rem; height: 0.5rem; margin-right: 0.55rem;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(-45deg); transition: transform 0.15s ease; vertical-align: 1px;
}
.deposit-fold[aria-expanded="true"] .fold-arrow { transform: rotate(45deg); }
.deposit-fold[aria-expanded="true"] > td { background: rgba(167, 139, 250, 0.08); }
.deposit-none > td { padding: 1.1rem 0.9rem; color: var(--ink-3); font-size: 0.85rem; }
tr[data-closed] > td { opacity: 0.72; }
