/* ============================================================================
   nable-ui.css: the shared nable design system.

   One stylesheet, linked by onboarding.html, dashboard.html and the login page,
   so the look is defined once. Faithful to the founder-approved redesign
   (internal/redesign) and governed by DESIGN.md. Our blue only (#4db8d4); the
   redesign's electric/periwinkle/cyan blues are folded to it here.

   THEME MODEL (matches the dashboard's existing toggle):
     - Tokens have three states. An explicit choice stamps data-theme on <html>;
       the unstamped default follows the OS.
     - Bare :root carries the LIGHT palette. Dark is declared twice: once behind
       prefers-color-scheme (guarded against an explicit light pick) and once
       behind [data-theme="dark"], so the toggle wins in either direction.
     - Onboarding and sign-in are dark by founder call: their shell stamps
       <html data-theme="dark"> so they open dark on any OS, and the bottom
       toggle can still flip to light. The dashboard leaves <html> unstamped so
       it follows the OS, exactly as it does today.

   Only tokens live in the theme blocks. Every colour is defined on bare :root
   first, so a page never renders one theme's text on the other theme's ground.
   ========================================================================== */

:root {
  /* Fonts (served at /static/fonts/fonts.css). Geist for UI, Geist Mono for
     JSON / ids / numbers. The trailing names are fallbacks only, never loaded. */
  --n-font-ui: 'Geist', system-ui, -apple-system, sans-serif;
  --n-font-mono: 'Geist Mono', ui-monospace, 'JetBrains Mono', monospace;

  /* Radii: DESIGN.md: 2 chips, 6 inputs, 8 buttons, 12 cards/surfaces. */
  --n-r-chip: 2px;
  --n-r-input: 6px;
  --n-r-btn: 8px;
  --n-r-card: 12px;
  --n-r-round: 999px;   /* circles only: dots, avatars. Never on a box. */

  /* Accent: OURS, #4db8d4, both themes. Fills/borders read this; only accent
     TEXT swaps per theme (small cyan text is illegible on white). */
  --n-accent: #4db8d4;
  --n-accent-ink: #05222b;                     /* dark text placed ON the accent fill */
  --n-accent-border: rgba(77, 184, 212, .38);  /* selected / focus ring */
  --n-accent-tint: rgba(77, 184, 212, .12);    /* hover wash, chip fill */
  --n-accent-glow: rgba(77, 184, 212, .16);    /* the sign-in radial glow */

  /* Semantic status: kept as-is (these are not "the blue"). */
  --n-ok: #4ade80;
  --n-warn: #fbbf24;
  --n-err: #f87171;
  --n-ok-tint: rgba(74, 222, 128, .13);
  --n-warn-tint: rgba(251, 191, 36, .13);
  --n-err-tint: rgba(248, 113, 113, .13);

  /* Spacing rhythm */
  --n-gap: 14px;
  --n-pad-card: 18px;
  --n-maxw: 1240px;

  /* ---- LIGHT palette (bare :root default) ---- */
  --n-bg: #f6f8f9;            /* page ground */
  --n-bg-raised: #ffffff;     /* main content plane */
  --n-surface: #ffffff;       /* cards */
  --n-surface-2: #eef2f4;     /* elevated / hover */
  --n-surface-inset: #f0f3f5; /* right-rail inset, code/JSON panel */
  --n-border: #e2e7ea;
  --n-border-strong: #cfd6db;
  --n-hairline: #edf1f3;
  --n-text: #14181c;
  --n-text-2: #4a5158;
  --n-text-muted: #6d727c;    /* labels, sub-labels */
  --n-text-faint: #9aa0a8;
  --n-accent-strong: #1a86a6; /* accent TEXT on light ground */
  --n-accent-hover: #3aa7c4;  /* primary-button hover fill on light */
  --n-dot: rgba(20, 24, 28, .05);       /* static dot texture */
  --n-scrim: rgba(15, 20, 24, .40);
  --n-shadow-card: 0 1px 2px rgba(15, 20, 24, .06);
  --n-shadow-raised: 0 4px 18px rgba(15, 20, 24, .10);
}

/* ---- DARK palette: system-follow, guarded against an explicit light pick ---- */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --n-bg: #0a0b0e;            /* founder-approved, not pure black */
    --n-bg-raised: #101116;
    --n-surface: #16171d;
    --n-surface-2: #1c1d24;
    --n-surface-inset: #0c0d11; /* darker than the plane, so the JSON panel recedes */
    --n-border: #24252d;
    --n-border-strong: #313239;
    --n-hairline: #1e1f26;
    --n-text: #eef1f3;
    --n-text-2: #a4a8b1;
    --n-text-muted: #6d727c;
    --n-text-faint: #4c515b;
    --n-accent-strong: #7fd3e8; /* accent TEXT on dark ground */
    --n-accent-hover: #63c5df;  /* primary-button hover fill on dark */
    --n-dot: rgba(255, 255, 255, .045);
    --n-scrim: rgba(0, 0, 0, .58);
    --n-shadow-card: 0 1px 2px rgba(0, 0, 0, .35);
    --n-shadow-raised: 0 8px 30px rgba(0, 0, 0, .55);
  }
}

/* ---- DARK palette: explicit stamp, so the toggle wins on a light OS too ---- */
:root[data-theme="dark"] {
  --n-bg: #0a0b0e;
  --n-bg-raised: #101116;
  --n-surface: #16171d;
  --n-surface-2: #1c1d24;
  --n-surface-inset: #0c0d11;
  --n-border: #24252d;
  --n-border-strong: #313239;
  --n-hairline: #1e1f26;
  --n-text: #eef1f3;
  --n-text-2: #a4a8b1;
  --n-text-muted: #6d727c;
  --n-text-faint: #4c515b;
  --n-accent-strong: #7fd3e8;
  --n-accent-hover: #63c5df;
  --n-dot: rgba(255, 255, 255, .045);
  --n-scrim: rgba(0, 0, 0, .58);
  --n-shadow-card: 0 1px 2px rgba(0, 0, 0, .35);
  --n-shadow-raised: 0 8px 30px rgba(0, 0, 0, .55);
}

/* ============================================================================
   Base
   ========================================================================== */
.n-ui, .n-ui * { box-sizing: border-box; }
.n-ui {
  margin: 0;
  background: var(--n-bg);
  color: var(--n-text);
  font-family: var(--n-font-ui);
  font-size: 13.5px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
.n-ui button:not(.n-btn) { font: inherit; color: inherit; background: none; border: none; padding: 0; cursor: pointer; }
.n-ui a { color: inherit; text-decoration: none; }
.n-mono { font-family: var(--n-font-mono); font-variant-numeric: tabular-nums; }

/* Typography helpers */
.n-eyebrow {
  font-size: 11px; font-weight: 500; letter-spacing: .14em; text-transform: uppercase;
  color: var(--n-accent-strong);
}
.n-h1 {
  font-family: var(--n-font-ui); font-weight: 500; letter-spacing: -.03em;
  font-size: clamp(24px, 2.2vw, 30px); line-height: 1.1; color: var(--n-text); margin: 0;
}
.n-subhead { font-size: 14.5px; color: var(--n-text-2); margin: 8px 0 0; max-width: 46ch; line-height: 1.6; }
.n-label {
  font-size: 11px; font-weight: 500; letter-spacing: .12em; text-transform: uppercase;
  color: var(--n-text-muted);
}

/* ============================================================================
   Brand mark: the falling-cost-line N. Always #4db8d4 (never the bundle blues).
   Drop <svg class="n-mark"> using currentColor; set the wordmark beside it.
   ========================================================================== */
.n-mark { width: 22px; height: 22px; color: var(--n-accent); display: block; }
.n-wordmark { font-weight: 500; font-size: 15px; letter-spacing: -.01em; color: var(--n-text); }

/* ============================================================================
   Top bar: N-mark + wordmark left, links right.
   ========================================================================== */
.n-topbar {
  display: flex; align-items: center; justify-content: space-between;
  height: 56px; padding: 0 22px;
  border-bottom: 1px solid var(--n-hairline); background: var(--n-bg-raised);
}
.n-topbar__brand { display: flex; align-items: center; gap: 9px; }
.n-topbar__nav { display: flex; align-items: center; gap: 18px; }
.n-topbar__link {
  font-size: 13px; color: var(--n-text-2); min-height: 44px;
  display: inline-flex; align-items: center; transition: color .15s ease;
}
.n-topbar__link:hover { color: var(--n-text); }

/* ============================================================================
   Onboarding: 3-column shell. Left rail (brand + steps) / a shared topbar
   over center + trust / the connect column / the right trust rail.

   The topbar (step counter, Docs/Help, progress line) sits ONLY above center
   and trust, never above the rail: the rail carries its own brand mark at
   the top instead of a page-wide header, matching the founder-approved
   mockup (internal/redesign/_zip.html, 2026-09-05). Named grid areas, not
   row order, keep the topbar spanning exactly those two columns as the
   layout narrows.
   ========================================================================== */
.n-onboard {
  display: grid;
  grid-template-columns: 260px minmax(0, 1fr) 320px;
  grid-template-areas: "rail topbar topbar" "rail center trust";
  grid-template-rows: max-content 1fr;
  min-height: 100vh;
}
.n-onboard__rail { grid-area: rail; }
.n-onboard__topbar { grid-area: topbar; }
.n-onboard__center {
  grid-area: center;
  padding: 44px clamp(22px, 3.5vw, 48px) 16px;
  display: flex; flex-direction: column; gap: 22px;
  max-width: 700px; width: 100%; margin: 0 auto;
}
.n-onboard__trust {
  grid-area: trust;
  padding: 44px clamp(20px, 2vw, 28px) 40px 0;
}
@media (max-width: 1040px) {
  .n-onboard {
    grid-template-columns: 240px minmax(0, 1fr);
    grid-template-areas: "rail topbar" "rail center" "rail trust";
    grid-template-rows: max-content max-content 1fr;
  }
  .n-onboard__trust {
    grid-area: trust;
    padding: 24px clamp(22px, 3.5vw, 48px) 40px;
    max-width: 700px; width: 100%; margin: 0 auto;
  }
}
@media (max-width: 720px) {
  .n-onboard { grid-template-columns: 1fr; grid-template-areas: "topbar" "center" "trust"; }
  .n-onboard__rail.n-rail { display: none; }
  /* The rail (and its brand) is gone at this width, so the topbar grows the
     wordmark it otherwise keeps hidden: the brand must never fully disappear. */
  .n-onboard__topbar-brand { display: flex; }
}

/* ---- Shared topbar: step counter left, Docs/Help right, a thin accent
   progress line along the very top edge. Purely presentational (render()
   keeps its text and fill width current); it owns no connect logic. ---- */
.n-onboard__topbar { display: flex; flex-direction: column; }
.n-onboard__progress { height: 2px; background: var(--n-hairline); }
.n-onboard__progress > i { display: block; height: 100%; background: var(--n-accent); width: 0; transition: width .3s ease; }
.n-onboard__topbar-row {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  height: 45px; padding: 0 clamp(20px, 2vw, 28px) 0 clamp(22px, 3.5vw, 48px);
}
.n-onboard__topbar-brand { display: none; align-items: center; gap: 8px; }
.n-onboard__step { font-size: 12.5px; color: var(--n-text-muted); }

/* ---- Left rail ---- */
.n-rail {
  border-right: 1px solid var(--n-hairline); background: var(--n-bg);
  padding: 22px 18px; display: flex; flex-direction: column; gap: 22px;
}
.n-rail__brand { display: flex; align-items: center; gap: 9px; padding: 0 6px; }
.n-rail__label { margin: 0 6px 2px; }         /* apply .n-label too: "SETUP" */
.n-rail__spacer { flex: 1 1 auto; }           /* pushes the theme toggle to the bottom */

/* ---- Step nav ----
   Selectors below read `.n-ui button.n-step`, not plain `.n-step`: the base
   reset up top (`.n-ui button:not(.n-btn)`) is two classes deep once you
   count its :not() argument, so a bare single-class `.n-step` loses the
   cascade to it and silently renders with padding:0/background:none. Custom
   button components need to match or beat that specificity on purpose. */
.n-stepnav { display: flex; flex-direction: column; gap: 2px; }
.n-ui button.n-step {
  display: grid; grid-template-columns: 26px 1fr; align-items: start; gap: 11px;
  padding: 9px 8px; border-radius: var(--n-r-input); text-align: left; width: 100%;
  transition: background .15s ease;
}
.n-ui button.n-step:hover { background: var(--n-surface-2); }
.n-step__dot {
  width: 22px; height: 22px; border-radius: var(--n-r-round);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--n-font-mono); font-size: 11px; margin-top: 1px;
  border: 1px solid var(--n-border-strong); color: var(--n-text-muted);
  background: transparent; flex: 0 0 auto;
}
.n-step__label { font-size: 13px; font-weight: 500; color: var(--n-text-2); }
.n-step__sub { font-size: 11.5px; color: var(--n-text-faint); margin-top: 1px; }
/* future: hollow number (default above). active: filled accent dot. done: check. */
.n-step--active .n-step__dot {
  background: var(--n-accent); border-color: var(--n-accent); color: var(--n-accent-ink);
}
.n-step--active .n-step__label { color: var(--n-text); }
.n-step--done .n-step__dot {
  background: transparent; border-color: var(--n-accent); color: var(--n-accent-strong);
}
.n-step--done .n-step__label { color: var(--n-text-2); }

/* ---- Reassurance card ("Read-only, the whole way") ---- */
.n-reassure {
  display: flex; gap: 10px; padding: 13px; border-radius: var(--n-r-card);
  background: var(--n-surface); border: 1px solid var(--n-border);
}
.n-reassure__icon { color: var(--n-accent); flex: 0 0 auto; margin-top: 1px; }
.n-reassure__text { font-size: 12px; color: var(--n-text-2); line-height: 1.45; }

/* ============================================================================
   Provider cards: AWS / GCP / Azure tiles. Horizontal row tiles, fixed at
   2-up: a boxed brand logo on the left, name + status stacked to its right.
   Fixed columns (not auto-fit) so three providers always read as "two, then
   one on its own row" regardless of how wide the center column gets.
   ========================================================================== */
.n-provider-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
/* `.n-ui button.n-provider`, same reason as .n-step above: beats the base
   button reset's specificity instead of losing border/background/padding to it. */
.n-ui button.n-provider {
  display: flex; flex-direction: row; align-items: center; gap: 12px;
  padding: 12px 14px; border-radius: var(--n-r-card);
  background: var(--n-surface); border: 1px solid var(--n-border);
  text-align: left; transition: border-color .15s ease, background .15s ease;
}
.n-ui button.n-provider:hover { border-color: var(--n-border-strong); background: var(--n-surface-2); }
.n-ui button.n-provider--selected {
  border-color: var(--n-accent); background: var(--n-accent-tint);
  box-shadow: 0 0 0 3px var(--n-accent-tint);
}
/* White boxed logo, like a brand badge: keeps every provider's real colour
   (AWS orange, GCP tricolour, Azure blue) legible on the dark shell. A dark
   `color` gives the two currentColor-only marks (github/openai, see svg() in
   the script below) something to resolve against if they ever land here. */
.n-provider__logo {
  width: 36px; height: 36px; border-radius: var(--n-r-btn); flex: 0 0 auto;
  background: #fff; border: 1px solid var(--n-border); color: #14181c;
  display: flex; align-items: center; justify-content: center;
}
.n-provider__logo svg, .n-provider__logo img { height: 18px; width: auto; display: block; }
.n-provider__text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.n-provider__name { font-size: 14px; font-weight: 500; color: var(--n-text); }
.n-provider__sub { font-size: 11.5px; color: var(--n-text-muted); }

/* ============================================================================
   Detail card: selected provider: how it connects, Connected pill, kv table.
   ========================================================================== */
.n-detail {
  border-radius: var(--n-r-card); background: var(--n-surface);
  border: 1px solid var(--n-border); padding: var(--n-pad-card);
  display: flex; flex-direction: column; gap: 14px;
}
/* Logo + a two-line title (name, then how-it-connects) filling the row, so
   the Connected pill (a sibling after __titles) lands flush right without
   its own justify-content rule. */
.n-detail__head { display: flex; align-items: center; gap: 12px; }
.n-detail__logo {
  width: 40px; height: 40px; border-radius: var(--n-r-btn); flex: 0 0 auto;
  background: #fff; border: 1px solid var(--n-border); color: #14181c;
  display: flex; align-items: center; justify-content: center;
}
.n-detail__logo svg { height: 20px; width: auto; }
.n-detail__titles { display: flex; flex-direction: column; gap: 2px; flex: 1 1 auto; min-width: 0; }
.n-detail__title { font-size: 15px; font-weight: 500; color: var(--n-text); }
.n-detail__sub { font-size: 12px; color: var(--n-text-muted); }
.n-detail__meta { font-size: 12.5px; color: var(--n-text-2); line-height: 1.5; }

/* Key/value table (account / role / write-perms) */
.n-kv { display: flex; flex-direction: column; border-top: 1px solid var(--n-hairline); }
.n-kv__row {
  display: grid; grid-template-columns: 128px 1fr; gap: 12px; align-items: center;
  padding: 9px 0; border-bottom: 1px solid var(--n-hairline);
}
.n-kv__key { font-size: 12px; color: var(--n-text-muted); }
.n-kv__val { font-size: 12.5px; color: var(--n-text); font-family: var(--n-font-mono); word-break: break-all; }

/* ============================================================================
   Pills / chips
   ========================================================================== */
.n-pill {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11.5px; font-weight: 500; padding: 3px 9px; border-radius: var(--n-r-chip);
  border: 1px solid var(--n-border); color: var(--n-text-2); background: var(--n-surface-2);
}
.n-pill__dot { width: 6px; height: 6px; border-radius: var(--n-r-round); background: currentColor; }
.n-pill--ok { color: var(--n-ok); background: var(--n-ok-tint); border-color: transparent; }
.n-pill--warn { color: var(--n-warn); background: var(--n-warn-tint); border-color: transparent; }
.n-pill--err { color: var(--n-err); background: var(--n-err-tint); border-color: transparent; }
.n-pill--accent { color: var(--n-accent-strong); background: var(--n-accent-tint); border-color: transparent; }

.n-chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 10.5px; font-weight: 500; letter-spacing: .02em; text-transform: uppercase;
  padding: 3px 7px; border-radius: var(--n-r-chip);
  color: var(--n-text-muted); background: var(--n-surface-2); border: 1px solid var(--n-border);
}

/* ============================================================================
   Buttons
   ========================================================================== */
.n-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 40px; padding: 0 18px; border-radius: var(--n-r-btn);
  font-family: inherit; font-size: 13.5px; font-weight: 500; cursor: pointer;
  transition: background .15s ease, border-color .15s ease, opacity .15s ease;
}
.n-btn:disabled { opacity: .5; cursor: not-allowed; }
.n-btn--primary { background: var(--n-accent); color: var(--n-accent-ink); border: 1px solid var(--n-accent); }
.n-btn--primary:hover:not(:disabled) { background: var(--n-accent-hover); border-color: var(--n-accent-hover); }
.n-btn--secondary { background: transparent; color: var(--n-text); border: 1px solid var(--n-border-strong); }
.n-btn--secondary:hover:not(:disabled) { background: var(--n-surface-2); }
/* SSO door: light bg, dark text, small glyph. Reads as "the primary door" on a
   dark page without borrowing the accent, per the sign-in spec. */
.n-btn--sso { background: #ffffff; color: #14181c; border: 1px solid #ffffff; }
.n-btn--sso:hover:not(:disabled) { background: #eef2f4; }
.n-btn--sso .n-btn__glyph { width: 16px; height: 16px; }
.n-btn--block { width: 100%; }

/* ============================================================================
   Trust panel (right rail): "WHAT NABLE GETS": the IAM JSON + can/cannot list.
   ========================================================================== */
.n-trust {
  border-left: 1px solid var(--n-hairline); background: var(--n-bg);
  padding: 26px 20px; display: flex; flex-direction: column; gap: 16px;
}
.n-trust__label { margin: 0; }                 /* apply .n-label too: "WHAT NABLE GETS" */
.n-trust__json {
  font-family: var(--n-font-mono); font-size: 11.5px; line-height: 1.6;
  background: var(--n-surface-inset); border: 1px solid var(--n-border);
  border-radius: var(--n-r-input); padding: 13px 14px;
  overflow-x: auto; white-space: pre; color: var(--n-text-2);
}
/* Subtle key/string tint. Wrap tokens in these spans inside .n-trust__json. */
.n-json-key { color: var(--n-accent-strong); }
.n-json-str { color: var(--n-text); }
.n-json-punc { color: var(--n-text-faint); }

/* One bordered card holding all three rows (Reads / Never / Cannot), divided
   by hairlines, rather than three loose lines: matches the mockup's card
   treatment for this list. Cross rows read as `--n-err`: RE-SKIN-RULES.md
   keeps red as a real semantic colour, and "cannot / never" is exactly the
   negative case it exists for. */
.n-trust__list {
  display: flex; flex-direction: column;
  border: 1px solid var(--n-border); border-radius: var(--n-r-card);
  background: var(--n-surface); overflow: hidden;
}
.n-trust__item { display: grid; grid-template-columns: 18px 1fr; gap: 10px; padding: 11px 14px; font-size: 12.5px; line-height: 1.5; color: var(--n-text-2); }
.n-trust__item + .n-trust__item { border-top: 1px solid var(--n-hairline); }
.n-trust__item-ic { width: 16px; height: 16px; margin-top: 1px; flex: 0 0 auto; }
.n-trust__item--yes .n-trust__item-ic { color: var(--n-ok); }
.n-trust__item--no .n-trust__item-ic { color: var(--n-err); }

/* ============================================================================
   Sign-in: centered, dark, static glow + static dots. SSO only.
   ========================================================================== */
.n-signin {
  position: relative; min-height: calc(100vh - 56px);
  display: flex; align-items: center; justify-content: center; padding: 40px 20px;
  overflow: hidden;
}
/* Static radial glow, top-center. NEVER animated. */
.n-signin__glow {
  position: absolute; top: -180px; left: 50%; transform: translateX(-50%);
  width: 620px; height: 620px; pointer-events: none; z-index: 0;
  background: radial-gradient(circle, var(--n-accent-glow) 0%, transparent 62%);
}
/* Static dot texture: a tiled dot grid, no motion (DESIGN.md bans pulsing dots). */
.n-dots {
  position: absolute; inset: 0; pointer-events: none; z-index: 0;
  background-image: radial-gradient(var(--n-dot) 1px, transparent 1.4px);
  background-size: 22px 22px;
  -webkit-mask-image: radial-gradient(circle at 50% 30%, #000 0%, transparent 70%);
  mask-image: radial-gradient(circle at 50% 30%, #000 0%, transparent 70%);
}
.n-signin__card {
  position: relative; z-index: 1; width: 100%; max-width: 380px;
  display: flex; flex-direction: column; align-items: center; gap: 14px; text-align: center;
}
.n-signin__card .n-h1 { text-align: center; }
.n-signin__card .n-subhead { text-align: center; margin: 0; }
.n-signin__actions { width: 100%; margin-top: 8px; }
.n-fineprint { font-size: 11.5px; color: var(--n-text-faint); line-height: 1.5; margin-top: 4px; }
.n-fineprint a { color: var(--n-text-2); text-decoration: underline; text-underline-offset: 2px; }

.n-page-footer {
  display: flex; align-items: center; justify-content: center; gap: 18px;
  padding: 20px; border-top: 1px solid var(--n-hairline);
  font-size: 12px; color: var(--n-text-muted);
}
.n-page-footer a { color: var(--n-text-muted); }
.n-page-footer a:hover { color: var(--n-text-2); }

/* ============================================================================
   Theme toggle (system / light / dark): reused from the dashboard model.
   ========================================================================== */
.n-theme-tog { display: inline-flex; gap: 1px; background: var(--n-hairline); border-radius: var(--n-r-btn); padding: 2px; }
/* `.n-ui button.n-theme-tog` would not reach these (button is a descendant,
   not the class holder), so this one keeps the :not(.n-btn) reset's own
   compound shape (class + element + class-in-:not) to match its specificity:
   otherwise `color` here loses to the reset's `color: inherit` and every
   inactive icon renders full-brightness text colour instead of a dim one. */
.n-ui .n-theme-tog button:not(.n-btn) {
  width: 26px; height: 22px; border-radius: var(--n-r-input);
  display: flex; align-items: center; justify-content: center; color: var(--n-text-faint);
}
:root:not([data-theme]) .n-theme-tog [data-th="system"],
:root[data-theme="light"] .n-theme-tog [data-th="light"],
:root[data-theme="dark"] .n-theme-tog [data-th="dark"] {
  background: var(--n-surface); color: var(--n-text); box-shadow: var(--n-shadow-card);
}

/* ============================================================================
   ACCOUNTS LIST (dashboard Integrations feature).

   One cloud connection covers many linked accounts. Render each account by
   NAME (primary), id secondary in mono, period spend right-aligned in mono,
   sorted by spend descending. Header reads "N accounts", never "1 sources".
   ========================================================================== */
.n-accounts {
  border: 1px solid var(--n-border); border-radius: var(--n-r-card);
  background: var(--n-surface); overflow: hidden;
}
.n-accounts__head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 13px 16px; border-bottom: 1px solid var(--n-hairline); background: var(--n-bg-raised);
}
.n-accounts__title { font-size: 13.5px; font-weight: 500; color: var(--n-text); }
.n-accounts__count { font-size: 12px; color: var(--n-text-muted); }   /* "N accounts" */
.n-accounts__list { display: flex; flex-direction: column; }

.n-acct-row {
  display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 12px;
  padding: 11px 16px; border-bottom: 1px solid var(--n-hairline);
}
.n-acct-row:last-child { border-bottom: none; }
.n-acct-row:hover { background: var(--n-surface-2); }
.n-acct__ident { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.n-acct__name { font-size: 13.5px; font-weight: 500; color: var(--n-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.n-acct__id { font-family: var(--n-font-mono); font-size: 11.5px; color: var(--n-text-muted); font-variant-numeric: tabular-nums; }
.n-acct__spend { font-family: var(--n-font-mono); font-size: 13px; color: var(--n-text); font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }
/* Fallback: no name available: the id is promoted to the primary line. */
.n-acct-row--nameless .n-acct__id { font-size: 13.5px; color: var(--n-text); }
/* Source note ("account names unavailable, showing ids"): honest, never a lie. */
.n-src-note { padding: 9px 16px; font-size: 11.5px; color: var(--n-text-faint); border-top: 1px solid var(--n-hairline); }

/* ============================================================================
   Motion: respect reduced motion. Nothing decorative animates here anyway.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  .n-ui * { transition-duration: .01ms !important; animation-duration: .01ms !important; }
}
