/* Staker dashboard - clean, professional, financial-portal styling.
   One accent hue (teal-green, evoking SOL/growth) used consistently; text in
   neutral ink tokens, never the accent, per data-viz rules. */
:root {
  --bg: #f4f6f9;
  --bg-2: #eef1f6;           /* slightly deeper, for subtle panel contrast */
  --surface: #ffffff;
  --surface-2: #fbfcfe;      /* raised surfaces (tile hover, insets) */
  --ink: #10141b;
  --ink-2: #4a5361;
  --ink-3: #828b99;
  --line: #e7eaf0;
  --line-2: #eef1f5;         /* fainter divider */
  /* Solana Company brand: purple -> teal gradient. Charts use the teal end as
     the single accent hue; the gradient itself is used for the brand mark and
     hero emphasis. */
  --brand-purple: #9945ff;
  /* I1 identity palette: colour = WHO, not "good". SOL Prime is always the
     brand purple; the network / peers are always neutral grey. Green and red
     are reserved for the verdict (delta chips), so a chart stays honest on a
     metric where we lose. */
  --id-us: #9945ff;
  --id-net: #94a0b3;
  /* B4: one colour for "this is THE action on this screen". In-app primary
     buttons were teal (--accent) while marketing primary buttons were purple,
     so the same role had two colours depending on which page you were on.
     Purple wins because --accent already means "selected / positive" in ~40
     other places (active tabs, toggles, chips) -- repointing --accent would
     have dragged all of those along with it. */
  --primary: #7c3aed;
  --primary-ink: #ffffff;
  --primary-ring: rgba(124,58,237,.4);
  --brand-teal: #14b89a;
  --brand-grad: linear-gradient(120deg, #9945ff 0%, #7d5cf5 42%, #14c8a8 100%);
  --accent: #12b394;          /* teal end - charts, buttons */
  --accent-weak: #ddf3ee;
  --accent-ink: #0b7360;
  --pos: #1a7f5a;
  --warn: #b7791f;
  /* DESTRUCTIVE, distinct from --warn. --warn is amber and means "be careful";
     deleting is not a caution, and a mustard button does not read as dangerous.
     Red is the only colour a delete confirm can honestly use. */
  --neg: #c0392b;
  --neg-weak: #fdecea;
  --neg-line: #f5c6c0;
  --neg-ink: #8e261b;
  --radius: 14px;
  --radius-sm: 10px;
  /* layered, soft shadows for a premium material feel */
  --shadow: 0 1px 2px rgba(16,20,27,.04), 0 4px 14px -4px rgba(16,20,27,.06);
  --shadow-lg: 0 2px 6px rgba(16,20,27,.05), 0 14px 40px -10px rgba(16,20,27,.14);
  --ring: 0 0 0 3px rgba(18,179,148,.18);   /* focus ring */
  --font-ui: "Inter var", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI",
    Roboto, Helvetica, Arial, "Noto Sans", "PingFang SC", "PingFang TC",
    "Microsoft YaHei", sans-serif;
  --font-num: "Inter var", "Inter", ui-monospace, "SF Mono", "Segoe UI", system-ui, sans-serif;
}
/* Dark palette, shared by (a) system-dark when no explicit choice is set, and
   (b) an explicit data-theme="dark". The theme switcher stamps data-theme on
   <html>; when it's "system" we remove the attribute and fall back to the media
   query. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0c0f14; --bg-2: #0f131a; --surface: #161b23; --surface-2: #222834;
    --ink: #eef1f6; --ink-2: #aeb8c6; --ink-3: #79828f;
    --line: #242b36; --line-2: #1d232d; --accent: #2fd0b3; --accent-weak: #123a35;
    --accent-ink: #74e6d6;
    --shadow: 0 1px 2px rgba(0,0,0,.4), 0 6px 18px -6px rgba(0,0,0,.5);
    --shadow-lg: 0 2px 8px rgba(0,0,0,.5), 0 18px 46px -12px rgba(0,0,0,.6);
    --ring: 0 0 0 3px rgba(47,208,179,.22);
    --neg: #e05a4a; --neg-weak: #3a1e1a; --neg-line: #5c2b24; --neg-ink: #ff9d90;
  --id-us: #b06bff; --id-net: #7d8899;
  --primary: #8b5cf6; --primary-ink: #ffffff; --primary-ring: rgba(139,92,246,.45);
  }
}
:root[data-theme="dark"] {
  --bg: #0c0f14; --bg-2: #0f131a; --surface: #161b23; --surface-2: #222834;
  --ink: #eef1f6; --ink-2: #aeb8c6; --ink-3: #79828f;
  --line: #242b36; --line-2: #1d232d; --accent: #2fd0b3; --accent-weak: #123a35;
  --accent-ink: #74e6d6;
  --shadow: 0 1px 2px rgba(0,0,0,.4), 0 6px 18px -6px rgba(0,0,0,.5);
  --shadow-lg: 0 2px 8px rgba(0,0,0,.5), 0 18px 46px -12px rgba(0,0,0,.6);
  --ring: 0 0 0 3px rgba(47,208,179,.22);
  --neg: #e05a4a; --neg-weak: #3a1e1a; --neg-line: #5c2b24; --neg-ink: #ff9d90;
  --id-us: #b06bff; --id-net: #7d8899;
  --primary: #8b5cf6; --primary-ink: #ffffff; --primary-ring: rgba(139,92,246,.45);
}
* { box-sizing: border-box; }
body {
  margin: 0; background: var(--bg); color: var(--ink);
  font-family: var(--font-ui); font-size: 15px; line-height: 1.55;
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
  font-feature-settings: "cv02", "cv03", "cv04", "cv11", "ss01";
  letter-spacing: -0.006em;
  text-rendering: optimizeLegibility;
}
/* all tabular numbers get true monospaced-digit alignment + slashed zero */
.value, .num, td.num, .tile .value, [class*="tabular"], .valstats b {
  font-feature-settings: "tnum" 1, "zero" 1; font-variant-numeric: tabular-nums slashed-zero;
}
.hidden { display: none !important; }
::selection { background: var(--accent-weak); color: var(--accent-ink); }

/* top bar */
.topbar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 24px; background: var(--surface);
  border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 5;
}
.brand { display: flex; align-items: center; gap: 10px; font-weight: 700; font-size: 16px; }
.brand .dot { width: 12px; height: 12px; border-radius: 50%;
  background: var(--brand-grad); }
/* logo: black variant on light theme, white on dark; hide the text label when
   a logo image is present so we don't double up. */
.brand .logo { height: 34px; width: auto; display: block; }
.brand .logo-white { display: none; }
/* system dark (no explicit light choice) -> white logo */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .brand .logo-black { display: none; }
  :root:not([data-theme="light"]) .brand .logo-white { display: block; }
}
/* explicit dark -> white logo; explicit light -> black logo (wins over system) */
:root[data-theme="dark"] .brand .logo-black { display: none; }
:root[data-theme="dark"] .brand .logo-white { display: block; }
:root[data-theme="light"] .brand .logo-black { display: block; }
:root[data-theme="light"] .brand .logo-white { display: none; }
.brand.has-logo .brand-text, .brand.has-logo .dot { display: none; }
.valstats { display: flex; gap: 22px; flex-wrap: wrap; font-size: 13px; color: var(--ink-2); }
.valstats b { color: var(--ink); font-variant-numeric: tabular-nums; }

.wrap { max-width: 960px; margin: 0 auto; padding: 24px 20px 60px; }

/* ---- app shell with left sidebar ---- */
/* INTERNAL-ONLY banner (admin/internal pages only) — a fixed red bar pinned to
   the very top so the internal view is unmistakably distinct from the client view.
   Body gets padding-top when present, and the sticky sidebar/content-top offsets
   shift down by the banner height so nothing hides beneath it. */
:root { --internal-banner-h: 30px; }
.internal-banner {
  position: fixed; top: 0; left: 0; right: 0; z-index: 200;
  height: var(--internal-banner-h); line-height: var(--internal-banner-h);
  background: #f5c518; color: #3a2e00; text-align: center;
  font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  box-shadow: 0 1px 6px rgba(0,0,0,.25); user-select: none;
  /* The bar is a FIXED 30px tall, so the text must never wrap -- a second
     line would be clipped. Keep it on one line and let it shrink instead. */
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding: 0 8px;
}
@media (max-width: 420px) {
  /* "(BETA VERSION)" pushes the string past a phone width at 12px. */
  .internal-banner { font-size: 10px; letter-spacing: .03em; }
}
body.has-internal-banner { padding-top: var(--internal-banner-h); }
body.has-internal-banner .sidebar { top: var(--internal-banner-h); height: calc(100vh - var(--internal-banner-h)); }
body.has-internal-banner .content-top { top: var(--internal-banner-h); }

.shell { display: grid; grid-template-columns: 232px 1fr; min-height: 100vh; }
.sidebar {
  background: var(--surface); border-right: 1px solid var(--line);
  display: flex; flex-direction: column; padding: 16px 12px 10px; gap: 2px;
  position: sticky; top: 0; height: 100vh; overflow-y: auto;
  /* hide the scrollbar chrome but keep scrollability if it ever overflows */
  scrollbar-width: none; -ms-overflow-style: none;
}
.sidebar::-webkit-scrollbar { width: 0; height: 0; }
.sidebar .brand { padding: 4px 8px 12px; }
.sidebar .brand .logo { height: 30px; }
.navsection { font-size: 10px; text-transform: uppercase; letter-spacing: .07em;
  color: var(--ink-3); font-weight: 700; padding: 14px 10px 5px; opacity: .85; }

/* validator picker */
.valpicker { position: relative; margin: 4px 4px 10px; }
/* client wallet-count badge under the validator picker */
.wallet-count { display: flex; align-items: center; gap: 8px; margin: 0 4px 12px; padding: 8px 10px;
  border: 1px solid var(--line); border-radius: 9px; background: var(--surface-2); }
.wallet-count .wc-ico { font-size: 15px; line-height: 1; }
.wallet-count .wc-n { font-size: 15px; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--ink); }
.wallet-count .wc-lbl { font-size: 11.5px; font-weight: 600; letter-spacing: .02em; color: var(--ink-3);
  text-transform: uppercase; }
.valpicker-btn { display: flex; align-items: center; gap: 8px; width: 100%; padding: 8px 10px;
  border: 1px solid var(--line); border-radius: 9px; background: var(--bg); color: var(--ink);
  font-size: 13px; font-weight: 600; cursor: pointer; }
.valpicker-btn.single { cursor: default; }
.valpicker-btn .vp-caret { margin-left: auto; color: var(--ink-3); font-size: 11px; }
.valpicker-btn.single .vp-caret { display: none; }
.vp-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--brand-grad); flex: none; }
.valpicker-menu { position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 20;
  background: var(--surface); border: 1px solid var(--line); border-radius: 10px; padding: 5px;
  box-shadow: var(--shadow); display: none; }
.valpicker-menu.open { display: block; }
.vp-item { display: flex; align-items: center; gap: 8px; width: 100%; padding: 8px 9px;
  border: 0; background: none; color: var(--ink-2); font-size: 13px; border-radius: 7px;
  cursor: pointer; text-align: left; }
.vp-item:hover { background: var(--bg); color: var(--ink); }
.vp-item.on { color: var(--accent-ink); font-weight: 600; }
.vp-item .vp-sub { margin-left: auto; font-size: 11px; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.navitem {
  display: flex; align-items: center; gap: 10px; padding: 7px 11px; border-radius: 8px;
  color: var(--ink-2); font-size: 13.5px; font-weight: 500; cursor: pointer; border: 0;
  background: none; width: 100%; text-align: left; text-decoration: none;
  /* force identical box metrics whether the item is a <button> or an <a> -
     buttons otherwise render a few px shorter, making the dashboard nav look
     tighter than the account/validators pages. */
  box-sizing: border-box; line-height: 20px; font-family: inherit;
  margin: 0; appearance: none; -webkit-appearance: none;
}
.navitem { position: relative; transition: background .14s ease, color .14s ease; }
.navitem:hover, .navitem:focus, .navitem:active { background: var(--bg); color: var(--ink); text-decoration: none; }
.navitem.active { background: var(--accent-weak); color: var(--accent-ink); font-weight: 600; }
.navitem.active::before { content: ""; position: absolute; left: -12px; top: 50%; transform: translateY(-50%);
  width: 3px; height: 18px; border-radius: 0 3px 3px 0; background: var(--brand-grad); }
.navitem .ico { width: 18px; text-align: center; opacity: .75; font-size: 14px; }
.navitem.active .ico { opacity: 1; }
.sidebar .spacer { flex: 1; }
.sidebar-foot { padding: 12px 10px; border-top: 1px solid var(--line); margin-top: 8px; flex: none;
  display: flex; flex-direction: column; gap: 10px; }
.sidebar-foot .who { font-size: 13px; color: var(--ink-2); }
.sidebar-foot .who b { color: var(--ink); display: block; }
/* keep the theme toggle compact - don't let the column layout stretch it full-width */
.sidebar-foot .theme-toggle { align-self: flex-start; }

.content { min-width: 0; display: flex; flex-direction: column; }
/* Shown only for the demo/showcase account (sidebar.js, driven by /api/me's
   is_demo) -- a full-width strip above the page header, on every client page,
   so synthetic demo data is never mistaken for a real position. */
/* Demo banner. Mirrors .internal-banner: fixed to the VIEWPORT, not the content
   column, so it spans the full width including over the sidebar -- it used to be
   inserted inside .content and only spanned the panel, which read as part of the
   page rather than a standing warning about the data. Orange-red so it is
   clearly distinct from the yellow internal-only bar. */
.demo-banner {
  position: fixed; top: 0; left: 0; right: 0; z-index: 200;
  height: var(--internal-banner-h); line-height: var(--internal-banner-h);
  background: #f6c99a; color: #6b3410; text-align: center;
  font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  box-shadow: 0 1px 6px rgba(0,0,0,.25); user-select: none;
}
body.has-demo-banner { padding-top: var(--internal-banner-h); }
body.has-demo-banner .sidebar { top: var(--internal-banner-h); height: calc(100vh - var(--internal-banner-h)); }
body.has-demo-banner .content-top { top: var(--internal-banner-h); }
.content-top {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 8px 16px;   /* wrap the two groups instead of overlapping when tight */
  padding: 14px 30px; border-bottom: 1px solid var(--line);
  background: var(--surface);   /* fallback for no color-mix support */
  background: color-mix(in srgb, var(--surface) 82%, transparent);
  -webkit-backdrop-filter: saturate(180%) blur(12px); backdrop-filter: saturate(180%) blur(12px);
  position: sticky; top: 0; z-index: 5;
  min-height: 66px; box-sizing: border-box;   /* uniform header height across pages */
}
/* both header groups may shrink so their contents never collide */
.content-top > div { min-width: 0; }
.content-top h1 { font-size: 19px; margin: 0; letter-spacing: -0.018em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Center the page BODY in a max-width column (instead of hugging the left). The
   sticky header stays FULL-WIDTH (edge to edge) so its two groups — page title +
   the control cluster — always have room to sit on one row; forcing the header
   into the same narrow centered column made it wrap on wide screens. Its inner
   content is centered to line up with the body via the padding below. */
/* Body content sits in a centered max-width column. The sticky header stays
   FULL-WIDTH (edge to edge) — this is a standard app-header pattern and gives its
   two groups (page title + control cluster) the whole width, so they never wrap
   onto a second row on wide screens (the earlier centered-column header did). */
.content-inner { padding: 28px 34px 44px; max-width: 1320px; width: 100%; margin: 0 auto; flex: 1 0 auto; box-sizing: border-box; }
.content > .content-top { padding-left: 30px; padding-right: 30px; }
/* Keep the header on ONE row on desktop: don't wrap the two groups — let the title
   group (with its epoch progress bar) shrink instead. Mobile has its own rules. */
@media (min-width: 821px) {
  .content-top { flex-wrap: nowrap; }
  /* title group GROWS to claim spare width so the h1 only ellipsises when there's
     genuinely no room; the control cluster keeps its natural size and never wraps. */
  .content-top > div:first-child { min-width: 0; flex: 1 1 auto; }
  .content-top > div:last-child { flex: 0 0 auto; }
}

/* hamburger button — hidden on desktop, shown on mobile in the content top-bar */
.nav-toggle { display: none; align-items: center; justify-content: center;
  width: 38px; height: 38px; border: 1px solid var(--line); border-radius: 9px;
  background: var(--surface); color: var(--ink); cursor: pointer; padding: 0; flex: none; }
.nav-toggle:hover { background: var(--bg); border-color: var(--ink-3); }
.nav-toggle svg { width: 20px; height: 20px; }
/* dark overlay behind the open drawer */
.nav-overlay { display: none; position: fixed; inset: 0; background: rgba(0,0,0,.45);
  z-index: 40; opacity: 0; transition: opacity .2s ease; }

@media (max-width: 820px) {
  /* sidebar -> OFF-CANVAS DRAWER: hidden by default, slides in via the hamburger.
     This keeps the FULL vertical nav accessible on mobile (the old horizontal
     row overflowed the viewport and dropped the section labels). */
  .shell { grid-template-columns: 1fr; }
  .sidebar { position: fixed; top: 0; left: 0; bottom: 0; height: 100dvh;
    width: min(280px, 84vw); z-index: 50; flex-direction: column;
    border-right: 1px solid var(--line); border-bottom: 0;
    transform: translateX(-100%); transition: transform .24s ease;
    box-shadow: 2px 0 18px rgba(0,0,0,.18); overflow-y: auto; }
  body.nav-open .sidebar { transform: translateX(0) !important; }
  body.nav-open .nav-overlay { display: block; opacity: 1; }
  body.nav-open { overflow: hidden; }   /* lock page scroll while the drawer is open */
  .nav-toggle { display: inline-flex; }
  /* reset the desktop centering padding on mobile + stop the header overflowing */
  .content > .content-top { padding: 10px 14px; }
  .content-top { gap: 6px 8px; min-height: 56px; overflow: hidden; flex-wrap: nowrap; }
  .content-top > div { min-width: 0; }
  .content-top > div:first-child { flex: 1 1 auto; }   /* title side shrinks */
  .content-top > div:last-child { flex: 0 0 auto; }    /* controls keep their size */
  .content-top h1 { font-size: 17px; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
  /* hamburger sits inside the title group, left of the title */
  .content-top > div:first-child { display: flex; align-items: center; gap: 10px; }
  /* simple pages (Account, Performance): header is <h1> + <div#acctMenu> directly,
     no wrapping div. Push the account menu to the right so ☰ + title hug the left. */
  .content-top > h1 { margin-right: auto; }
  .content-top > .nav-toggle + h1 { margin-left: 0; }
  .content-inner { padding: 16px 14px 48px; }
  .content-top #epochBadge { display: none; }   /* save space; shown on validator view */
}

/* CRAMPED-DESKTOP zone (821–1080px, e.g. iPad / Surface Pro landscape): the sidebar
   is still shown so the content column is narrow, but the header is on ONE nowrap
   row with non-shrinking controls — the informational badges (live epoch progress +
   price, settled-through-epoch) would collide with the currency toggle / account
   menu. Hide those secondary read-outs here (they're on the Overview panels anyway);
   keep the interactive controls. Below 821px the mobile drawer rules take over. */
@media (min-width: 821px) and (max-width: 1180px) {
  .content-top #epochBadge,
  .content-top #settledBadge,
  .content-top #priceBadge { display: none; }
}

/* general small-screen rules (apply to all pages) */
@media (max-width: 640px) {
  .wrap { padding: 16px 14px 48px; }
  .topbar { padding: 12px 14px; }
  .brand .logo { height: 28px; }
  .tiles { grid-template-columns: 1fr 1fr; gap: 10px; }
  .tile { padding: 14px 14px; }
  .tile .value { font-size: 22px; }
  .panel { padding: 16px 15px; }
  h1 { font-size: 21px; }
  /* tables scroll horizontally instead of overflowing the viewport */
  table { display: block; overflow-x: auto; white-space: nowrap; }
  .acct-name { display: none; }                 /* avatar only on mobile */
  .acct-menu { width: min(250px, calc(100vw - 28px)); }
  .searchrow { flex-direction: column; }
  .searchrow button { width: 100%; }
  .vs-inner { flex-direction: column; gap: 8px; }
  /* top-bar: keep every control on ONE row and stop them overlapping.
     Drop the least-essential items so the globe/bell/avatar always fit. */
  .content-top { gap: 8px; }
  .content-top > div { gap: 8px !important; min-width: 0; }
  .content-top > div:last-child { flex: none; }
  .price-badge { display: none; }               /* SOL price hidden on mobile */
  #report { display: none; }                    /* report button hidden on mobile */
  .lang-globe { padding: 6px 7px; }
  /* The language code stays visible. It used to be hidden here to save width,
     leaving a bare globe that gave no clue which language was active -- and
     the width it saved (about 20px) was then spent several times over by the
     "Display:" label B14 added to the currency selector on the same row.
     That label is the one that does not earn its space on a phone: the
     select shows "SOL"/"USD", which says what it is. */
  .cur-lbl { display: none; }
  .notif-btn, .lang-globe { font-size: 16px; }
  .lang-menu { width: min(200px, calc(100vw - 28px)); }
  .notif-menu { width: min(300px, calc(100vw - 28px)); }
}
@media (max-width: 400px) {
  .tiles { grid-template-columns: 1fr; }
}
.panel {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 24px 26px; margin-bottom: 22px; box-shadow: var(--shadow);
}
h1 { font-size: 25px; margin: 0 0 6px; letter-spacing: -0.021em; font-weight: 700; }
h2 { font-size: 17px; margin: 0 0 4px; letter-spacing: -0.014em; font-weight: 700; }
.sub { color: var(--ink-2); font-size: 13.5px; margin: 0 0 15px; line-height: 1.6; }

/* search */
.search h1 { margin-top: 0; }
.searchrow { display: flex; gap: 10px; margin-top: 6px; }
#addr {
  flex: 1; padding: 12px 14px; font-size: 15px; border: 1px solid var(--line);
  border-radius: 10px; background: var(--bg); color: var(--ink); font-family: ui-monospace, "SF Mono", Menlo, monospace;
}
#addr:focus { outline: 2px solid var(--accent); border-color: var(--accent); }
/* Base for ALL buttons: just reset chrome + cursor. No fill/shadow here, so
   utility buttons (nav items, tabs, toggles — all of which carry a class) don't
   inherit the accent look that was drawing a faint box around each nav item. */
button { cursor: pointer; font-family: inherit; border: 0; background: none; color: inherit; }
button:disabled { opacity: .5; cursor: default; }
/* Primary action buttons = classless buttons (this app gives every utility
   button a class) + anything explicitly marked .btn-primary. */
button:not([class]), button.btn-primary, .modalbtns button.danger {
  padding: 11px 20px; font-size: 14.5px; font-weight: 600; border: 1px solid transparent;
  border-radius: var(--radius-sm); background: var(--primary); color: var(--primary-ink);
  letter-spacing: -0.005em;
  box-shadow: 0 1px 2px rgba(16,20,27,.08), inset 0 1px 0 rgba(255,255,255,.14);
  transition: filter .15s ease, transform .08s ease, box-shadow .15s ease;
}
button:not([class]):hover, button.btn-primary:hover {
  filter: brightness(1.06); box-shadow: 0 3px 10px -2px var(--primary-ring); }
button:not([class]):active, button.btn-primary:active, .modalbtns button.danger:active { transform: translateY(1px); }
button:focus-visible { outline: none; box-shadow: var(--ring); }
button.secondary {
  padding: 11px 20px; font-size: 14.5px; font-weight: 600; border-radius: var(--radius-sm);
  background: var(--surface); color: var(--ink); border: 1px solid var(--line);
  box-shadow: 0 1px 2px rgba(16,20,27,.04);
  transition: background .15s ease, border-color .15s ease, box-shadow .15s ease;
}
button.secondary:hover { background: var(--bg); border-color: var(--ink-3); box-shadow: 0 1px 2px rgba(16,20,27,.06); }
button:disabled { opacity: .5; cursor: default; box-shadow: none; }

/* "Download report" — a distinct, sharper CTA in the brand purple, set apart
   from the teal primary and the muted secondary. */
button.btn-report, a.btn-report {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 9px 16px; font-size: 13.5px; font-weight: 600; letter-spacing: -0.005em;
  border: 1px solid transparent; border-radius: 9px; color: #fff; cursor: pointer;
  text-decoration: none;
  background: linear-gradient(120deg, #8b46f0 0%, #7d5cf5 55%, #6d4bf0 100%);
  box-shadow: 0 1px 2px rgba(60,25,120,.22), 0 6px 16px -6px rgba(125,92,245,.5),
    inset 0 1px 0 rgba(255,255,255,.18);
  transition: filter .15s ease, transform .08s ease, box-shadow .15s ease;
}
button.btn-report:hover, a.btn-report:hover { filter: brightness(1.07);
  box-shadow: 0 2px 4px rgba(60,25,120,.24), 0 10px 22px -6px rgba(125,92,245,.6),
    inset 0 1px 0 rgba(255,255,255,.2); }
button.btn-report:active, a.btn-report:active { transform: translateY(1px); }
button.btn-report .rep-ico, a.btn-report .rep-ico { font-size: 14px; line-height: 1; }

/* ===== monthly statement page ===== */
.stmt-rows { display: flex; flex-direction: column; }
.stmt-row { display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 16px 4px; border-bottom: 1px solid var(--line); flex-wrap: wrap; }
.stmt-row:last-child { border-bottom: 0; }
.stmt-month { font-weight: 700; font-size: 15px; display: flex; align-items: center; gap: 8px; }
.stmt-latest { font-size: 10.5px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em;
  color: var(--accent-ink); background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 999px; padding: 2px 8px; }
/* provisional (current in-progress month) — amber tag, distinct from the green "latest" */
.stmt-provisional { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  color: var(--warn); background: #fdf4e3; border: 1px solid #f0dcae; border-radius: 999px; padding: 2px 8px; }
.stmt-prov-note { color: var(--warn); }
.stmt-sub { font-size: 12.5px; color: var(--ink-3); margin-top: 3px; font-variant-numeric: tabular-nums; }
.rb-provisional { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  color: var(--warn); background: #fdf4e3; border: 1px solid #f0dcae; border-radius: 999px;
  padding: 1px 7px; margin-left: 6px; vertical-align: 1px; }
.stmt-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.stmt-rebate-note { margin: 0 0 14px; font-size: 12.5px; color: var(--accent-ink);
  background: var(--surface-2); border: 1px solid var(--line); border-radius: 10px; padding: 10px 14px; }
@media (max-width: 560px) { .stmt-row { flex-direction: column; align-items: stretch; }
  .stmt-actions { justify-content: stretch; } .stmt-actions .btn-report,
  .stmt-actions .secondary { flex: 1; justify-content: center; } }
button.btn-report:disabled { filter: grayscale(.3); }
.hint { margin-top: 10px; font-size: 13px; color: var(--ink-3); min-height: 18px; }
.hint.err { color: var(--warn); }

/* refined inputs (pages set their own box; this adds smooth focus everywhere) */
input, textarea, select { transition: border-color .15s ease, box-shadow .15s ease, background .15s ease; }
input:focus, textarea:focus, select:focus { outline: none !important; box-shadow: var(--ring); border-color: var(--accent) !important; }
input::placeholder, textarea::placeholder { color: var(--ink-3); opacity: .8; }

/* login / auth pages: soft branded ambient background + elevated card */
.login-wrap {
  position: relative; overflow: hidden;
  background:
    radial-gradient(1100px 520px at 15% -10%, rgba(153,69,255,.10), transparent 60%),
    radial-gradient(900px 480px at 100% 110%, rgba(18,200,168,.12), transparent 55%),
    var(--bg);
}
.login-card { box-shadow: var(--shadow-lg) !important; border-radius: 18px !important; }
.login-card h1 { letter-spacing: -0.02em; }

/* hero tiles */
.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 16px; margin-bottom: 22px; }
/* admin overview host now holds two labeled rows, each a horizontal tile row —
   so it must be a plain block, not a grid (a grid would column-wrap the rows).
   Scope to the admin host only: the client dashboard reuses id="tiles" on its
   .statstrip, and a bare #tiles{display:block} would out-specify the grid there
   and stack the stat tiles vertically. */
#tiles:not(.statstrip) { display: block; }
/* admin overview: two labeled rows (clients / our validator), tiles laid out
   HORIZONTALLY across the row. force 3-up on wide screens, wrap on narrow. */
.tiles-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-bottom: 20px; }
@media (max-width: 720px) { .tiles-row { grid-template-columns: 1fr; } }
.ov-rowlabel { font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-3); margin: 4px 2px 10px; }
/* general period filter bar above the overview tiles — right-aligned */
.ov-filter { display: flex; align-items: center; gap: 12px; margin: 0 2px 16px; justify-content: flex-end; }
/* clients-page sub-tabs (Clients | Delegator book) */
.subtabs { display: flex; gap: 4px; margin: 0 0 18px; border-bottom: 1px solid var(--line); }
.subtab { border: 0; background: none; color: var(--ink-3); cursor: pointer; font-size: 13.5px;
  font-weight: 600; padding: 9px 14px; border-bottom: 2px solid transparent; margin-bottom: -1px; }
.subtab:hover { color: var(--ink); }
.subtab.active { color: var(--accent-ink); border-bottom-color: var(--accent); }
.guide-tabbody { padding-top: 4px; }
.ov-filter-lbl { font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3); }
.ov-filter .ov-period { margin-top: 0; }
/* period segmented control (All-time / YTD / MTD) */
.ov-period { display: inline-flex; gap: 2px; margin-top: 10px; padding: 2px;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: 8px; }
.ov-period-btn { border: 0; background: none; color: var(--ink-3); cursor: pointer;
  font-size: 11px; font-weight: 700; letter-spacing: .03em; padding: 4px 9px; border-radius: 6px; }
.ov-period-btn:hover { color: var(--ink); }
.ov-period-btn.active { background: var(--accent); color: #fff; }
.tile {
  position: relative; background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 20px 22px; box-shadow: var(--shadow);
  transition: box-shadow .18s ease, transform .18s ease, border-color .18s ease;
}
.tile:hover { box-shadow: var(--shadow-lg); transform: translateY(-2px); border-color: var(--line); }
.tile .label { font-size: 11.5px; color: var(--ink-3); text-transform: uppercase;
  letter-spacing: .06em; font-weight: 600; }
.tile .value { font-size: 29px; font-weight: 700; margin-top: 8px; line-height: 1.1;
  letter-spacing: -0.02em; color: var(--ink); }
.tile .value .unit { font-size: 15px; font-weight: 600; color: var(--ink-3); margin-left: 4px; letter-spacing: 0; }
.tile .note { font-size: 12px; color: var(--ink-3); margin-top: 5px; }
.tile.accent .value { color: var(--accent-ink); }

/* ---- Overview redesign: hero band + stat strip + chart/side-panel grid ---- */

/* hero band — the headline portfolio value */
.hero {
  position: relative; overflow: hidden;
  display: flex; align-items: center; justify-content: space-between;
  gap: 28px; flex-wrap: wrap;
  background:
    radial-gradient(680px 300px at 8% -30%, rgba(153,69,255,.10), transparent 62%),
    radial-gradient(560px 320px at 102% 130%, rgba(20,200,168,.13), transparent 58%),
    var(--surface);
  border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow); padding: 26px 30px; margin-bottom: 16px;
}
.hero::before {   /* brand gradient rail on the left edge */
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px;
  background: var(--brand-grad);
}
.hero-main { min-width: 0; }
.hero-label { font-size: 11.5px; color: var(--ink-3); text-transform: uppercase;
  letter-spacing: .07em; font-weight: 600; }
.hero-value { font-size: 46px; font-weight: 800; line-height: 1.02; margin-top: 6px;
  letter-spacing: -0.03em; color: var(--ink); font-variant-numeric: tabular-nums slashed-zero; }
.hero-alt { font-size: 14px; color: var(--ink-2); margin-top: 6px; font-variant-numeric: tabular-nums; }
.hero-side { display: flex; align-items: center; gap: 24px; flex-wrap: wrap; }
.hero-metric { text-align: right; }
.hm-k { font-size: 11.5px; color: var(--ink-3); text-transform: uppercase; letter-spacing: .05em; font-weight: 600; }
.hm-v { font-size: 30px; font-weight: 700; color: var(--accent-ink); line-height: 1.1;
  font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }
.hm-d { font-size: 11.5px; color: var(--ink-3); margin-top: 2px; }
.hero-proj { max-width: 232px; padding: 14px 18px; border-radius: 14px;
  border: 1px solid var(--accent-weak);
  background: linear-gradient(135deg, rgba(153,69,255,.07), rgba(20,184,154,.10));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.04); }
.hp-head { display: flex; align-items: center; gap: 7px; }
.hp-ico { display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; border-radius: 6px; background: var(--accent-weak);
  color: var(--accent-ink); font-size: 13px; font-weight: 800; line-height: 1; }
.hp-k { font-size: 11px; color: var(--ink-3); text-transform: uppercase;
  letter-spacing: .05em; font-weight: 600; }
.hp-amt { font-size: 26px; font-weight: 800; line-height: 1.05; margin-top: 8px;
  letter-spacing: -0.02em; color: var(--accent-ink); font-variant-numeric: tabular-nums; }

/* compact stat strip (denser than .tiles — 4-up, tighter) */
.statstrip { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px; margin-bottom: 18px; }
.statstrip .tile { padding: 16px 18px; }
.statstrip .tile .value { font-size: 24px; margin-top: 6px; }

/* overview grid: earnings chart (wide) + validator-at-a-glance rail */
.ov-grid { display: grid; grid-template-columns: 1.7fr 1fr; gap: 20px; align-items: stretch; }
.ov-grid > .panel { margin-bottom: 0; }

/* validator-at-a-glance side panel */
.vglance { display: flex; flex-direction: column; }
.vg-head { display: flex; align-items: center; gap: 9px; margin-bottom: 4px; }
.vg-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--brand-grad);
  box-shadow: 0 0 0 3px var(--accent-weak); flex: 0 0 auto; }
.vg-epoch { margin: 16px 0 6px; }
.vg-epoch-top { display: flex; justify-content: space-between; align-items: baseline;
  font-size: 12.5px; color: var(--ink-2); margin-bottom: 5px; }
.vg-epoch-top b { color: var(--ink); }
.vg-list { margin: 8px 0 0; display: flex; flex-direction: column; }
.vg-row { display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--line-2); }
.vg-row:last-child { border-bottom: 0; }
.vg-row dt { font-size: 12.5px; color: var(--ink-3); font-weight: 600; }
.vg-row dd { margin: 0; font-size: 14px; color: var(--ink); font-weight: 600;
  text-align: right; font-variant-numeric: tabular-nums; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vg-row dd.accent { color: var(--accent-ink); }
.vg-status.ok { color: var(--pos); } .vg-status.warn { color: var(--warn); }
.vg-rank { color: var(--ink-3); font-weight: 500; }
.vg-link { margin-top: auto; padding-top: 16px; font-size: 13px; font-weight: 600;
  color: var(--accent-ink); text-decoration: none; }
.vg-link:hover { text-decoration: underline; }

@media (max-width: 1000px) {
  .ov-grid { grid-template-columns: 1fr; }
  /* keep the 3 stat tiles in one horizontal row on tablet/narrow-desktop
     widths — the minmax(0,1fr) tracks shrink to fit rather than wrapping. */
}
@media (max-width: 560px) {
  .hero { padding: 20px 20px; }
  .hero-value { font-size: 36px; }
  .hero-side { width: 100%; justify-content: space-between; }
  /* on a phone the 3-up row is too cramped — stack to a single column. */
  .statstrip { grid-template-columns: 1fr; }
}

/* charts */
.chart { width: 100%; }
.chart-legend { display: flex; gap: 18px; margin-top: 8px; font-size: 12.5px; color: var(--ink-2); }
.chart-legend span { display: inline-flex; align-items: center; gap: 6px; }
.chart-legend i { width: 12px; height: 12px; border-radius: 3px; display: inline-block; }
.chart svg { display: block; width: 100%; height: auto; max-width: 100%; }
.axis text { fill: var(--ink-3); font-size: 11px; }
.axis line, .axis path { stroke: var(--line); }
.gridline { stroke: var(--line); stroke-dasharray: 2 3; }
.tt {
  position: fixed; pointer-events: none; z-index: 40; opacity: 0;
  transition: opacity .08s; white-space: nowrap;
  background: #10141b; color: #fff; border: 1px solid rgba(255,255,255,.12);
  padding: 9px 12px; border-radius: 9px; font-size: 12.5px; line-height: 1.35;
  box-shadow: 0 6px 24px rgba(0,0,0,.35);
  display: flex; flex-direction: column; gap: 1px;
}
.tt .tt-k { font-size: 11px; color: #9aa4b2; text-transform: uppercase; letter-spacing: .04em; }
.tt b { font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums; color: #fff; }
.tt .tt-s { font-size: 11px; color: #9aa4b2; }

/* accounts table */
table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
/* wrap wide/dense tables in this so they scroll WITHIN their own box at any
   width instead of forcing the whole page to scroll horizontally. Preferred
   over the ≤640px `table{display:block}` hack (which leaves a dead zone at
   641–820px where the content column is narrow but the table still overflows). */
.table-scroll { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.table-scroll table { min-width: 480px; }

/* epoch-history pager */
.epoch-pager { display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-top: 12px; flex-wrap: wrap; }
.epoch-pager-info { font-size: 12.5px; color: var(--ink-3); }
.epoch-pager-btns { display: flex; align-items: center; gap: 10px; }
.epoch-pager-page { font-size: 12.5px; color: var(--ink-2); font-variant-numeric: tabular-nums; min-width: 44px; text-align: center; }
.pg-btn { width: 30px; height: 30px; border-radius: 8px; border: 1px solid var(--line);
  background: var(--surface); color: var(--ink); font-size: 16px; line-height: 1; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; padding: 0; }
.pg-btn:hover:not(:disabled) { background: var(--bg); border-color: var(--ink-3); }
.pg-btn:disabled { opacity: .4; cursor: not-allowed; }
/* rows-per-page selector inside a pager */
.pg-size { margin: 0 2px; padding: 2px 6px; font-size: 12.5px; color: var(--ink);
  background: var(--surface-2); border: 1px solid var(--line); border-radius: 6px; cursor: pointer;
  vertical-align: middle; }
.pg-size:focus { outline: none; border-color: var(--accent); }

/* rebate breakdown table */
.rb-earned { display: flex; justify-content: space-between; align-items: baseline;
  padding: 6px 0 12px; border-bottom: 1px solid var(--line); margin-bottom: 4px; }
.rb-earned b { font-variant-numeric: tabular-nums; }
/* composition of the net-staking-rewards total: inflation vs MEV sub-lines */
.rb-comp { margin: 0 0 14px; padding: 10px 12px; border-radius: 9px; background: var(--surface-2);
  border: 1px solid var(--line); }
.rb-comp-h { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-3);
  font-weight: 600; margin-bottom: 6px; }
.rb-comp-line { display: flex; justify-content: space-between; align-items: baseline; padding: 3px 0;
  font-size: 13px; }
.rb-comp-k { color: var(--ink-2); display: flex; align-items: center; gap: 7px; }
.rb-comp-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; display: inline-block; }
.rb-comp-dot.infl { background: #14b89a; }
.rb-comp-dot.mev { background: #9945ff; }
.rb-comp-v { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; }
.rb-comp-pct { color: var(--ink-3); font-weight: 500; font-size: 12px; margin-left: 4px; }
.rb-table { width: 100%; border-collapse: collapse; }
.rb-table th { font-size: 11.5px; color: var(--ink-3); text-transform: uppercase; letter-spacing: .02em; font-weight: 600; }
.rb-table td, .rb-table th { padding: 9px 12px; }
.rb-table .num { font-variant-numeric: tabular-nums; }
.rb-table tr.rb-total td { border-top: 1px solid var(--line); border-bottom: none;
  font-weight: 600; color: var(--accent-ink); padding-top: 12px; }
.rb-table tr.rb-total .rb-usd { color: var(--ink-3); font-weight: 400; }
th, td { text-align: left; padding: 11px 12px; border-bottom: 1px solid var(--line-2); }
thead th { border-bottom: 1px solid var(--line); }
tbody tr:last-child td, tbody tr:last-child th { border-bottom: 0; }
tbody tr { transition: background .12s ease; }
tbody tr:hover td { background: var(--bg-2); }
th { color: var(--ink-3); font-weight: 600; font-size: 11px; text-transform: uppercase; letter-spacing: .05em; }
td { color: var(--ink); }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums slashed-zero; }
td.addr { font-family: ui-monospace, Menlo, monospace; font-size: 12px; color: var(--ink-2); }
.badge { font-size: 11px; padding: 2px 8px; border-radius: 20px; background: var(--accent-weak); color: var(--accent-ink); font-weight: 600; }
.badge.warn { background: #fdf0d9; color: var(--warn); }
.badge.ok { background: rgba(26,127,90,.14); color: var(--pos); }
.badge-soft { background: var(--surface-2); color: var(--ink-3); border: 1px solid var(--line); }

/* delegator book: inline label editing */
.bk-namecell { white-space: nowrap; }
.bk-namecell .bk-name { margin-right: 8px; }
/* Label button. Was a bare pencil glyph at 11.5px in --ink-2 -- grey on grey and
   unreadable, so it looked like a rendering artefact rather than a control. Now
   it says what it does, a step larger and at full --ink-2 weight. */
.bk-lbl-btn { border: 1px solid var(--line); background: var(--surface-2); color: var(--ink-2);
  font-size: 12px; font-weight: 600; padding: 3px 10px; border-radius: 7px; cursor: pointer;
  vertical-align: middle; white-space: nowrap; }
.bk-lbl-btn:hover { border-color: var(--accent); color: var(--accent-ink);
  background: var(--surface); }
.bk-lbl-btn:focus-visible { outline: none; box-shadow: var(--ring); }
.bk-edit-in { padding: 6px 9px; font-size: 13px; border: 1px solid var(--accent); border-radius: 8px;
  background: var(--surface); color: var(--ink); width: 180px; max-width: 46vw; }
.bk-edit-in:focus { outline: none; box-shadow: var(--ring); }
.bk-save, .bk-cancel { font-size: 12.5px; font-weight: 600; padding: 5px 12px; border-radius: 8px;
  cursor: pointer; margin-left: 6px; vertical-align: middle; }
.bk-save { background: var(--accent); color: #fff; border: 0; }
.bk-save:hover { filter: brightness(1.06); }
.bk-save:disabled { opacity: .55; cursor: default; }

/* Staker book: sortable column headers. The marker hangs off .bk-th-lbl (the
   label), never off the th -- the stake column is right-aligned and wide, so a
   cell-anchored arrow lands a column away from the word it sorts. */
.bk-th { cursor: pointer; user-select: none; }
.bk-th .bk-th-lbl { display: inline-flex; align-items: center; gap: 4px; cursor: pointer; }
.bk-th .bk-th-lbl:focus-visible { outline: none; box-shadow: var(--ring); border-radius: 5px; }
.bk-th:hover { color: var(--ink-2); }
/* Idle arrow is empty, so reserve its width: without this the header text shifts
   sideways every time the active column changes. */
.bk-th .bk-arrow { display: inline-block; min-width: 9px; opacity: .55; font-weight: 700; }
.bk-th.sorted { color: var(--accent-ink); }
.bk-th.sorted .bk-arrow { opacity: 1; color: var(--accent-ink); }

/* Roles & Access: capability picker grouped by sidebar page. Actions sit
   indented under the page they belong to, with a rule down the left so the
   nesting is readable at a glance rather than inferred from padding. */
.caprow-page { font-weight: 600; }
.caprow-nopage { color: var(--ink-3); font-weight: 600; padding-left: 24px; }
.caprow-actions { margin: 2px 0 6px 26px; padding-left: 12px;
  border-left: 2px solid var(--line); }
.caprow-action { font-weight: 400; font-size: 12.5px; color: var(--ink-2); }
.rolecard-new { display: flex; flex-direction: column; align-items: flex-start;
  justify-content: center; border-style: dashed; }
.rolecard-actions .link.del { color: var(--warn); margin-left: 10px; }
/* Destructive confirm. Uses the same --warn the inline "Delete" links use, so
   a dangerous action looks the same wherever it appears. */
/* Geometry comes from the primary rule above (same padding, radius and
   weight as Cancel) -- this only changes the colour. */
.modalbtns button.danger { background: var(--neg); border-color: var(--neg); color: #fff; }
.modalbtns button.danger:hover:not(:disabled) { background: var(--neg-ink); border-color: var(--neg-ink);
  filter: none; box-shadow: 0 3px 10px -2px rgba(192,57,43,.4); }
.modalbtns button.danger:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(192,57,43,.25); }
/* Disabled is the DEFAULT state of a delete confirm (it unlocks only once the
   name matches), so it has to look deliberately inert rather than like a
   broken red button. */
.modalbtns button.danger:disabled { background: var(--surface-2); border-color: var(--line);
  color: var(--ink-3); cursor: not-allowed; opacity: 1; }
.danger-note { background: var(--neg-weak); border: 1px solid var(--neg-line);
  color: var(--neg-ink); border-radius: 9px; padding: 9px 11px; font-size: 12px;
  line-height: 1.45; margin: 0 0 14px; }

/* Staker book: the full stake account. Monospace so base58 look-alikes (0/O,
   1/l/I) are tellable apart -- the address is shown in full precisely so it can
   be checked character by character, which a proportional face defeats. */
.bk-acctcell { white-space: nowrap; }
.bk-acct { font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 12px; color: var(--ink-2); letter-spacing: -.1px; }
.bk-acctcell .copy-mini { margin-left: 4px; vertical-align: middle; }

/* Add-address failure line. Empty by default, so it takes no space until there
   is something to say. */
.addr-err { margin: 6px 0 0; min-height: 0; }
.addr-err:empty { display: none; }

/* Click-to-rename on the client header. The name is NOT a permanent input --
   it reads as a heading until hovered, so the card stays a record rather than
   a form. A dotted underline on hover is the affordance; a pencil icon beside
   a 20px heading was the unreadable smudge the Staker book already had. */
.client-head .nm-text { cursor: text; border-radius: 4px; padding: 0 2px; margin: 0 -2px; }
.client-head .nm-text:hover { background: var(--surface-2);
  box-shadow: inset 0 -1px 0 0 var(--ink-3); }
.nm-edit { font-size: 17px; font-weight: 700; padding: 3px 8px; border: 1px solid var(--accent);
  border-radius: 8px; background: var(--surface); color: var(--ink); width: 320px; max-width: 60vw; }
.nm-edit:focus { outline: none; box-shadow: var(--ring); }
.nm-save, .nm-cancel { margin-left: 6px; vertical-align: middle; }
.nm-err { margin-left: 8px; font-size: 12px; color: var(--warn); }
.bk-cancel { background: var(--surface-2); color: var(--ink-2); border: 1px solid var(--line); }
.bk-cancel:hover { border-color: var(--ink-3); }
.bk-edit-err { margin-left: 8px; }
.badge.muted { background: var(--surface-2); color: var(--ink-3); }
/* Role pill (e.g. "admin") — a soft brand-purple tint with a tiny gradient dot,
   sized to sit cleanly beside the neutral .badge instead of a hard filled box. */
.role-badge { display: inline-flex; align-items: center; gap: 5px; font-size: 11px;
  padding: 2px 9px 2px 7px; border-radius: 20px; font-weight: 600; letter-spacing: .01em;
  background: rgba(153,69,255,.12); color: #7d3ff0;
  border: 1px solid rgba(153,69,255,.22); text-transform: capitalize; }
.role-badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: var(--brand-grad); flex: none; }
:root[data-theme="dark"] .role-badge,
:root:not([data-theme="light"]) .role-badge {
  background: rgba(153,69,255,.20); color: #c9a8ff; border-color: rgba(153,69,255,.34); }

/* notifications bell */
.notif-wrap { position: relative; display: inline-block; }
.notif-btn { background: none; border: 0; font-size: 17px; cursor: pointer; padding: 6px 8px;
  border-radius: 8px; line-height: 1; position: relative; filter: grayscale(.2); }
.notif-btn:hover { background: var(--bg); }
.notif-badge { position: absolute; top: 0; right: 0; min-width: 16px; height: 16px;
  padding: 0 4px; background: var(--brand-grad); color: #fff; font-size: 10px; font-weight: 700;
  border-radius: 9px; display: flex; align-items: center; justify-content: center; }
.notif-menu { position: absolute; right: 0; top: calc(100% + 8px); width: 320px; max-height: 420px;
  overflow: auto; background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 8px 30px rgba(0,0,0,.2); padding: 6px; z-index: 55; display: none; }
.notif-menu.open { display: block; }
.notif-head { display: flex; justify-content: space-between; align-items: center; padding: 8px 10px;
  border-bottom: 1px solid var(--line); margin-bottom: 4px; font-weight: 700; font-size: 13px; }
.notif-head .link { font-size: 12px; }
.notif-item { display: flex; gap: 10px; padding: 10px; border-radius: 8px; }
.notif-item.unread { background: var(--accent-weak); }
.notif-item .ni-ico { font-size: 15px; }
.ni-t { font-size: 13px; font-weight: 600; color: var(--ink); }
.ni-b { font-size: 12px; color: var(--ink-2); margin-top: 1px; }
.ni-when { font-size: 11px; color: var(--ink-3); margin-top: 2px; }
.notif-empty { padding: 24px 10px; text-align: center; color: var(--ink-3); font-size: 13px; }

/* language globe (next to the notification bell) */
.lang-wrap { position: relative; display: inline-block; }
.lang-globe { display: inline-flex; align-items: center; gap: 4px; background: none; border: 0;
  font-size: 16px; cursor: pointer; padding: 6px 8px; border-radius: 8px; line-height: 1; }
.lang-globe:hover { background: var(--bg); }
.lang-globe .lang-cur { font-size: 11px; font-weight: 700; color: var(--ink-2); }
.lang-menu { position: absolute; right: 0; top: calc(100% + 8px); width: 190px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 8px 30px rgba(0,0,0,.2); padding: 6px; z-index: 55; display: none; }
.lang-menu.open { display: block; }
.lang-item { display: flex; align-items: center; gap: 9px; width: 100%; text-align: left;
  background: none; border: 0; padding: 9px 10px; border-radius: 8px; cursor: pointer;
  font-size: 13.5px; color: var(--ink); }
.lang-item:hover { background: var(--bg); }
.lang-item.on { color: var(--accent-ink); font-weight: 600; }
.lang-item .lang-tag { display: inline-flex; align-items: center; justify-content: center;
  min-width: 26px; height: 22px; border-radius: 6px; background: var(--bg); border: 1px solid var(--line);
  font-size: 12px; font-weight: 700; }
.lang-item.on .lang-tag { background: var(--accent-weak); border-color: var(--accent); }
.lang-item .lang-check { margin-left: auto; color: var(--accent-ink); }
/* governing-language footnote under the language list */
.lang-note { margin: 4px 6px 2px; padding: 8px 4px 2px; border-top: 1px solid var(--line-2);
  font-size: 11px; line-height: 1.45; color: var(--ink-3); }

/* validator health chips (ValidBlocks) */
.health-strip { display: flex; flex-wrap: wrap; gap: 10px; margin: 14px 0 4px; }
.hchip { display: flex; flex-direction: column; gap: 3px; min-width: 100px;
  padding: 11px 15px; border: 1px solid var(--line); border-radius: 12px; background: var(--surface-2);
  box-shadow: var(--shadow); transition: transform .15s ease, box-shadow .15s ease; }
.hchip:hover { transform: translateY(-1px); box-shadow: var(--shadow-lg); }
.hchip .hk { font-size: 11px; text-transform: uppercase; letter-spacing: .03em; color: var(--ink-3); font-weight: 600; }
.hchip .hv { font-size: 15px; font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; }
.hchip.accent { border-color: var(--accent); background: var(--accent-weak); }
.hchip.accent .hv { color: var(--accent-ink); }
.hchip.ok .hv { color: var(--pos); }
.hchip.warn .hv { color: var(--warn); }
/* vs-network comparison rows on the performance page */
.cmp-row { display: grid; grid-template-columns: 1fr auto auto; gap: 10px 18px; align-items: center;
  padding: 12px 0; border-bottom: 1px solid var(--line); }
.cmp-row:last-child { border-bottom: 0; }
.cmp-row .cmp-label { font-size: 13.5px; color: var(--ink-2); }
.cmp-row .cmp-us { font-size: 16px; font-weight: 700; color: var(--accent-ink); font-variant-numeric: tabular-nums; text-align: right; }
.cmp-row .cmp-net { font-size: 13px; color: var(--ink-3); font-variant-numeric: tabular-nums; text-align: right; min-width: 120px; }
.cmp-head { display: grid; grid-template-columns: 1fr auto auto; gap: 10px 18px;
  font-size: 11px; text-transform: uppercase; letter-spacing: .03em; color: var(--ink-3); font-weight: 700; padding-bottom: 4px; }
.cmp-head span:not(:first-child) { text-align: right; }
.cmp-head span:last-child { min-width: 120px; }
.pool-row { display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid var(--line); font-size: 14px; }
.pool-row:last-child { border-bottom: 0; }

/* charts 2-per-row on desktop, 1-per-row on narrow screens. `stretch` makes
   both panels in a row the SAME height (they were staggering before). The
   bottom margin matches .panel's 22px so the grid is separated from whatever
   panel follows it (it was touching the next full-width panel). */
.chart-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px;
  align-items: stretch; margin-bottom: 22px; }
.chart-grid > .panel { margin-bottom: 0; display: flex; flex-direction: column; }
.chart-grid > .panel .chart { margin-top: auto; }   /* pin chart to bottom so titles align across a row */
@media (max-width: 900px) { .chart-grid { grid-template-columns: 1fr; gap: 0; } .chart-grid > .panel { margin-bottom: 20px; } }

/* "Us vs the network": chart on the left, comparison table on the right */
.cmp-split { display: grid; grid-template-columns: 1.05fr 1fr; gap: 26px; align-items: start; }
@media (max-width: 820px) { .cmp-split { grid-template-columns: 1fr; gap: 16px; } }

/* account menu (top-right avatar + dropdown) */
.acct { position: relative; display: inline-flex; align-items: center; gap: 4px; }
/* Dual-hat view switch inside the account dropdown (admin + staking client) */
.acct-viewas { padding: 10px 14px 4px; }
.acct-viewas-lbl { font-size: 10.5px; color: var(--ink-3); text-transform: uppercase;
  letter-spacing: .07em; font-weight: 700; margin-bottom: 6px; }
.acct-viewas-seg { display: flex; gap: 4px; background: var(--bg); border: 1px solid var(--line);
  border-radius: 9px; padding: 3px; }
.acct-viewas-seg a { flex: 1; text-align: center; font-size: 13px; font-weight: 600;
  color: var(--ink-3); text-decoration: none; padding: 6px 8px; border-radius: 6px; }
.acct-viewas-seg a:hover { color: var(--ink); }
.acct-viewas-seg a.on { color: var(--accent-ink); background: var(--surface); box-shadow: 0 1px 2px rgba(0,0,0,.12); }
.acct-btn { display: flex; align-items: center; gap: 8px; background: none; border: 0;
  padding: 4px 6px 4px 4px; border-radius: 24px; cursor: pointer; }
.acct-btn:hover { background: var(--bg); }
.avatar { width: 34px; height: 34px; border-radius: 50%; flex: none;
  background: var(--brand-grad); color: #fff; font-weight: 700; font-size: 14px;
  display: flex; align-items: center; justify-content: center; overflow: hidden;
  border: 1px solid var(--line); }
.avatar img { width: 100%; height: 100%; object-fit: cover; }
.acct-btn .caret { color: var(--ink-3); font-size: 11px; }
.acct-name { font-size: 13.5px; color: var(--ink); font-weight: 600; max-width: 140px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.acct-menu { position: absolute; right: 0; top: calc(100% + 8px); width: 250px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 8px 30px rgba(0,0,0,.18); padding: 8px; z-index: 50; display: none; }
.acct-menu.open { display: block; }
.acct-head { display: flex; align-items: center; gap: 10px; padding: 8px 8px 12px;
  border-bottom: 1px solid var(--line); margin-bottom: 6px; }
.acct-head .avatar { width: 40px; height: 40px; }
.acct-head .info { min-width: 0; }
.acct-head .n { font-weight: 700; font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.acct-head .e { font-size: 12px; color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.acct-head .role { font-size: 11px; color: var(--accent-ink); font-weight: 600; text-transform: uppercase; letter-spacing: .04em; }
.acct-item { display: flex; align-items: center; gap: 10px; padding: 9px 10px;
  border-radius: 8px; color: var(--ink-2); font-size: 14px; cursor: pointer; text-decoration: none;
  border: 0; background: none; width: 100%; text-align: left; }
.acct-item:hover { background: var(--bg); color: var(--ink); }
.acct-item .ico { width: 16px; text-align: center; opacity: .85; }
.acct-menu .divider { height: 1px; background: var(--line); margin: 6px 4px; }
.acct-menu .theme-row { display: flex; align-items: center; justify-content: space-between; padding: 8px 10px; font-size: 13px; color: var(--ink-2); }

/* theme toggle (segmented) */
.theme-toggle { display: inline-flex; gap: 2px; padding: 3px; border-radius: 9px;
  background: var(--bg); border: 1px solid var(--line); }
.theme-btn { background: none; color: var(--ink-3); padding: 4px 9px; font-size: 13px;
  border-radius: 6px; line-height: 1; }
.theme-btn:hover { color: var(--ink); filter: none; background: none; }
.theme-btn.on { background: var(--surface); color: var(--accent-ink); box-shadow: var(--shadow); }

/* theme dropdown (Light / System / Dark) — mirrors the language 🌐 switcher */
.theme-wrap { position: relative; display: inline-block; }
.theme-globe { display: inline-flex; align-items: center; justify-content: center; background: none;
  border: 0; font-size: 16px; cursor: pointer; padding: 6px 8px; border-radius: 8px; line-height: 1;
  color: var(--ink-2); }
.theme-globe:hover { background: var(--bg); color: var(--ink); }
.theme-menu { position: absolute; right: 0; top: calc(100% + 8px); width: 170px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 8px 30px rgba(0,0,0,.2); padding: 6px; z-index: 55; display: none; }
.theme-menu.open { display: block; }
.theme-item { display: flex; align-items: center; gap: 9px; width: 100%; text-align: left;
  background: none; border: 0; padding: 9px 10px; border-radius: 8px; cursor: pointer;
  font-size: 13.5px; color: var(--ink); }
.theme-item:hover { background: var(--bg); }
.theme-item.on { color: var(--accent-ink); font-weight: 600; }
.theme-item .theme-tag { display: inline-flex; align-items: center; justify-content: center;
  min-width: 26px; height: 22px; border-radius: 6px; background: var(--bg); border: 1px solid var(--line);
  font-size: 13px; }
.theme-item.on .theme-tag { background: var(--accent-weak); border-color: var(--accent); }
.theme-item .theme-check { margin-left: auto; color: var(--accent-ink); }

/* language switcher (EN / 繁 / 简) — same pill style as the theme toggle */
.lang-toggle { display: inline-flex; gap: 2px; padding: 3px; border-radius: 9px;
  background: var(--bg); border: 1px solid var(--line); }
.lang-btn { background: none; color: var(--ink-3); padding: 4px 9px; font-size: 13px;
  border-radius: 6px; line-height: 1; font-weight: 600; }
.lang-btn:hover { color: var(--ink); filter: none; background: none; }
.lang-btn.on { background: var(--surface); color: var(--accent-ink); box-shadow: var(--shadow); }
/* login/simple pages: a small inline switcher pinned top-right */
.lang-corner { position: fixed; top: 16px; right: 18px; z-index: 20; }

/* on-chain us-vs-cluster comparison bars (Performance page) */
.oc-head { display: flex; align-items: center; gap: 10px; }
.oc-badge { display: inline-flex; align-items: center; gap: 6px; font-size: 11px;
  font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--accent-ink);
  background: var(--accent-weak); border: 1px solid var(--accent-weak);
  padding: 3px 9px; border-radius: 999px; cursor: default; }
.oc-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--accent);
  box-shadow: 0 0 0 3px rgba(20,184,154,.18); }

/* quarterly-statement quarter picker (dropdown off the "Quarterly PDF" button) */
.qpick-wrap { position: relative; display: inline-block; }
.qpick-caret { margin-left: 6px; font-size: 10px; opacity: .8; }
.qpick-menu { position: absolute; right: 0; top: calc(100% + 6px); min-width: 220px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 8px 30px rgba(0,0,0,.2); padding: 6px; z-index: 55; display: none; }
.qpick-menu.open { display: block; }
.qpick-item { display: flex; align-items: center; justify-content: space-between; gap: 12px;
  width: 100%; text-align: left; background: none; border: 0; padding: 9px 11px;
  border-radius: 8px; cursor: pointer; font-size: 13px; color: var(--ink); }
.qpick-item:hover { background: var(--bg); }
.qpick-lbl { font-weight: 600; }
.qpick-latest { font-size: 10.5px; font-weight: 700; color: var(--accent-ink);
  background: var(--accent-weak); border-radius: 999px; padding: 1px 7px; margin-left: 6px; }
.qpick-meta { font-size: 11.5px; color: var(--ink-3); font-variant-numeric: tabular-nums; white-space: nowrap; }
.qpick-loading, .qpick-empty { padding: 12px; font-size: 12.5px; color: var(--ink-3); }
.qpick-group { padding: 8px 11px 4px; font-size: 10.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .05em; color: var(--ink-3); }
.qpick-sub { padding-left: 18px; }
.qpick-sep { height: 1px; background: var(--line); margin: 6px 4px; }
.qpick-menu { min-width: 260px; }

/* validator revenue decomposition (Trillium panel) */
.apystrip { display: flex; flex-wrap: wrap; gap: 10px; }
.apybox { flex: 1 1 168px; background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 10px; padding: 12px 14px; }
.apybox .k { font-size: 11px; font-weight: 640; text-transform: uppercase;
  letter-spacing: .06em; color: var(--ink-3); margin-bottom: 5px; }
.apybox .v { font-size: 23px; font-weight: 620; letter-spacing: -.02em;
  font-variant-numeric: tabular-nums; line-height: 1.1; }
.apybox .f { font-size: 12px; color: var(--ink-3); margin-top: 3px; }
.rev-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 13.5px;
  font-variant-numeric: tabular-nums; }
.rev-table th, .rev-table td { padding: 10px 12px; text-align: right; white-space: nowrap;
  border-bottom: 1px solid var(--line-2); }
.rev-table th:first-child, .rev-table td:first-child { text-align: left; }
.rev-table thead th { background: var(--surface-2); color: var(--ink-3); font-size: 11px;
  text-transform: uppercase; letter-spacing: .04em; font-weight: 700;
  border-bottom: 1px solid var(--line); }
.rev-table td.sep, .rev-table th.sep { border-left: 1px solid var(--line); }
.rev-table tr.rev-total td { font-weight: 700; background: var(--surface-2);
  border-top: 1px solid var(--line); }
.rev-table .muted { color: var(--ink-3); }
.rev-table .neg { color: var(--warn); }

/* B10. The table was ~1,400px in a ~1,000px column, so 400px of it -- Gross
   revenue, Vote cost, Net revenue and USD -- sat behind a horizontal scroll,
   including the number the page exists to report.

   Net revenue and USD were pinned to the right edge to keep them in view.
   That is no longer needed, and the pinning cost more than it bought: two
   frozen columns in a table this narrow read as a stuck panel rather than
   part of the row. Dropping "(after vote cost)" and "(at today's price)"
   from the headers took the widest column from 216px to 80px, and the whole
   table now fits with no overflow at all in SOL (and 96px in USD), so those
   two columns simply scroll with everything else.

   The month/epoch column STAYS pinned. It is the row label -- in USD mode
   there is still a little horizontal scroll, and a figure with no visible
   month beside it is unreadable. One pinned column does not read as a panel
   the way three did. */
.rev-table th:first-child,
.rev-table td:first-child { position: sticky; left: 0; z-index: 2; background: var(--surface); }
/* header cells are already sticky top: keep the corner above the pinned body */
.rev-table thead th:first-child { z-index: 6; background: var(--surface-2); }
/* total / group rows carry their own background -- restate it on the pinned
   cell or the generic --surface above would override the row's emphasis. */
.rev-table tr.rev-total td:first-child,
.rev-table tr.rev-tot td:first-child,
.rev-table tr.rev-grp-row td:first-child { background: var(--surface-2); }
/* Narrow screens: a pinned label column leaves too little room for the data
   on a phone, so drop back to a plain scroll. */
@media (max-width: 760px) {
  .rev-table th:first-child, .rev-table td:first-child { position: static; }
}
.oc-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 18px; margin-top: 16px; }
.oc-card { border: 1px solid var(--line); border-radius: 12px; padding: 16px 18px;
  background: var(--surface-2); }
.oc-k { font-size: 12px; color: var(--ink-3); text-transform: uppercase;
  letter-spacing: .04em; font-weight: 600; }
.oc-v { font-size: 28px; font-weight: 800; line-height: 1.05; margin: 8px 0 2px;
  letter-spacing: -0.02em; font-variant-numeric: tabular-nums; color: var(--ink); }
.oc-v.good { color: var(--accent-ink); }
.oc-v.warn { color: var(--warn); }
.oc-sub { font-size: 12px; color: var(--ink-3); margin-bottom: 12px; }
/* the mini comparison bar: ours (accent) over cluster (muted) baseline */
.oc-bars { display: flex; flex-direction: column; gap: 8px; }
.oc-bar { display: grid; grid-template-columns: 42px 1fr auto; align-items: center; gap: 8px; }
.oc-bar .bl { font-size: 11px; color: var(--ink-3); font-weight: 600; }
.oc-track { display: block; height: 8px; border-radius: 5px; background: var(--bg); overflow: hidden; }
/* MUST be block: an inline <span> ignores width, so every one of these bars
   computed to zero and the whole comparison rendered as empty tracks. */
.oc-fill { display: block; height: 100%; border-radius: 5px; transition: width .5s ease; }
.oc-fill.us { background: var(--brand-grad); }
.oc-fill.net { background: var(--ink-3); opacity: .55; }
.oc-bar .bv { font-size: 11.5px; font-weight: 700; color: var(--ink-2);
  font-variant-numeric: tabular-nums; min-width: 46px; text-align: right; }
.oc-note { font-size: 11.5px; color: var(--ink-3); margin-top: 10px; }
.oc-win { color: var(--pos); font-weight: 700; }
/* when the ✓ badge should sit on its own line above the explanation text */
.oc-win-block { display: block; margin-bottom: 2px; }
@media (max-width: 900px) { .oc-grid { grid-template-columns: 1fr; } }

/* admin: per-client rebate setter */
.rebate-set { display: flex; align-items: center; gap: 8px; margin-top: 10px;
  padding-top: 12px; border-top: 1px solid var(--line-2); flex-wrap: wrap; }
.rs-label { font-size: 12.5px; color: var(--ink-2); font-weight: 600; }
.rs-input { width: 70px; padding: 6px 8px; font-size: 13px; border: 1px solid var(--line);
  border-radius: 8px; background: var(--surface-2); color: var(--ink); text-align: right; }
.rs-suffix { font-size: 13px; color: var(--ink-3); margin-left: -4px; }
.rs-hint { font-size: 11.5px; color: var(--ink-3); }
/* ---- admin clients: data table + master-detail ---- */
.client-search { width: 100%; margin-top: 14px; font: inherit; font-size: 14px; color: var(--ink);
  background: var(--surface-2); border: 1px solid var(--line); border-radius: 10px; padding: 10px 13px;
  box-sizing: border-box; }
.client-table { width: 100%; font-size: 13.5px; }
.client-table thead th { font-size: 11px; font-weight: 660; text-transform: uppercase; letter-spacing: .03em;
  color: var(--ink-3); white-space: nowrap; }
.client-table td { white-space: nowrap; }
.client-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.client-trow { cursor: pointer; transition: background .12s ease; }
.client-trow:hover td { background: var(--bg); }
.ct-name .cr-name { font-weight: 600; }
.ct-name .cr-user { font-size: 12px; color: var(--ink-3); margin-left: 8px; }
.ct-email { color: var(--ink-2); }
.ct-date { color: var(--ink-2); font-variant-numeric: tabular-nums; }
.ct-open { text-align: right; width: 24px; }
.copy-mini { border: 0; background: transparent; color: var(--ink-3); cursor: pointer; font-size: 12px;
  padding: 0 4px; border-radius: 5px; }
.copy-mini:hover { color: var(--ink); background: var(--line); }
.cr-name { font-weight: 600; font-size: 14.5px; }
.cr-user { font-size: 12.5px; color: var(--ink-3); }
.cr-status { display: inline-block; font-size: 11px; font-weight: 640; text-transform: uppercase; letter-spacing: .04em;
  padding: 2px 9px; border-radius: 999px; }
.cr-status.ok { color: var(--pos); background: color-mix(in srgb, var(--pos) 13%, transparent); }
.cr-status.warn { color: var(--warn); background: color-mix(in srgb, var(--warn) 14%, transparent); }
.cr-chevron { color: var(--ink-3); font-size: 18px; line-height: 1; }
.client-back { display: inline-block; margin-bottom: 14px; }

/* client detail: account meta + team (read-only) */
.meta-h { font-size: 11.5px; font-weight: 660; text-transform: uppercase; letter-spacing: .05em;
  color: var(--ink-3); margin: 0 0 12px; }
.meta-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px 22px; }
.meta-kv { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.meta-k { font-size: 11px; color: var(--ink-3); text-transform: uppercase; letter-spacing: .03em; }
.meta-v { font-size: 13.5px; color: var(--ink); word-break: break-word; }
.team-list { display: flex; flex-direction: column; gap: 8px; }
.team-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 10px 12px;
  border: 1px solid var(--line); border-radius: 9px; background: var(--surface-2); }
.tm-name { font-weight: 560; font-size: 13.5px; }
.tm-user { font-size: 12px; color: var(--ink-3); }
.tm-flags { margin-left: auto; display: flex; gap: 8px; align-items: center; }
.team-badge { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em;
  color: var(--accent-ink); background: color-mix(in srgb, var(--accent) 14%, transparent);
  border-radius: 5px; padding: 1px 7px; }
.team-adminrow { display: flex; align-items: center; justify-content: space-between; gap: 12px;
  flex-wrap: wrap; padding: 12px 14px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--surface-2); }
.ta-title { font-weight: 600; font-size: 13.5px; }
.team-admin-select { font: inherit; font-size: 13.5px; color: var(--ink); background: var(--surface);
  border: 1px solid var(--line); border-radius: 9px; padding: 8px 30px 8px 11px; cursor: pointer;
  -webkit-appearance: none; appearance: none; max-width: 240px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23828b99' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 10px center; }
.team-admin-select:hover { border-color: var(--ink-3); }
.invite-row { opacity: .9; }
.team-invite-link { margin-top: 12px; padding: 12px 14px; border: 1px solid var(--line);
  border-left: 3px solid var(--accent); border-radius: 10px; background: var(--surface-2); }
.til-note { font-size: 12.5px; color: var(--ink-2); margin-bottom: 8px; line-height: 1.5; }
.til-row { display: flex; gap: 8px; align-items: center; }
.til-row input { flex: 1; min-width: 0; font: inherit; font-size: 12.5px; color: var(--ink);
  background: var(--surface); border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px;
  font-family: ui-monospace, Menlo, monospace; }
.team-add { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; align-items: center; }
.team-add input { font: inherit; font-size: 13.5px; color: var(--ink); background: var(--surface-2);
  border: 1px solid var(--line); border-radius: 9px; padding: 9px 11px; box-sizing: border-box; }
.team-add input:hover { border-color: var(--ink-3); }

/* ---- admin guide (how-to) ---- */
.guide-step { display: flex; gap: 14px; padding: 14px 0; border-top: 1px solid var(--line-2); }
.guide-step:first-of-type { border-top: 0; padding-top: 4px; }
.guide-num { flex: none; width: 26px; height: 26px; border-radius: 50%; display: flex;
  align-items: center; justify-content: center; font-size: 13px; font-weight: 700;
  color: var(--accent-ink); background: color-mix(in srgb, var(--accent) 15%, transparent); }
.guide-step h3 { font-size: 14.5px; font-weight: 620; margin: 2px 0 4px; }
.guide-step .sub { margin: 0; }
.guide-note { margin-top: 16px; padding: 12px 14px; border-radius: 10px; font-size: 13px;
  color: var(--ink-2); background: var(--surface-2); border-left: 3px solid var(--accent); }

.rebate-block { margin-top: 12px; padding: 12px 14px; border: 1px solid var(--line);
  border-radius: 10px; background: var(--surface-2); }
.rebate-block .rebate-set { margin-top: 8px; }
.rebate-block .rebate-set:first-of-type { margin-top: 4px; }
.rb-title { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  color: var(--ink-3); margin-bottom: 2px; }
.rebate-block .rs-label { min-width: 150px; }
.rb-readonly { opacity: .8; }
.rs-ro { font-size: 13px; font-weight: 700; color: var(--ink-2); min-width: 48px;
  font-variant-numeric: tabular-nums; }
.rs-eff { font-size: 12px; color: var(--ink-3); margin-left: 4px; }
.rs-eff b { color: var(--accent-ink); font-variant-numeric: tabular-nums; }
/* read-only commission summary (per client) + Edit button */
.cs-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
.cs-row { display: grid; grid-template-columns: 150px 64px 1fr auto; align-items: baseline;
  gap: 8px; padding: 5px 0; border-top: 1px solid var(--line); font-size: 13px; }
.cs-row:first-of-type { border-top: 0; }
.cs-label { color: var(--ink-2); font-weight: 600; }
.cs-charge { font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; text-align: right; }
.cs-of { color: var(--ink-3); font-size: 12px; }
.cs-reb { color: var(--pos); font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums;
  white-space: nowrap; }
/* commission edit modal fields */
.cm-grid { display: flex; flex-direction: column; gap: 4px; margin: 12px 0 4px; }
.cm-field { display: grid; grid-template-columns: 1fr 120px auto; align-items: center; gap: 10px;
  padding: 8px 0; border-top: 1px solid var(--line); }
.cm-field:first-child { border-top: 0; }
.cm-label { font-size: 13.5px; font-weight: 600; color: var(--ink); display: flex; flex-direction: column; }
.cm-label small { font-weight: 400; color: var(--ink-3); font-size: 11.5px; }
.cm-inwrap { display: inline-flex; align-items: center; gap: 4px; }
.cm-inwrap .rs-input { width: 88px; }
.cm-eff { font-size: 12px; color: var(--pos); font-weight: 600; font-variant-numeric: tabular-nums;
  white-space: nowrap; text-align: right; min-width: 84px; }
.cm-err { margin-top: 8px; }
/* collapsible "advanced" priority & base rebate rows (hidden by default; only
   shown for the rare client with a priority/base contract term). */
.rebate-adv { margin-top: 8px; border-top: 1px dashed var(--line); padding-top: 6px; }
.rebate-adv > summary { font-size: 12px; color: var(--ink-3); cursor: pointer;
  list-style: none; padding: 4px 0; user-select: none; }
.rebate-adv > summary::before { content: "▸ "; color: var(--ink-3); }
.rebate-adv[open] > summary::before { content: "▾ "; }
.rebate-adv > summary:hover { color: var(--ink); }
/* admin: rebate request rows */
.rebate-req { display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 12px 14px; border: 1px solid var(--line); border-radius: 12px; margin-bottom: 10px;
  background: var(--surface-2); }
.rr-who { font-size: 14px; font-weight: 700; color: var(--ink); }
.rr-u { font-size: 12px; color: var(--ink-3); font-weight: 500; }
.rr-detail { font-size: 12.5px; color: var(--ink-2); margin-top: 2px; font-variant-numeric: tabular-nums; }
.rr-note { font-size: 12px; color: var(--ink-3); margin-top: 4px; font-style: italic; }
.rr-actions { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }

/* rebate panel (My rewards) */
.rebate-panel { position: relative; overflow: hidden;
  background: radial-gradient(600px 240px at 100% -20%, rgba(153,69,255,.07), transparent 60%),
    radial-gradient(500px 240px at 0% 120%, rgba(20,200,168,.09), transparent 58%), var(--surface); }
.rb-head { display: flex; align-items: center; gap: 12px; }
/* statement period the rebate figures cover (e.g. "For August 2026") */
.rb-period { margin: 6px 0 0; font-size: 12.5px; font-weight: 600; color: var(--ink-2);
  text-transform: uppercase; letter-spacing: .03em; }
.rb-badge { font-size: 12px; font-weight: 700; color: var(--accent-ink);
  background: var(--accent-weak); border-radius: 999px; padding: 4px 12px; white-space: nowrap; }
.rb-calc-link { margin-left: auto; background: none; border: 0; color: var(--accent-ink);
  font-size: 12.5px; font-weight: 600; cursor: pointer; text-decoration: underline;
  text-underline-offset: 2px; padding: 4px 6px; }
.rb-calc-link:hover { color: var(--ink); }

/* rebate calculation modal (Excel-style breakdown) */
.rbc-overlay { position: fixed; inset: 0; background: rgba(10,14,20,.5); z-index: 60;
  display: flex; align-items: center; justify-content: center; padding: 20px; }
.rbc-modal { width: 100%; max-width: 620px; max-height: 88vh; overflow: auto; }
.rbc-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.rbc-head h2 { margin: 0; font-size: 19px; }
.rbc-x { background: none; border: 0; font-size: 18px; color: var(--ink-3); cursor: pointer;
  line-height: 1; padding: 4px 8px; border-radius: 6px; }
.rbc-x:hover { background: var(--bg); color: var(--ink); }
/* stacked step list — each step: label + amount on top, formula wrapping beneath.
   No horizontal table, so nothing clips on a narrow modal. */
.rbc-steps { margin: 14px 0 6px; }
.rbc-step { padding: 11px 0; border-bottom: 1px solid var(--line-2); }
.rbc-step:first-child { padding-top: 4px; }
.rbc-step-top { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.rbc-step-label { font-size: 13.5px; font-weight: 600; color: var(--ink); }
.rbc-step-amt { font-size: 14px; font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums;
  white-space: nowrap; text-align: right; }
.rbc-step-formula { margin-top: 5px; }
.rbc-step-formula code { font-family: ui-monospace, Menlo, monospace; font-size: 11.5px;
  color: var(--ink-3); background: var(--bg); padding: 2px 7px; border-radius: 5px;
  display: inline-block; white-space: normal; line-height: 1.5; }
/* the final "rebate payable" row: emphasised, its own separator */
.rbc-step-total { margin-top: 4px; border-top: 2px solid var(--line); border-bottom: 0; padding-top: 13px; }
.rbc-step-total .rbc-step-label { font-weight: 700; }
.rbc-step-total .rbc-step-amt { color: var(--accent-ink); font-size: 17px; }
.rbc-eff { margin: 8px 0; padding: 10px 12px; background: var(--accent-weak); border-radius: 9px;
  font-size: 12.5px; color: var(--ink-2); }
.rbc-eff b { color: var(--accent-ink); }
.rbc-note { font-size: 11.5px; margin-top: 10px; }
.rbc-foot { display: flex; justify-content: flex-end; margin-top: 14px; }
.rb-calc { margin: 16px 0 4px; border: 1px solid var(--line); border-radius: 12px; overflow: hidden; }
.rb-row { display: flex; align-items: baseline; justify-content: space-between;
  padding: 12px 16px; font-size: 14px; color: var(--ink-2); border-bottom: 1px solid var(--line-2); }
.rb-row b { color: var(--ink); font-variant-numeric: tabular-nums; font-weight: 700; }
.rb-row.rb-total { border-bottom: 0; background: var(--bg); }
.rb-row.rb-total span { color: var(--ink); font-weight: 600; }
.rb-row.rb-total b { font-size: 20px; color: var(--accent-ink); }
.rb-usd { font-size: 12.5px; color: var(--ink-3); font-weight: 500; margin-left: 4px; }
.rb-est { display: inline-block; font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em; color: var(--ink-3); background: var(--bg);
  border: 1px solid var(--line); border-radius: 5px; padding: 1px 5px; margin-left: 6px;
  vertical-align: 1px; }
.rb-effective { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  margin-top: 14px; padding: 12px 16px; border-radius: 12px;
  background: var(--accent-weak); border: 1px solid var(--accent-weak); }
.rb-eff-k { font-size: 13px; font-weight: 600; color: var(--ink-2); }
.rb-eff-v { font-size: 22px; font-weight: 800; color: var(--accent-ink);
  font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
.rb-eff-note { font-size: 12px; color: var(--ink-3); }
.rb-actions { margin-top: 16px; }
.rb-note { font-size: 11.5px; color: var(--ink-3); margin-top: 12px; }
.rb-confirm { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.rb-confirm-q { font-size: 13px; color: var(--ink-2); }

/* brand gradient accents (#8) */
.tile.accent { position: relative; overflow: hidden; }
.tile.accent::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0;
  width: 4px; background: var(--brand-grad); }
.brand .dot { background: var(--brand-grad); }
.grad-text { background: var(--brand-grad); -webkit-background-clip: text;
  background-clip: text; color: transparent; }

/* SOL price badge + currency toggle (top bar right) */
/* The SOL price is live market data, not page chrome, so it gets the brand
   accent and a pill rather than sitting in the same grey as everything else in
   the header. Shared by the client and admin shells. */
.price-badge { font-size: 13px; color: var(--ink-2); font-variant-numeric: tabular-nums;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 11px; border-radius: 999px;
  /* colour-mix off --accent-ink so the pill tracks the theme's own accent (teal
     in light, brighter teal in dark) instead of hard-coding a second palette. */
  background: color-mix(in srgb, var(--accent-ink) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent-ink) 26%, transparent); }
.price-badge b { color: var(--accent-ink); font-weight: 680; }
.cur-toggle { display: inline-flex; gap: 2px; padding: 3px; border-radius: 8px;
  background: var(--bg); border: 1px solid var(--line); }
.cur-btn { background: none; color: var(--ink-3); padding: 4px 10px; font-size: 12.5px;
  font-weight: 600; border: 0; border-radius: 6px; cursor: pointer; }
.cur-btn.on { background: var(--surface); color: var(--accent-ink); box-shadow: var(--shadow); }
/* currency picker as a compact select (scales past 2 options) */
.cur-toggle .cur-select {
  font: inherit; font-size: 12.5px; font-weight: 600; color: var(--accent-ink);
  background: var(--surface); border: 1px solid var(--line); border-radius: 8px;
  padding: 5px 26px 5px 11px; cursor: pointer; line-height: 1.2;
  -webkit-appearance: none; appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23888' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 9px center;
}
.cur-toggle .cur-select:hover { border-color: var(--ink-3); }
.cur-toggle:has(.cur-select) { padding: 0; background: none; border: 0; }

/* epoch progress widget (top bar) */
.epoch-widget { min-width: 180px; }
.epoch-top { display: flex; justify-content: space-between; align-items: baseline;
  font-size: 12px; color: var(--ink-2); }
.epoch-top b { color: var(--ink); }
.epoch-pct { font-variant-numeric: tabular-nums; color: var(--accent-ink); font-weight: 600; }
.epoch-track { height: 6px; border-radius: 4px; background: var(--bg); overflow: hidden; margin: 4px 0 3px; }
.epoch-fill { height: 100%; background: var(--brand-grad); border-radius: 4px; transition: width .4s; }
.epoch-sub { font-size: 10.5px; color: var(--ink-3); font-variant-numeric: tabular-nums; }
/* "Rewards settled through epoch N" anchor — distinguishes settled data coverage
   from the live network-epoch widget. */
.settled-badge:empty { display: none; }
.settled-badge { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px;
  color: var(--ink-2); background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 999px; padding: 4px 11px; white-space: nowrap; cursor: default; }
.settled-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--pos); flex: 0 0 auto; }
@media (max-width: 720px) { .settled-badge { display: none; } }

/* APY explainer (gross - commission = net) */
.apy-row { display: flex; align-items: stretch; gap: 12px; flex-wrap: wrap; margin-top: 6px; }
.apy-cell { flex: 1; min-width: 150px; border: 1px solid var(--line); border-radius: 10px;
  padding: 14px 16px; background: var(--bg); }
.apy-cell.accent { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent-weak); }
.apy-k { font-size: 12px; color: var(--ink-3); text-transform: uppercase; letter-spacing: .03em; font-weight: 600; }
.apy-v { font-size: 26px; font-weight: 700; margin-top: 4px; font-variant-numeric: tabular-nums; }
.apy-cell.accent .apy-v { color: var(--accent-ink); }
.apy-d { font-size: 11.5px; color: var(--ink-3); margin-top: 2px; }
.apy-op { display: flex; align-items: center; font-size: 22px; color: var(--ink-3); font-weight: 700; }
/* --- Rewards Breakdown --- */
/* inline info tooltip */
.rw-info { display: inline-flex; align-items: center; justify-content: center; width: 15px; height: 15px;
  border-radius: 50%; font-size: 10px; font-weight: 700; color: var(--ink-3); border: 1px solid var(--line);
  background: var(--surface-2); cursor: help; vertical-align: middle; margin-left: 3px; }
.rw-info:hover, .rw-info:focus { color: var(--ink); border-color: var(--ink-3); outline: none; }
.rw-panel-head { margin-bottom: 14px; }
/* two revenue-stream cards */
.rw-streams { display: flex; gap: 14px; flex-wrap: wrap; }
.rw-stream { flex: 1; min-width: 180px; border: 1px solid var(--line); border-radius: 12px;
  padding: 16px 18px; background: var(--bg); position: relative; }
.rw-stream.s-infl { border-left: 3px solid var(--accent); }
.rw-stream.s-mev { border-left: 3px solid var(--violet, #7c6cf0); }
.rw-stream-k { font-size: 12px; color: var(--ink-3); text-transform: uppercase; letter-spacing: .03em; font-weight: 600; }
.rw-stream-v { font-size: 24px; font-weight: 700; margin-top: 5px; font-variant-numeric: tabular-nums; }
.rw-stream-d { font-size: 12px; color: var(--ink-3); margin-top: 3px; }
.rw-streams-note { margin-top: 12px; font-size: 12px; color: var(--ink-3); }
/* after-rebate APY hero */
.rw-apy-hero { border: 1px solid var(--accent); box-shadow: 0 0 0 1px var(--accent-weak);
  border-radius: 12px; padding: 18px 20px; background: var(--accent-weak); }
.rw-apy-k { font-size: 12px; color: var(--ink-3); text-transform: uppercase; letter-spacing: .03em; font-weight: 700; }
.rw-apy-v { font-size: 40px; font-weight: 800; margin-top: 4px; color: var(--accent-ink); font-variant-numeric: tabular-nums; line-height: 1.05; }
.rw-apy-d { font-size: 12.5px; color: var(--ink-2); margin-top: 4px; }
/* after-rebate row — the client's effective yield once the commission rebate is
   settled; a positive-green band that sits below the gross→total breakdown. */
.apy-rebate-row { display: flex; align-items: center; justify-content: space-between; gap: 14px;
  flex-wrap: wrap; margin-top: 12px; padding: 12px 16px; border-radius: 10px;
  background: color-mix(in srgb, var(--pos) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--pos) 32%, transparent); }
.apy-rebate-label { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; min-width: 0;
  line-height: 1.35; }
.apy-rebate-badge { font-size: 12px; font-weight: 700; color: var(--pos); text-transform: uppercase;
  letter-spacing: .03em; white-space: nowrap; line-height: 1.35; }
.apy-rebate-label .sub { line-height: 1.35; margin: 0; }
.apy-rebate-val { font-size: 24px; font-weight: 700; color: var(--pos); font-variant-numeric: tabular-nums;
  white-space: nowrap; line-height: 1.35; }
.apy-rebate-uplift { font-size: 13px; font-weight: 600; color: var(--pos); opacity: .8; }
.apy-row code, .sub code { font-family: ui-monospace, Menlo, monospace; font-size: 12px;
  background: var(--bg); padding: 1px 5px; border-radius: 5px; }

/* composition bar */
.comp-bar { display: flex; height: 34px; border-radius: 8px; overflow: hidden; background: var(--bg); }
.comp-seg { height: 100%; transition: width .3s; min-width: 2px; }

/* section clarification note (validator vs client) */
.section-note { background: var(--bg); border: 1px solid var(--line); border-radius: 10px;
  padding: 12px 16px; margin-bottom: 18px; font-size: 13px; }
.section-note b { color: var(--ink); }

/* vs-holding callout */
.vs-holding { margin-bottom: 20px; }
.vs-inner { display: flex; gap: 14px; align-items: flex-start; padding: 16px 20px;
  border-radius: var(--radius); border: 1px solid var(--accent-weak);
  background: linear-gradient(120deg, rgba(153,69,255,.06), rgba(20,184,154,.08));
  font-size: 14px; line-height: 1.55; color: var(--ink-2); }
.vs-inner b { color: var(--ink); }
.vs-ico { font-size: 22px; color: var(--accent-ink); font-weight: 700; line-height: 1.2; }

.actions { margin: 4px 0 40px; }
.foot { text-align: center; color: var(--ink-3); font-size: 12px; padding: 20px; border-top: 1px solid var(--line); display: flex; flex-direction: column; gap: 4px; }

/* global site footer: social icons LEFT · links CENTER · copyright RIGHT,
   sticks to the bottom of the content column (flex-shrink 0). */
.site-foot { border-top: 1px solid var(--line); padding: 16px 32px; margin-top: 24px;
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 12px;
  font-size: 12.5px; color: var(--ink-3); flex: 0 0 auto; }
.site-foot .links { display: flex; gap: 18px; flex-wrap: wrap; justify-content: center; }
.site-foot .copy { text-align: right; }
.site-foot a { color: var(--ink-3); text-decoration: none; }
.site-foot a:hover { color: var(--ink); }
.site-foot .social { display: flex; gap: 10px; justify-content: flex-start; }
.site-foot .social a { display: inline-flex; width: 28px; height: 28px; align-items: center;
  justify-content: center; border: 1px solid var(--line); border-radius: 7px; font-size: 13px; }
.site-foot .social a:hover { border-color: var(--accent); color: var(--accent-ink); }
@media (max-width: 640px) { .site-foot { grid-template-columns: 1fr; text-align: center; }
  .site-foot .copy, .site-foot .social { justify-content: center; text-align: center; } }

/* ---- mobile header controls (placed at end so these WIN over base rules
   regardless of source order; the old .price-badge/#report hides were defined
   BEFORE the base .price-badge rule and so never applied). Higher specificity
   (.content-top prefix) also guarantees the override. ---- */
@media (max-width: 640px) {
  /* SOL price hidden on mobile — the currency toggle still lets you switch */
  .content-top .price-badge { display: none !important; }
  /* Statements button -> compact icon-only so it stops crowding the avatar */
  .content-top .btn-report { padding: 8px 10px; }
  .content-top .btn-report span[data-i18n] { display: none; }   /* hide the word, keep ▤ icon */
  .content-top .btn-report .rep-ico { margin: 0; }
  /* the account menu (avatar) must never be pushed off-screen */
  .content-top #acctMenu { flex: none; }
}
/* very narrow phones: also drop the Statements button entirely (reachable from
   the drawer / statement page) so the avatar always fits */
@media (max-width: 400px) {
  .content-top .btn-report { display: none; }
}

/* --------- on-chain loading indicator (Validator Health & charts) --------- */
.chain-loading { display: flex; align-items: center; gap: 12px; padding: 22px 6px; color: var(--ink-3); }
.chain-msg { font-size: 13px; }
.chain-spin { display: inline-flex; gap: 4px; }
.chain-spin span { width: 8px; height: 8px; border-radius: 50%;
  background: var(--accent); opacity: .35; animation: chainPulse 1.1s ease-in-out infinite; }
.chain-spin span:nth-child(2) { animation-delay: .18s; }
.chain-spin span:nth-child(3) { animation-delay: .36s; }
@keyframes chainPulse { 0%, 80%, 100% { opacity: .3; transform: scale(.82); }
  40% { opacity: 1; transform: scale(1.08); } }
@media (prefers-reduced-motion: reduce) { .chain-spin span { animation: none; opacity: .6; } }

/* ---------------------------- Revenue Compare (admin) --------------------- */
/* Source-provenance banner. Unlike the green ON-CHAIN pill (data read straight
   from the chain), this flags that the figures come from a THIRD PARTY (Trillium)
   — an honest label so nobody mistakes it for our own on-chain reads. */
/* Badge + explanatory text as one centered row. The badge (~26px tall) and the
   text line center-align. flex-wrap lets the text drop below the badge on very
   narrow screens instead of overlapping. */
.src-banner { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin-bottom: 4px; }
.src-banner > .sub { line-height: 1.5; margin: 0; }
/* per-section data-source citation — small, muted line under a panel/chart so it's
   unambiguous where each number comes from (Solana RPC / Trillium / ValidBlocks). */
.src-cite { display: inline-flex; align-items: center; gap: 6px; margin-top: 12px;
  font-size: 11px; color: var(--ink-3); }
.src-cite::before { content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: var(--ink-3); flex: 0 0 auto; }
.src-cite.src-cite-chain::before { background: var(--accent); }
.chart-grid .src-cite { margin-top: 8px; }
.src-badge { display: inline-flex; align-items: center; gap: 7px; font-size: 11.5px; font-weight: 640;
  text-transform: uppercase; letter-spacing: .04em; padding: 6px 12px; border-radius: 999px;
  white-space: nowrap; }
/* tight line-height on the text so its box hugs the caps — with align-items:center
   the dot then sits on the true optical middle of the letters (uppercase has no
   descenders, so a loose line-box would push the dot visually high). */
.src-badge > span:last-child { line-height: 1; }
.src-badge .src-dot { width: 7px; height: 7px; border-radius: 50%; flex: none; }
.src-badge-3p { color: #9a6a12; background: color-mix(in srgb, #d9a441 18%, transparent);
  border: 1px solid color-mix(in srgb, #d9a441 40%, transparent); }
.src-badge-3p .src-dot { background: #d9a441; }
:root:not([data-theme="light"]) .src-badge-3p, :root[data-theme="dark"] .src-badge-3p { color: #e6b45a; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .src-badge-3p { color: #e6b45a; } }
/* on-chain (green) variant — for the Validator Health page top badge */
.src-badge-chain { color: var(--pos); background: color-mix(in srgb, var(--pos) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--pos) 38%, transparent); }
.src-badge-chain .src-dot { background: var(--pos); }

.cmp-controls { display: flex; flex-wrap: wrap; gap: 16px 20px; align-items: flex-end; }
.cmp-field { display: flex; flex-direction: column; gap: 7px; }
/* An element-level display wins over the UA's [hidden]{display:none}, so a
   .cmp-field toggled with the hidden attribute stays on screen without this. */
.cmp-field[hidden] { display: none; }
.cmp-field > label { font-size: 11px; font-weight: 660; text-transform: uppercase;
  letter-spacing: .06em; color: var(--ink-3); }
/* proper form controls (the compare inputs/selects were falling through to raw
   browser defaults). Rounded, on our surface tokens, comfortable height. */
.cmp-field input[type="text"], .cmp-field input[type="number"], .cmp-field select {
  font: inherit; font-size: 14px; color: var(--ink); background: var(--surface);
  border: 1px solid var(--line); border-radius: 10px; padding: 10px 13px; height: 42px;
  box-sizing: border-box; -webkit-appearance: none; appearance: none; }
.cmp-field select { padding-right: 34px; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23828b99' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 12px center; }
/* Read-only field value (e.g. "Maximum number of validators selected") --
   same box as the select/input controls beside it in a .cmp-field row, so
   it sits at the same height/baseline instead of reading as plain text. */
.cmp-field-value { font-size: 14px; color: var(--ink); background: var(--surface);
  border: 1px solid var(--line); border-radius: 10px; padding: 10px 13px; height: 42px;
  box-sizing: border-box; display: flex; align-items: center; font-weight: 600; }
.cmp-field input:hover, .cmp-field select:hover { border-color: var(--ink-3); }
.cmp-search { flex: 1 1 340px; min-width: 240px; }
.cmp-search-wrap { position: relative; }
.cmp-field .cmp-search-wrap input[type="text"] { width: 100%; padding-left: 38px; }
/* search icon */
.cmp-search-wrap::before { content: ""; position: absolute; left: 13px; top: 50%; width: 15px; height: 15px;
  transform: translateY(-50%); pointer-events: none; opacity: .55;
  background: no-repeat center / contain url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23828b99' stroke-width='2.2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M21 21l-4.3-4.3'/%3E%3C/svg%3E"); }
.cmp-results { position: absolute; z-index: 40; top: calc(100% + 6px); left: 0; right: 0;
  max-height: 320px; overflow-y: auto; background: var(--surface); border: 1px solid var(--line);
  border-radius: 12px; box-shadow: var(--shadow-lg); display: none; padding: 5px; }
.cmp-results.open { display: block; }
.cmp-results button { display: block; width: 100%; text-align: left; border: 0; border-radius: 8px;
  background: transparent; padding: 9px 11px; cursor: pointer; color: var(--ink); }
.cmp-results button:hover, .cmp-results button.cmp-cursor { background: var(--bg); }
.cmp-nm { font-weight: 580; font-size: 13.5px; }
.cmp-meta { font-size: 11.5px; color: var(--ink-3); margin-top: 1px; }
/* General / By-revenue-stream view toggle (Validator Comparison) */
.cmp-viewtoggle { display: inline-flex; border: 1px solid var(--line); border-radius: 9px;
  overflow: hidden; margin: 4px 0 16px; }
.cmp-vt { border: 0; background: var(--surface-2); color: var(--ink-2); font-size: 13px; font-weight: 600;
  padding: 8px 16px; cursor: pointer; border-right: 1px solid var(--line); }
.cmp-vt:last-child { border-right: 0; }
.cmp-vt:hover { color: var(--ink); }
.cmp-vt.active { background: var(--accent); color: #fff; }
/* Network reference column visibility (Mean/Median/Top 25%/Bottom 25%) --
   real checkboxes, not chips: unlike the view toggle above, any subset can
   be on at once, so a tick/cross reads more honestly than a pill. */
.cmp-stat-toggle { display: flex; flex-wrap: wrap; gap: 6px 16px; align-items: center; margin: 4px 0 16px; }
.cmp-stat-check { display: inline-flex; align-items: center; gap: 6px; font-size: 13px;
  font-weight: 600; color: var(--ink-2); cursor: pointer; user-select: none; }
.cmp-stat-check:hover { color: var(--ink); }
.cmp-stat-check input[type="checkbox"] { accent-color: var(--accent); width: 15px; height: 15px;
  margin: 0; cursor: pointer; }
/* A min/median/max cell that traces to one real validator -- hover shows
   name + pubkey (native title tooltip), click opens that validator in
   Peer Comparison. Mean/avg cells (no single real validator) stay plain text. */
.cmp-vref { color: inherit; text-decoration: underline dotted;
  text-decoration-color: var(--ink-3); text-underline-offset: 2px; cursor: pointer; }
.cmp-vref:hover { color: var(--accent); text-decoration-color: var(--accent); }
.cmp-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.cmp-chip { display: inline-flex; align-items: center; gap: 4px; background: var(--surface-2);
  border: 1px solid var(--line); border-radius: 999px; padding: 6px 8px 6px 14px; font-size: 13px; font-weight: 540; }
.cmp-x { border: 0; background: transparent; width: 20px; height: 20px; display: inline-flex;
  align-items: center; justify-content: center; border-radius: 50%;
  color: var(--ink-3); font-size: 15px; line-height: 1; cursor: pointer; }
.cmp-x:hover { color: var(--ink); background: var(--line); }

.cmp-table { font-size: 13.5px; }
.cmp-table th, .cmp-table td { white-space: nowrap; padding: 11px 13px; }
.cmp-table th:first-child, .cmp-table td:first-child { white-space: normal; }
.cmp-table thead th { font-size: 11px; font-weight: 660; text-transform: uppercase; letter-spacing: .03em;
  color: var(--ink-3); }
.cmp-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.cmp-table th.num { text-align: right; }
.cmp-table th.sep, .cmp-table td.sep { border-left: 1px solid var(--line); }
.cmp-table .cmp-pctsub { color: var(--ink-3); font-size: 10.5px; font-weight: 500; white-space: nowrap; }
.cmp-table tbody tr:hover td { background: var(--bg); }
.cmp-table tr.cmp-ours td { background: color-mix(in srgb, var(--accent) 9%, transparent); }
.cmp-table tr.cmp-ours:hover td { background: color-mix(in srgb, var(--accent) 13%, transparent); }
.cmp-table tr.cmp-ours td:first-child { box-shadow: inset 3px 0 0 var(--accent); }
.cmp-table tr.cmp-total td { font-weight: 660; background: var(--surface-2);
  border-top: 1px solid var(--line-strong, var(--line)); }
.cmp-table tr.cmp-total:hover td { background: var(--surface-2); }
/* By-epoch view: mark the best and worst validator in each epoch row, so the
   eye can follow who leads epoch to epoch instead of re-reading every number.
   Colour alone does not carry the meaning — the figures are right there. */
.cmp-table td.cmp-best { color: var(--pos); font-weight: 660; }
.cmp-table td.cmp-worst { color: var(--warn); }
/* Cohort Detail's own table: always one label column plus 3-4 equally-
   shaped numeric columns (Mean/Median/Top 25%/Bottom 25%, or Median/Top 25%/
   Bottom 25% for the Validator-Level method) -- auto layout sized each by
   its own content/header width, leaving uneven gaps between them. Fixed
   layout with only the label column's width pinned divides the remainder
   equally among however many numeric columns are actually present. */
#cdTable { table-layout: fixed; width: 100%; }
/* Wide enough that the longest row label ("Inflation / staking reward")
   fits on one line instead of wrapping and inflating every row's height --
   180px wasn't (an earlier min-width fix on the header cell alone did
   nothing here: min-width is ignored under table-layout:fixed, only an
   explicit width counts). */
#cdTable th:first-child, #cdTable td:first-child { width: 260px; }
/* Header AND data cells both centered over the column, same as Peer
   Comparison's own stream-view STAT_COLS cells (compare.js) -- a right-
   aligned number under a centered header reads as misaligned. */
#cdTable thead th.num, #cdTable td.num { text-align: center; }
.cmp-grp { text-align: center !important; font-size: 10.5px; text-transform: uppercase;
  letter-spacing: .07em; color: var(--ink-3); font-weight: 660; padding-bottom: 6px; }
.cmp-badge-us { display: inline-block; font-size: 10.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em; color: var(--accent-ink); background: color-mix(in srgb, var(--accent) 14%, transparent);
  border-radius: 5px; padding: 1px 6px; vertical-align: 1px; margin-left: 6px; }
.cmp-vhead { display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: baseline;
  justify-content: space-between; margin-bottom: 14px; }
.cmp-h3 { font-size: 11.5px; font-weight: 640; text-transform: uppercase; letter-spacing: .06em;
  color: var(--ink-3); margin: 0 0 10px; }
/* Epoch coverage: a small pill under a column header (stream view) or inline
   next to the name (general view). Always shown, on its own column/row --
   validators can each have a different range, and the network mean/median/
   top-25% columns are a further different one (the full requested window
   regardless of any validator's own coverage) -- see coverageInfo() and
   netRange in compare.js. */
.cmp-cov-badge { display: block; font-size: 10px; font-weight: 600; font-variant-numeric: tabular-nums;
  color: var(--ink-3); background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 999px; padding: 1px 8px; margin: 5px auto 0; width: fit-content; white-space: nowrap; }
.cmp-cov-badge.cmp-cov-inline { display: inline-block; margin: 0 0 0 6px; vertical-align: 1px; }
.cmp-wide-warn { background: rgba(230,160,30,.10); border: 1px solid rgba(230,160,30,.35);
  border-radius: 8px; padding: 9px 13px; font-size: 12.5px; color: var(--ink-2);
  margin: 4px 0 16px; line-height: 1.55; }
.mono { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: .9em; }

/* APY strip — stat cards */
.apystrip { display: flex; flex-wrap: wrap; gap: 12px; }
.apybox { flex: 1 1 160px; background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 12px; padding: 14px 16px; position: relative; overflow: hidden; }
.apybox::before { content: ""; position: absolute; inset: 0 auto 0 0; width: 3px; background: var(--line); }
.apybox:nth-child(1)::before { background: var(--accent); }
.apybox:nth-child(2)::before { background: var(--pos); }
.apybox:nth-child(3)::before { background: var(--warn); }
.apybox .apy-k { font-size: 10.5px; font-weight: 660; text-transform: uppercase; letter-spacing: .06em;
  color: var(--ink-3); margin-bottom: 6px; }
.apybox .apy-v { font-size: 23px; font-weight: 640; letter-spacing: -.025em; font-variant-numeric: tabular-nums; line-height: 1.05; }
.apybox .apy-v.pos { color: var(--pos); }
.apybox .apy-v.neg { color: var(--warn); }
.apybox .apy-f { font-size: 11.5px; color: var(--ink-3); margin-top: 4px; line-height: 1.4; }
@media (max-width: 640px) { .cmp-controls { gap: 12px; } .cmp-field { flex: 1 1 100%; } .cmp-search { flex: 1 1 100%; } }

/* ===================== public marketing homepage ===================== */
body.home { margin: 0; }
.home-in { max-width: 1120px; margin: 0 auto; padding: 0 24px; }

/* top nav */
.home-nav { position: sticky; top: 0; z-index: 20; border-bottom: 1px solid var(--line);
  background: color-mix(in srgb, var(--bg) 85%, transparent);
  -webkit-backdrop-filter: saturate(180%) blur(12px); backdrop-filter: saturate(180%) blur(12px); }
.home-nav-in { max-width: 1120px; margin: 0 auto; padding: 12px 24px; display: flex;
  align-items: center; justify-content: space-between; gap: 16px; }
.home-nav .brand .logo { height: 36px; }
.home-nav-links { display: flex; align-items: center; gap: 20px; }
.home-nav-links > a { font-size: 14px; color: var(--ink-2); text-decoration: none; font-weight: 500; }
.home-nav-links > a:hover { color: var(--ink); }
.home-cta-sm { padding: 8px 16px; border-radius: 9px; background: var(--accent); color: #fff !important;
  font-weight: 600; font-size: 13.5px; }
.home-cta-sm:hover { filter: brightness(1.06); }
.home-theme-select { font: inherit; font-size: 15px; color: var(--ink); background: var(--surface);
  border: 1px solid var(--line); border-radius: 9px; padding: 6px 26px 6px 12px; cursor: pointer;
  line-height: 1.2; text-align: center;
  -webkit-appearance: none; appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23828b99' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 8px center; }
.home-theme-select:hover { border-color: var(--ink-3); }
@media (max-width: 720px) { .home-nav-links > a[href^="#"], .home-nav-links > a[href="/methodology"] { display: none; } }
/* mobile nav: the brand + remaining controls (lang, theme, CTA) must fit 360px
   without pushing horizontal overflow. Tighten padding/gaps, shrink the logo,
   and let the brand shrink first so the controls always stay on-screen. */
@media (max-width: 560px) {
  .home-nav-in { padding: 10px 14px; gap: 8px; }
  /* let the brand shrink so the controls always fit, but scale the logo image
     DOWN as a whole (max-width) rather than clipping it — a cut-off wordmark
     ("Solana C…") looks broken. */
  .home-nav .brand { min-width: 0; }
  .home-nav .brand .logo { height: 26px; max-width: 100%; object-fit: contain; object-position: left center; }
  .home-nav-links { gap: 8px; flex-shrink: 0; }
  .home-cta-sm { padding: 7px 12px; font-size: 12.5px; white-space: nowrap; }
  .home-theme-select { padding: 5px 22px 5px 9px; font-size: 13px; }
}
/* very narrow (≤380px): drop the CTA text to just the wordmark room — keep the
   button but let the logo take priority; shrink the CTA further. */
@media (max-width: 380px) {
  .home-nav-in { gap: 6px; padding: 10px 12px; }
  .home-nav .brand .logo { height: 24px; }
  .home-cta-sm { padding: 6px 10px; font-size: 12px; }
}

/* hero — theme-aware. BASE below is the LIGHT (day) treatment: soft light
   ground, dark ink text, the same purple/teal glows dialed down so they read
   as gentle brand tinting on white. Dark-theme overrides further down restore
   the original high-impact near-black ground + white text. Colours here are
   written against light values on purpose; the dark blocks re-state them. */
.home-hero { position: relative; overflow: hidden; background:
  radial-gradient(1200px 600px at 80% -10%, #eef1fb 0%, transparent 60%),
  radial-gradient(900px 500px at 0% 100%, #e6f6f1 0%, transparent 55%), #f7f9fc;
  color: var(--ink); border-bottom: 1px solid var(--line); }
.home-hero .hero-glow { position: absolute; border-radius: 50%; filter: blur(90px); opacity: .18; pointer-events: none; }
.home-hero .hero-glow-a { width: 460px; height: 460px; top: -140px; right: -60px; background: #9945ff; }
.home-hero .hero-glow-b { width: 520px; height: 520px; bottom: -200px; left: -140px; background: #14c8a8; }
.home-hero-in { position: relative; max-width: 1120px; margin: 0 auto; padding: 84px 24px 72px; }
.home-badge { display: inline-flex; align-items: center; gap: 8px; font-size: 12px; font-weight: 600;
  letter-spacing: .01em; color: var(--ink-2); background: var(--surface);
  border: 1px solid var(--line); border-radius: 999px; padding: 6px 14px; }
.home-dot { width: 7px; height: 7px; border-radius: 50%; background: #14b89a; box-shadow: 0 0 0 3px rgba(20,184,154,.22); }
.home-h1 { font-size: clamp(34px, 5vw, 52px); line-height: 1.05; letter-spacing: -.03em; font-weight: 720;
  margin: 20px 0 16px; text-wrap: balance; max-width: 16ch; color: var(--ink); }
.home-lede { font-size: 16.5px; line-height: 1.65; color: var(--ink-2); margin: 0 0 30px; max-width: 52ch; }
.home-cta-row { display: flex; flex-wrap: wrap; gap: 12px; }
.home-btn { display: inline-flex; align-items: center; justify-content: center; padding: 12px 24px;
  border-radius: 11px; font-weight: 640; font-size: 15px; text-decoration: none; transition: filter .12s, transform .12s; }
.home-btn:active { transform: translateY(1px); }
/* Same --primary as the in-app button: the marketing gradient keeps its
   lift, but both now resolve to one colour, and a theme change moves
   them together instead of leaving the two halves of the site apart. */
.home-btn-primary { background: linear-gradient(180deg,
  color-mix(in srgb, var(--primary) 82%, #fff), var(--primary));
  color: var(--primary-ink); box-shadow: 0 6px 20px var(--primary-ring); }
.home-btn-primary:hover { filter: brightness(1.07); }
.home-btn-ghost { background: var(--surface); color: var(--ink); border: 1px solid var(--line); }
.home-btn-ghost:hover { background: var(--surface-2); border-color: var(--ink-3); }
.home-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin-top: 48px; }
.home-stat { background: var(--surface); border: 1px solid var(--line); border-radius: 14px; padding: 18px 18px;
  box-shadow: var(--shadow); }
.home-stat .hs-v { font-size: 28px; font-weight: 720; letter-spacing: -.02em; color: var(--ink); font-variant-numeric: tabular-nums; }
.home-stat .hs-l { font-size: 12.5px; font-weight: 640; text-transform: uppercase; letter-spacing: .05em; color: var(--ink-2); margin-top: 4px; }
.home-stat .hs-s { font-size: 12px; color: var(--ink-3); margin-top: 6px; line-height: 1.45; }
@media (max-width: 900px) { .home-stats { grid-template-columns: 1fr 1fr; } }
@media (max-width: 480px) { .home-stats { grid-template-columns: 1fr; } .home-hero-in { padding: 60px 20px 52px; } }

/* hero — DARK theme: the original high-impact near-black ground + white text.
   Applied for system-dark (no explicit light choice) and explicit data-theme=dark,
   matching the theme convention used elsewhere in this file. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .home-hero { background:
    radial-gradient(1200px 600px at 80% -10%, #16223a 0%, transparent 60%),
    radial-gradient(900px 500px at 0% 100%, #10221f 0%, transparent 55%), #0b0e14;
    color: #fff; border-bottom: 0; }
  :root:not([data-theme="light"]) .home-hero .hero-glow { opacity: .5; filter: blur(80px); }
  :root:not([data-theme="light"]) .home-badge { color: rgba(255,255,255,.85);
    background: rgba(255,255,255,.07); border-color: rgba(255,255,255,.14); }
  :root:not([data-theme="light"]) .home-dot { background: #35d0a8; box-shadow: 0 0 0 3px rgba(53,208,168,.22); }
  :root:not([data-theme="light"]) .home-h1 { color: #fff; }
  :root:not([data-theme="light"]) .home-lede { color: rgba(255,255,255,.72); }
  :root:not([data-theme="light"]) .home-btn-ghost { background: rgba(255,255,255,.08); color: #fff; border-color: rgba(255,255,255,.18); }
  :root:not([data-theme="light"]) .home-btn-ghost:hover { background: rgba(255,255,255,.14); border-color: rgba(255,255,255,.28); }
  :root:not([data-theme="light"]) .home-stat { background: rgba(255,255,255,.05); border-color: rgba(255,255,255,.1); box-shadow: none; }
  :root:not([data-theme="light"]) .home-stat .hs-v { color: #fff; }
  :root:not([data-theme="light"]) .home-stat .hs-l { color: rgba(255,255,255,.7); }
  :root:not([data-theme="light"]) .home-stat .hs-s { color: rgba(255,255,255,.5); }
}
:root[data-theme="dark"] .home-hero { background:
  radial-gradient(1200px 600px at 80% -10%, #16223a 0%, transparent 60%),
  radial-gradient(900px 500px at 0% 100%, #10221f 0%, transparent 55%), #0b0e14;
  color: #fff; border-bottom: 0; }
:root[data-theme="dark"] .home-hero .hero-glow { opacity: .5; filter: blur(80px); }
:root[data-theme="dark"] .home-badge { color: rgba(255,255,255,.85);
  background: rgba(255,255,255,.07); border-color: rgba(255,255,255,.14); }
:root[data-theme="dark"] .home-dot { background: #35d0a8; box-shadow: 0 0 0 3px rgba(53,208,168,.22); }
:root[data-theme="dark"] .home-h1 { color: #fff; }
:root[data-theme="dark"] .home-lede { color: rgba(255,255,255,.72); }
:root[data-theme="dark"] .home-btn-ghost { background: rgba(255,255,255,.08); color: #fff; border-color: rgba(255,255,255,.18); }
:root[data-theme="dark"] .home-btn-ghost:hover { background: rgba(255,255,255,.14); border-color: rgba(255,255,255,.28); }
:root[data-theme="dark"] .home-stat { background: rgba(255,255,255,.05); border-color: rgba(255,255,255,.1); box-shadow: none; }
:root[data-theme="dark"] .home-stat .hs-v { color: #fff; }
:root[data-theme="dark"] .home-stat .hs-l { color: rgba(255,255,255,.7); }
:root[data-theme="dark"] .home-stat .hs-s { color: rgba(255,255,255,.5); }

/* content sections */
.home-section { padding: 76px 0; }
.home-section-alt { background: var(--bg-2); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.home-kicker { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .08em; color: var(--accent-ink); margin-bottom: 12px; }
.home-h2 { font-size: clamp(24px, 3.4vw, 32px); line-height: 1.15; letter-spacing: -.02em; font-weight: 700; margin: 0 0 40px; max-width: 22ch; text-wrap: balance; }
/* 4 cards: one balanced row on wide screens (mirrors the 4 hero stat tiles),
   2×2 on tablet, single column on mobile — never a lone orphan card. */
.home-cards { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; }
.home-card { background: var(--surface); border: 1px solid var(--line); border-radius: 16px; padding: 24px 22px; box-shadow: var(--shadow); }
.home-card .hc-ico { width: 42px; height: 42px; border-radius: 11px; display: flex; align-items: center; justify-content: center;
  font-size: 20px; color: var(--accent-ink); background: color-mix(in srgb, var(--accent) 12%, transparent); margin-bottom: 14px; }
.home-card h3 { font-size: 16.5px; font-weight: 640; margin: 0 0 8px; }
.home-card p { font-size: 13.5px; line-height: 1.6; color: var(--ink-2); margin: 0; }
@media (max-width: 900px) { .home-cards { grid-template-columns: 1fr 1fr; } }
@media (max-width: 620px) { .home-cards { grid-template-columns: 1fr; } .home-section { padding: 56px 0; } }

/* how-it-works steps */
.home-steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.home-step { position: relative; padding: 26px 22px; background: var(--surface); border: 1px solid var(--line); border-radius: 16px; }
.home-step .hs-num { width: 34px; height: 34px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  font-size: 15px; font-weight: 700; color: #fff; background: linear-gradient(180deg, #a259ff, #7c3aed); margin-bottom: 14px; }
.home-step h3 { font-size: 16.5px; font-weight: 640; margin: 0 0 8px; }
.home-step p { font-size: 13.5px; line-height: 1.6; color: var(--ink-2); margin: 0; }
@media (max-width: 720px) { .home-steps { grid-template-columns: 1fr; } }

/* CTA band */
.home-cta-band { padding: 72px 0; text-align: center; background:
  radial-gradient(700px 300px at 50% 0%, color-mix(in srgb, var(--accent) 16%, transparent) 0%, transparent 70%); }
.home-cta-h { font-size: clamp(24px, 3.4vw, 32px); font-weight: 720; letter-spacing: -.02em; margin: 0 0 10px; text-wrap: balance; }
.home-cta-sub { font-size: 15.5px; color: var(--ink-2); margin: 0 0 26px; }

/* ---- styled <select> (shared across all pages) --------------------------
   Two ways to use it:
   1. wrap in .select-wrap for a CSS chevron (used on the account page), or
   2. bare .nice-select — it carries its own SVG chevron via background-image,
      so it looks right anywhere (role-assign dropdown, rebates month, etc.). */
.select-wrap { position: relative; display: inline-block; }
.select-wrap::after { content: ""; position: absolute; right: 13px; top: 50%; width: 9px; height: 9px;
  margin-top: -6px; border-right: 2px solid var(--ink-3); border-bottom: 2px solid var(--ink-3);
  transform: rotate(45deg); pointer-events: none; transition: border-color .15s; }
.select-wrap:focus-within::after { border-color: var(--accent); }
select.nice-select { -webkit-appearance: none; -moz-appearance: none; appearance: none;
  padding: 10px 36px 10px 13px; font-size: 14px; font-weight: 500; line-height: 1.3;
  color: var(--ink); background-color: var(--surface-2); border: 1px solid var(--line); border-radius: 10px;
  cursor: pointer; transition: border-color .15s, box-shadow .15s;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='7' viewBox='0 0 10 7'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%238790a0' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 12px center; }
/* inside a .select-wrap the CSS chevron is used, so hide the SVG one */
.select-wrap select.nice-select { background-image: none; padding-right: 38px; }
select.nice-select:hover { border-color: var(--ink-3); }
select.nice-select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-weak); }
select.nice-select:disabled { opacity: .6; cursor: not-allowed; }
select.nice-select option { color: var(--ink); background: var(--surface); }

@media print {
  .topbar, .search, .actions, #go, button { display: none !important; }
  .panel { break-inside: avoid; box-shadow: none; border: 1px solid #ccc; }
  body { background: #fff; }
}

/* ---- Validator Comparison: page tabs + network cohort analysis ---------- */
.cmp-tabs { display:flex; gap:6px; border-bottom:1px solid var(--line); margin:0 0 20px; flex-wrap:wrap; }
.cmp-tab { font-size:13px; font-weight:600; padding:10px 16px; border:0; background:none;
  color:var(--ink-3); cursor:pointer; border-bottom:2px solid transparent; margin-bottom:-1px; }
.cmp-tab:hover { color:var(--ink-2); }
.cmp-tab.active { color:var(--ink); border-bottom-color:var(--accent); }
.cmp-pane[hidden] { display:none; }

.ch-warn { background:rgba(230,160,30,.10); border:1px solid rgba(230,160,30,.35);
  border-radius:10px; padding:12px 15px; font-size:12.5px; color:var(--ink-2);
  margin-bottom:18px; line-height:1.6; }
.ch-controls { display:flex; gap:16px; flex-wrap:wrap; align-items:flex-end;
  background:var(--card); border:1px solid var(--line); border-radius:12px; padding:16px 18px; }
.ch-chart { margin-top:18px; }
.ch-bar-row { display:grid; grid-template-columns:200px 1fr 150px; gap:14px;
  align-items:center; margin-bottom:8px; font-size:12.5px; }
.ch-bar-label { text-align:right; color:var(--ink-2); font-weight:560; overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap; }
.ch-bar-track { background:var(--surface-2); border-radius:6px; height:22px;
  position:relative; overflow:visible; }
.ch-bar-fill { height:100%; border-radius:6px; background:var(--accent); transition:width .25s ease; }
.ch-bar-fill.below { background:var(--ink-3); opacity:.45; }
.ch-bar-val { font-variant-numeric:tabular-nums; color:var(--ink-3); font-size:12px; white-space:nowrap; }
.ch-net { border-left:2px dashed var(--warn,#c89020); position:absolute; top:-3px; bottom:-3px;
  z-index:2; pointer-events:none; }
.ch-legend { display:flex; gap:8px; align-items:center; font-size:11.5px;
  color:var(--ink-3); margin-top:12px; flex-wrap:wrap; }
.ch-legend i { width:24px; height:11px; display:inline-block; border-radius:3px; }
@media (max-width: 560px) {
  /* the label/value columns were fixed px (200/150) -- on a phone those two
     alone exceed the viewport, so the bar track (the actual data viz, "1fr")
     was squeezed to a sliver. Shrink the fixed columns instead. */
  .ch-bar-row { grid-template-columns: 92px 1fr 64px; gap: 8px; font-size: 11px; }
  .ch-bar-val { font-size: 10.5px; }
}
.ch-map { margin-top:18px; }
.ch-map svg { width:100%; height:auto; display:block; }
.ch-map .cc { stroke:var(--line); stroke-width:.5; }
table.ch-tbl { width:100%; border-collapse:collapse; font-size:12.5px; margin-top:4px; }
table.ch-tbl th, table.ch-tbl td { text-align:left; padding:8px 11px; border-bottom:1px solid var(--line); }
table.ch-tbl th { font-size:10.5px; letter-spacing:.04em; text-transform:uppercase;
  color:var(--ink-3); cursor:pointer; user-select:none; white-space:nowrap; }
table.ch-tbl th:hover { color:var(--ink-2); }
table.ch-tbl th.sorted { color:var(--accent-ink); }
table.ch-tbl td.num { text-align:right; font-variant-numeric:tabular-nums; }
/* Headers must follow their own column. Numeric cells are right-aligned, so a
   left-aligned header sat at the far end of the column from the figures it
   labelled, which is what made the table hard to read. */
table.ch-tbl th.num { text-align:right; }
table.ch-tbl th:first-child, table.ch-tbl td:first-child { text-align:left; }
table.ch-tbl tbody tr:hover { background:var(--surface-2); }

/* Interactive cohort map */
.ch-mapwrap { position:relative; }
.ch-pt { cursor:pointer; }
.ch-pt .cc { transition:r .12s ease, fill-opacity .12s ease; }
.ch-pt:hover .cc, .ch-pt:focus .cc { fill-opacity:1; }
.ch-pt:focus { outline:none; }
.ch-pt:focus .cc { stroke:var(--ink); stroke-width:1.5; }
.ch-pt.is-us text { font-weight:700; fill:var(--accent-ink); }
.ch-tip { position:absolute; z-index:5; pointer-events:none; min-width:215px; max-width:260px;
  background:var(--surface,#fff); border:1px solid var(--line); border-radius:10px; padding:11px 13px;
  font-size:12px; line-height:1.45; box-shadow:0 8px 26px rgba(0,0,0,.20); }
.ch-tip-big { font-size:15px; font-weight:700; margin:4px 0 7px; display:flex; gap:8px;
  align-items:baseline; flex-wrap:wrap; }
.ch-tip-big span { font-size:11.5px; font-weight:600; }
.ch-tip-rows { display:grid; grid-template-columns:1fr auto; gap:2px 10px; font-size:11.5px;
  color:var(--ink-2); }
.ch-tip-rows i { width:8px; height:8px; border-radius:2px; display:inline-block; margin-right:6px; }
.ch-tip-rows b { font-variant-numeric:tabular-nums; }
.ch-tip-us { margin-top:8px; padding-top:7px; border-top:1px solid var(--line);
  font-size:11.5px; color:var(--accent-ink); font-weight:600; }

.ch-mapwrap svg { cursor:grab; }
.ch-mapwrap svg.is-panning { cursor:grabbing; }
.ch-zoom { position:absolute; top:10px; right:10px; display:flex; flex-direction:column;
  align-items:center; gap:4px; z-index:4; }
/* align-items:center above and flex:none below matter: a column flex container
   stretches its children across the cross axis, so the buttons inherited the
   widest glyph's intrinsic width (42px) instead of the 30px asked for here --
   and only the wider two, which is what made the stack look ragged.
   Centring the glyph with flex beats line-height, which cannot account for the
   differing cap heights of "+", "-" and "fit". */
.ch-zoom button { flex:none; width:30px; height:30px; padding:0;
  display:flex; align-items:center; justify-content:center;
  border:1px solid var(--line); background:var(--surface,#fff);
  color:var(--ink); border-radius:8px; font-size:15px; font-weight:700; cursor:pointer; line-height:1;
  box-shadow:0 2px 6px rgba(0,0,0,.10); }
.ch-zoom button:hover { border-color:var(--ink-3); }
.ch-zoom button.reset { font-size:11px; font-weight:600; }

/* Modal form fields. A bare <input> inside a <label> gets spacing from the
   input's own display:block, but a <select> wrapped in .select-wrap does not --
   so the label text sat flush against the dropdown. Space the control off its
   label regardless of which one it is. */
.modal-card label { display: block; margin-bottom: 12px; font-size: 12.5px;
  font-weight: 600; color: var(--ink-2); }
/* .select-wrap is inline-block, so inside a <label> it sat on the SAME LINE as
   the label text -- a margin-top could never separate them. Force it to a block
   so the control stacks under its label like the plain inputs do. */
.modal-card label > input,
.modal-card label > select { display: block; margin-top: 6px; width: 100%; }
.modal-card label > .select-wrap { display: block; margin-top: 6px; }

/* Always reserve the scrollbar's width, even when the page does not scroll.

   Without this the page reflows by ~15px the moment a scrollbar appears or
   disappears -- which is exactly what happens when zooming a chart changes the
   height of its axis labels. The chart itself was fine; the whole CARD was
   being re-measured narrower. `stable both-edges` keeps the layout width
   constant so nothing shifts.  */
html { scrollbar-gutter: stable; }

/* Company Wallets: per-validator split under each wallet's staked total. Most
   treasury wallets stake to OTHER validators, so the chips say who actually
   earns the commission; ours is accented so the split reads at a glance. */
/* B10: the Wallets table overflowed its column by 161px at 1,366px, hiding
   Last epoch and Total earned. The cause was two columns taking 658px of 997:
   a 44-character wallet address held on one line by the table's nowrap, and
   the validator chip forcing the Staked column wide. Both can give up width
   without losing anything -- the address is monospace and truncates from the
   middle of a known-length string, and the full value stays in the title. */
.cw-addr { font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px; color: var(--ink-3); max-width: 190px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cw-wlabel { white-space: normal; max-width: 220px; }
/* The validator chips sit UNDER the staked figure, so the column only needs
   to be as wide as the number; letting the chip row wrap inside a bounded
   width reclaims the last of the overflow. */
.cw-vsplit { display:flex; flex-wrap:wrap; gap:4px; justify-content:flex-end;
  margin-top:5px; max-width:190px; margin-left:auto; }
.cw-vchip { white-space: nowrap; }
.cw-vchip { font-size:10.5px; font-weight:600; line-height:1.5; padding:1px 7px;
  border-radius:999px; background:var(--surface-2); color:var(--ink-3);
  border:1px solid var(--line); white-space:nowrap; }
.cw-vchip b { font-weight:700; color:var(--ink-2); }
.cw-vchip.ours { background:color-mix(in srgb, var(--accent) 14%, transparent);
  border-color:color-mix(in srgb, var(--accent) 34%, transparent); color:var(--accent-ink); }
.cw-vchip.ours b { color:var(--accent-ink); }

/* B17: branded 404. A mistyped URL used to return FastAPI's raw
   {"detail":"Not Found"}, which reads as a broken site rather than a wrong
   address -- and for an institutional prospect following a stale link, that
   is the first impression. */
/* flex-direction COLUMN, not the default row. As a row the card became a flex
   item on the main axis: it shrink-wrapped to 132px, ignored width:100% and
   even width:560px !important, and overflowed to left:-191px. On the cross
   axis a block-level item sizes normally, so the width and max-width apply
   and align-items centres it. */
.nf-wrap { min-height: 60vh; display: flex; flex-direction: column;
  align-items: center; justify-content: center; padding: 48px 16px; }
/* A flex ITEM with only a max-width has no width basis, so it shrink-wraps
   to its longest unbreakable word -- this collapsed to 132px and sat off
   the left edge. width:100% gives it something for max-width to cap. */
.nf-card { text-align: center; width: 100%; max-width: 560px; }
.nf-code { font-size: 72px; font-weight: 800; line-height: 1;
  background: var(--brand-grad); -webkit-background-clip: text;
  background-clip: text; color: transparent; }
.nf-h1 { font-size: 26px; margin: 14px 0 8px; }
.nf-sub { color: var(--ink-3); margin: 0 0 24px; line-height: 1.6; }
.nf-actions { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }

/* B6: the contact rows had no styles at all, so each icon was inline text and
   its natural glyph width set where the label started -- ✉ (narrow mono
   glyph), 💬 and 🌐 (wide colour emoji) pushed "Email" ~13px left of "Client
   support" and "Website". A fixed-width icon column makes the labels align
   regardless of what glyph sits in it. */
.c-row { display: flex; align-items: flex-start; gap: 12px; margin: 0 0 14px; }
.c-ico { flex: 0 0 24px; width: 24px; text-align: center; line-height: 1.5;
  font-size: 16px; color: var(--ink-3); }
.c-row > div { min-width: 0; }

/* B14: the currency <select> sat next to a price pill that already reads
   "SOL $110 USD", so two unrelated SOLs appeared side by side and the select
   looked like it was reporting a value rather than choosing one. */
.cur-toggle { display: inline-flex; align-items: center; gap: 6px; }
.cur-lbl { font-size: 11.5px; color: var(--ink-3); letter-spacing: .02em; }

/* B8: links inside the legal pages carried no styling at all -- there is no
   global `a {}` rule, so they rendered in the browser's default blue with an
   underline, which is the one thing on these pages that looks unfinished.
   Brand colour, underline only on hover. */
.legal a { color: var(--primary); text-decoration: none;
  border-bottom: 1px solid transparent; transition: border-color .15s ease; }
.legal a:hover { border-bottom-color: currentColor; }
.legal a:focus-visible { outline: none; box-shadow: var(--ring); border-radius: 2px; }

/* B13: the overall tally gives no pass/fail on its own, so a badge says which
   option carried. Derived only from the stake percentages in hand -- this
   payload has no published threshold, so nothing here claims one. */
.gov-outcome { margin-left: 8px; font-size: 10.5px; font-weight: 700;
  letter-spacing: .03em; text-transform: uppercase; padding: 2px 7px;
  border-radius: 999px; vertical-align: middle; }
.gov-outcome.carried { background: var(--accent-weak); color: var(--accent-ink); }
.gov-outcome.rejected { background: var(--neg-weak); color: var(--neg-ink); }
/* The link is now a short label, not a 130-character URL; keep it from ever
   stretching a card again. */
.gov-link a { font-size: 12.5px; color: var(--primary); text-decoration: none;
  border-bottom: 1px solid transparent; }
.gov-link a:hover { border-bottom-color: currentColor; }

/* B13: the vote pill had no layout rule, so it sat immediately after the
   title and moved left/right/left down the page as the titles changed
   length. Pinning it to the right edge makes the column scannable. */
.gov-card-top { display: flex; align-items: flex-start; justify-content: space-between;
  gap: 16px; }
.gov-card-top > div:first-child { flex: 1 1 auto; min-width: 0; }
.gov-vote { flex: 0 0 auto; }
.gov-title { margin: 0 0 4px; }
/* the outcome badge needs to clear the header text it follows */
.gov-tally-h { display: flex; align-items: center; }

/* B16: CJK headings broke mid-word -- the Traditional H2 split 承諾 across
   two lines, which reads as two unrelated characters. CJK has no spaces, so
   the browser breaks anywhere by default; keep-all holds words together and
   the browser still wraps at punctuation. Scoped to headings, where a bad
   break is most visible and lines are short enough that keep-all cannot
   cause overflow. */
html[lang^="zh"] h1, html[lang^="zh"] h2, html[lang^="zh"] .home-h1,
html[lang^="ja"] h1, html[lang^="ja"] h2, html[lang^="ja"] .home-h1,
html[lang^="ko"] h1, html[lang^="ko"] h2, html[lang^="ko"] .home-h1 {
  word-break: keep-all; overflow-wrap: break-word;
}

/* I2: the live proof strip. Each tile names its own source and epoch range,
   because a number without a provenance line is the kind of claim A1-A3 were
   pulled up for. Tiles whose figure is unavailable are dropped by the
   renderer rather than shown empty. */
.home-proof { padding: 56px 0; border-top: 1px solid var(--line);
  background: var(--bg-2); }
.proof-lede { color: var(--ink-3); max-width: 640px; margin: 6px 0 26px;
  line-height: 1.6; }
.proof-grid { display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.proof-tile { background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 18px 18px 14px; min-width: 0; }
.pt-l { font-size: 11.5px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--ink-3); }
.pt-v { font-size: 30px; font-weight: 800; letter-spacing: -0.02em;
  margin: 6px 0 4px; color: var(--ink); }
.pt-s { font-size: 12.5px; color: var(--ink-2); line-height: 1.5; }
/* green/red here are a VERDICT on a delta, never identity -- same rule as I1 */
.pt-up { color: var(--pos); font-weight: 700; white-space: nowrap; }
.pt-down { color: var(--neg); font-weight: 700; white-space: nowrap; }
.pt-src { font-size: 11px; color: var(--ink-3); margin-top: 10px;
  padding-top: 8px; border-top: 1px solid var(--line); }
.proof-verify { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 18px; font-size: 12.5px; color: var(--ink-3); }
.proof-verify code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px; background: var(--surface); border: 1px solid var(--line);
  border-radius: 6px; padding: 3px 8px; color: var(--ink-2); }
.proof-links { display: inline-flex; gap: 12px; flex-wrap: wrap; }
.proof-links a { color: var(--primary); text-decoration: none;
  border-bottom: 1px solid transparent; }
.proof-links a:hover { border-bottom-color: currentColor; }
@media (max-width: 560px) {
  .home-proof { padding: 40px 0; }
  .pt-v { font-size: 26px; }
}

/* An expired invite stays listed -- hiding it made "never invited" and
   "invited, never signed up" look the same -- so it needs to read as lapsed
   at a glance without shouting. */
.inv-expired td { color: var(--ink-3); }
.inv-badge { display: inline-block; font-size: 10.5px; font-weight: 700;
  letter-spacing: .03em; text-transform: uppercase; padding: 1px 6px;
  border-radius: 999px; background: var(--neg-weak); color: var(--neg-ink);
  margin-right: 6px; }

/* The widest column in the revenue table was its HEADER, not its data:
   "NET REVENUE (AFTER VOTE COST)" held on one line forced 216px for cells
   showing "1,530.24". Header text wraps; the numbers stay nowrap so a figure
   never splits across lines. */
.rev-table thead th { white-space: normal; line-height: 1.25; }
.rev-table thead th.rev-stick-net,
.rev-table thead th.rev-stick-usd { max-width: 118px; }
