/* Nought: a dense, dark trading terminal. One palette, set here.
   This file holds only the design tokens, the base reset and the components every page shares (buttons, chips,
   inputs, segmented controls and their one selected look, .subtabs, the .hfade scroll fade, .eyebrow labels,
   .empty-state and .skel, tooltips, switches, the coin avatar and quick-buy button, dialogs, toasts). Page styles live
   in css/<page>.css, scoped under the page's root class; the frame (top bar, watchlist strip, status bar, search) is in
   css/shell.css. Generic names that pages also use for their own bits (.page, .empty, .pulse-dot, .sym, .nm, .copy,
   .age, .soc, .l1, .l2, .flag) are wrapped in :where(): zero specificity, so any page rule beats them. */
/* Themes: Nought Dark is the default. Grey, OLED and Light only redefine tokens, so every page follows them.
   A custom accent (Settings > Display) is set inline on <html> as --accent / --accent-2 / --accent-ink; on Light it is
   first darkened until it reads on white (src/ui/shell.js accentFor, mirrored in src/ui/theme-init.js before paint).
   --accent-def is the theme's own accent (what "Theme default" shows). src/ui/shell.js emits util 'theme' after every
   change, for code that needs resolved colours (charts). */
:root {
  /* surfaces: page, panels and cards, raised (menus, hovered rows, chips); strokes: dividers, then stronger borders */
  --bg: #06070b; --panel: #101114; --panel-2: #18181a; --line: #22242d; --line-2: #323542;
  /* text tiers: primary, secondary (values that are not the headline), labels and tertiary, then icons/placeholders */
  --fg: #fcfcfc; --fg-2: #c8c9d1; --muted: #828598; --dim: #6e7184;
  --accent-def: #526fff; --accent: var(--accent-def); --accent-2: #4560e0; --accent-ink: #fff;
  --accent-hover: color-mix(in srgb, var(--accent) 86%, #fff);
  --up: #12af80; --down: #f25461; --warn: #f5c84c; --info: #5dbcff;
  /* trading fills: the Buy / Sell buttons and active Buy / Sell tabs (text on them uses the -ink colour). For green or
     red TEXT use --up / --down, which read on every theme. */
  --buy: #2ee3ad; --buy-ink: #090909; --sell: #ec397a; --sell-ink: #090909;
  /* charts (canvas code reads these with getComputedStyle): candles, grid, background */
  --chart-bg: var(--panel); --chart-grid: #16171c; --chart-up: #0b9981; --chart-down: #f23446;
  /* market-cap tiers for coin rows: under ~$30K, ~$30K-$100K, $100K and up */
  --mc-low: #52c5ff; --mc-mid: #f5c84c; --mc-high: #12af80;
  /* neutral fills: a plain button / chip fill and its hover, a row hover wash, a half-strength divider */
  --fill: var(--line); --fill-2: var(--line-2); --hover: color-mix(in srgb, var(--fg) 4%, transparent); --line-soft: color-mix(in srgb, var(--line) 55%, transparent);
  --shadow: 0 10px 28px rgba(0, 0, 0, .55); --shadow-lg: 0 18px 48px rgba(0, 0, 0, .65); --backdrop: rgba(0, 0, 0, .62);
  /* the one "selected" look for segmented controls, tabs-in-a-box and toggles: an accent tint with accent text (solid
     accent is kept for primary buttons and the theme/accent pickers) */
  --sel-fg: var(--accent); --sel-bg: color-mix(in srgb, var(--accent) 15%, transparent); --sel-line: color-mix(in srgb, var(--accent) 40%, transparent);
  /* control heights: page toolbars use --h for inputs, segments and buttons alike; --h-xl is the big trade button */
  --h-sm: 26px; --h: 30px; --h-lg: 36px; --h-xl: 48px;
  /* radii: containers and image frames 4px, controls 6px, cards and menus 8px, dialogs 12px, pills fully round */
  --radius: 4px; --radius-md: 8px; --radius-lg: 12px; --pill: 999px;
  --row: 64px;
  /* numbers use the sans face with tabular figures (.mono / .num add them); --code is the true monospace, for keys,
     JSON and code */
  --sans: "Geist", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "Geist", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --code: "Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  color-scheme: dark;
}
:root[data-theme="grey"] {
  --bg: #131418; --panel: #1a1b20; --panel-2: #222329; --line: #2c2e37; --line-2: #3b3e4b;
  --fg: #f2f3f6; --fg-2: #c9cad3; --muted: #8c8fa2; --dim: #73768a;
  --chart-grid: #212228;
}
:root[data-theme="oled"] {
  --bg: #000; --panel: #060608; --panel-2: #0e0f12; --line: #1a1b22; --line-2: #2a2c36;
  --chart-grid: #0e0f13;
  --shadow: 0 12px 30px rgba(0, 0, 0, .8); --shadow-lg: 0 18px 44px rgba(0, 0, 0, .85); --backdrop: rgba(0, 0, 0, .78);
}
:root[data-theme="light"] {
  --bg: #f4f5f8; --panel: #fff; --panel-2: #eef0f4; --line: #e3e5eb; --line-2: #cfd3dc;
  --fg: #12141a; --fg-2: #3b404d; --muted: #5b6173; --dim: #6b7184;
  /* #526fff is 4.1:1 on white; this deeper blue reads at 5.3:1 */
  --accent-def: #3d5af1; --accent-2: #2f48c9; --accent-ink: #fff; --accent-hover: var(--accent-2);
  --up: #0a8752; --down: #d6304a; --warn: #95600c; --info: #0b6fb3;
  --buy: #1cc996; --buy-ink: #06120d; --sell: #e0336f; --sell-ink: #090909;
  --chart-grid: #eef0f3; --chart-up: #089981; --chart-down: #f23645;
  --mc-low: #0a74b5; --mc-mid: #8f6400; --mc-high: #0a8752;
  --hover: color-mix(in srgb, var(--fg) 5%, transparent);
  --shadow: 0 10px 28px rgba(20, 24, 34, .14); --shadow-lg: 0 16px 40px rgba(20, 24, 34, .18); --backdrop: rgba(20, 24, 34, .35);
  /* the accent on its own tint is about 4.5:1 on white; the darker shade reads */
  --sel-fg: var(--accent-2);
  color-scheme: light;
}

/* ---- base. The element resets have zero specificity, so any class (ours or a page's) beats them. ---- */
* { box-sizing: border-box; scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; }
html, body { height: 100%; }
body { margin: 0; background: var(--bg); color: var(--fg); font: 13px/1.4 var(--sans); display: grid; grid-template-rows: auto auto 1fr auto; overflow: hidden; -webkit-font-smoothing: antialiased; }
::selection { background: color-mix(in srgb, var(--accent) 35%, transparent); }
:where(a) { color: inherit; text-decoration: none; }
:where(button) { font: inherit; color: inherit; cursor: pointer; }
:where(input, select, textarea) { font: inherit; color: inherit; }
:where(select) option { background: var(--panel); color: var(--fg); }
:where(input[type="checkbox"], input[type="radio"], input[type="range"], progress) { accent-color: var(--accent); }
::placeholder { font-family: var(--sans); color: var(--dim); opacity: 1; }
.mono, .num { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.code { font-family: var(--code); }
.up { color: var(--up); } .down { color: var(--down); } .muted { color: var(--muted); } .dim { color: var(--dim); } .fg2 { color: var(--fg-2); }
.warn-t { color: var(--warn); } .info { color: var(--info); }
[hidden] { display: none !important; }
.sr-only { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
kbd { display: inline-grid; place-items: center; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 4px; border: 1px solid var(--line-2); background: var(--panel-2); color: var(--muted); font: 500 11px/1 var(--sans); }

#view { min-height: 0; overflow: hidden; }
/* narrow screens: the document scrolls rather than each page */
@media (max-width: 900px) { body { overflow: auto; } #view { overflow: visible; } }
/* a plain scrolling page (landing, upkeep, yield use it): prose defaults that the page's own rules always override */
:where(.page) { height: 100%; overflow-y: auto; }
:where(.page) h1 { margin: 0; font: 700 44px/1.02 var(--sans); letter-spacing: -.035em; text-wrap: balance; }
:where(.page) h1 em { font-style: normal; color: var(--accent); }
:where(.page) h2 { margin: 0 0 8px; font: 600 18px/1.2 var(--sans); }
:where(.page) p { margin: 0; color: var(--muted); font-size: 15px; line-height: 1.6; max-width: 64ch; }
@media (max-width: 700px) { :where(.page) h1 { font-size: 34px; } }

/* ---- focus: one accent ring for every control reached by keyboard ---- */
:where(input, select, textarea, summary, [tabindex]:not([tabindex="-1"])):focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.btn:focus-visible, .seg button:focus-visible, .qb:focus-visible, a:focus-visible, button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* ---- buttons. <button class="btn">: a compact grey pill; add one of
     .btn-accent (primary: blue pill, white bold text) · .btn-ghost (outlined, transparent) · .btn-buy / .btn-sell
     (trade fills) · .danger (red text on a red wash); sizes .sm / .lg / .xl, .icon for a round icon-only button,
     .block for full width. ---- */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; height: 32px; padding: 0 14px; border-radius: var(--pill); border: 1px solid transparent; background: var(--fill); color: var(--fg); font: 600 12.5px/1 var(--sans); white-space: nowrap; transition: background-color .12s, border-color .12s, color .12s; }
.btn:hover { background: var(--fill-2); }
.btn-accent { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); font-weight: 700; }
.btn-accent:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.btn-accent:focus-visible { outline-offset: 2px; } /* a gap between the accent fill and its ring, never a doubled border */
.btn-ghost { background: transparent; border-color: var(--line); color: var(--fg-2); }
.btn-ghost:hover { background: var(--hover); border-color: var(--line-2); color: var(--fg); }
.btn-buy { background: var(--buy); border-color: var(--buy); color: var(--buy-ink); font-weight: 700; }
.btn-buy:hover { background: color-mix(in srgb, var(--buy) 86%, #fff); border-color: color-mix(in srgb, var(--buy) 86%, #fff); }
.btn-sell { background: var(--sell); border-color: var(--sell); color: var(--sell-ink); font-weight: 700; }
.btn-sell:hover { background: color-mix(in srgb, var(--sell) 86%, #fff); border-color: color-mix(in srgb, var(--sell) 86%, #fff); }
.btn-buy:focus-visible, .btn-sell:focus-visible { outline-offset: 2px; }
.btn.danger { color: var(--down); background: color-mix(in srgb, var(--down) 9%, transparent); border-color: color-mix(in srgb, var(--down) 30%, transparent); }
.btn.danger:hover { background: color-mix(in srgb, var(--down) 16%, transparent); border-color: color-mix(in srgb, var(--down) 50%, transparent); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }
.btn.icon { width: 32px; padding: 0; }
.btn.sm { height: var(--h-sm); padding: 0 10px; font-size: 11.5px; }
.btn.sm.icon { width: var(--h-sm); padding: 0; }
.btn.lg { height: var(--h-lg); padding: 0 18px; font-size: 13.5px; }
.btn.xl { height: var(--h-xl); padding: 0 22px; font-size: 15px; }
.btn.block { display: flex; width: 100%; }
.btn-ghost.icon { border-color: transparent; color: var(--muted); }
.btn-ghost.icon:hover, .btn-ghost.icon[aria-expanded="true"] { color: var(--fg); background: var(--hover); border-color: var(--line); }

/* ---- chips and pills: <span class="chip">, a small rounded label; .chip.fee0 is the green "0% fees" ---- */
.chip { display: inline-flex; align-items: center; gap: 6px; height: var(--h-sm); padding: 0 10px; border: 1px solid var(--line); border-radius: var(--pill); background: var(--panel); color: var(--muted); font: 500 12px/1 var(--sans); white-space: nowrap; }
.chip.fee0 { color: var(--up); border-color: color-mix(in srgb, var(--up) 35%, transparent); background: color-mix(in srgb, var(--up) 9%, transparent); font-weight: 600; }
/* a 24px stat pill (icon + value), Pulse-card style: <span class="stat-pill"><svg…/>12%</span>, .up / .down colour it */
.stat-pill { display: inline-flex; align-items: center; gap: 4px; height: 24px; padding: 0 8px; border: 1px solid var(--line-soft); border-radius: var(--pill); background: var(--panel); color: var(--fg-2); font: 500 12px/1 var(--mono); font-variant-numeric: tabular-nums; white-space: nowrap; }
.stat-pill.up { color: var(--up); } .stat-pill.down { color: var(--down); }

/* ---- inputs: <input class="input">, <select class="input">, <textarea class="input">; .sm / .lg sizes, .pill for a
     round search field. A filled well with a thin border and an accent ring on focus. ---- */
.input { height: var(--h); min-width: 0; padding: 0 10px; border: 1px solid var(--line); border-radius: 6px; background: var(--panel-2); color: var(--fg); font: 500 12.5px/1 var(--sans); outline: 0; transition: border-color .12s, box-shadow .12s; }
.input:hover { border-color: var(--line-2); }
.input:focus, .input:focus-visible { border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent); outline: 0; }
.input[aria-invalid="true"] { border-color: var(--down); }
.input:disabled { opacity: .5; cursor: not-allowed; }
.input.sm { height: var(--h-sm); padding: 0 8px; font-size: 12px; }
.input.lg { height: var(--h-lg); font-size: 13px; }
.input.pill { border-radius: var(--pill); padding: 0 14px; }
textarea.input { height: auto; min-height: 84px; padding: 8px 10px; font: 12px/1.45 var(--code); resize: vertical; }
select.input { appearance: none; -webkit-appearance: none; padding-right: 28px; cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%), linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: calc(100% - 15px) 55%, calc(100% - 10px) 55%; background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; }
/* a toggle switch: <input type="checkbox" class="switch"> */
.switch { appearance: none; -webkit-appearance: none; position: relative; flex: none; width: 30px; height: 18px; margin: 0; border-radius: var(--pill); background: var(--line-2); cursor: pointer; transition: background-color .15s; }
.switch::before { content: ""; position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 50%; background: var(--muted); transition: transform .15s, background-color .15s; }
.switch:hover { background: color-mix(in srgb, var(--line-2) 80%, var(--fg)); }
.switch:checked { background: var(--accent); }
.switch:checked:hover { background: var(--accent-hover); }
.switch:checked::before { transform: translateX(12px); background: var(--accent-ink); }
.switch:disabled { opacity: .5; cursor: not-allowed; }
@media (prefers-reduced-motion: reduce) { .switch, .switch::before { transition: none; } }

/* a slider: <input type="range" class="range" style="--v:50%">; keep --v at the value's position so the filled part
   shows on every browser */
.range { appearance: none; -webkit-appearance: none; height: 18px; margin: 0; background: none; cursor: pointer; }
.range::-webkit-slider-runnable-track { height: 4px; border-radius: 2px; background: linear-gradient(90deg, var(--accent) var(--v, 0%), var(--line-2) 0); }
.range::-moz-range-track { height: 4px; border-radius: 2px; background: var(--line-2); }
.range::-moz-range-progress { height: 4px; border-radius: 2px; background: var(--accent); }
.range::-webkit-slider-thumb { -webkit-appearance: none; width: 14px; height: 14px; margin-top: -5px; border: 0; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent); }
.range::-moz-range-thumb { width: 14px; height: 14px; border: 0; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent); }
.range:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }

/* ---- segmented controls: <div class="seg" role="group"><button aria-pressed="true">1h</button>…</div>. The options
     sit in one bordered box; the picked one gets the accent tint. .sm is the small size. ---- */
.seg { display: flex; flex-wrap: wrap; width: fit-content; max-width: 100%; gap: 2px; padding: 2px; border: 1px solid var(--line); border-radius: 6px; background: var(--panel); }
.seg button { height: calc(var(--h) - 6px); padding: 0 10px; border: 0; border-radius: 4px; background: none; color: var(--muted); font: 500 12px/1 var(--sans); font-variant-numeric: tabular-nums; transition: background-color .12s, color .12s; }
.seg button:hover { color: var(--fg); background: var(--hover); }
.seg button.on, .seg button[aria-pressed="true"] { color: var(--sel-fg); background: var(--sel-bg); }
.seg.sm button { height: calc(var(--h-sm) - 6px); padding: 0 8px; font-size: 11.5px; }
/* <div class="seg-fill c7"><div class="seg">…</div></div>: the options share the row in equal columns, so a row never
   ends with one lonely button wrapped onto a second line. .two stacks a <small> under the label. */
.seg-fill .seg { display: grid; width: auto; grid-template-columns: repeat(var(--n, 5), minmax(0, 1fr)); gap: 2px; }
.seg-fill.c2 { --n: 2; } .seg-fill.c3 { --n: 3; } .seg-fill.c4 { --n: 4; } .seg-fill.c5 { --n: 5; } .seg-fill.c7 { --n: 7; }
.seg-fill .seg button { min-width: 0; padding: 0 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.seg-fill.two .seg button { height: auto; min-height: 36px; padding: 5px 2px; display: grid; gap: 3px; align-content: center; line-height: 1.1; }
.seg-fill.two .seg button small { font-size: 10px; opacity: .75; }
/* page sub-tabs (Discover, Trackers, Portfolio, Settings on a phone): <nav class="subtabs"><a class="on">Spot <b>12</b></a></nav>.
   Plain grey labels; the open one is white with a 2px underline. */
.subtabs { display: flex; gap: 2px; min-width: 0; overflow-x: auto; scrollbar-width: none; }
.subtabs::-webkit-scrollbar { display: none; }
.subtabs > a, .subtabs > button { position: relative; display: inline-flex; align-items: center; gap: 5px; height: 32px; padding: 0 10px; border: 0; border-radius: 6px; background: none; color: var(--muted); font: 500 13px/1 var(--sans); white-space: nowrap; flex: none; transition: color .12s; }
.subtabs > :hover { color: var(--fg); }
.subtabs > .on { color: var(--fg); }
.subtabs > .on::after { content: ""; position: absolute; left: 10px; right: 10px; bottom: 0; height: 2px; border-radius: 1px; background: var(--fg); }
.subtabs b { color: var(--dim); font: 500 11px/1 var(--mono); }
/* a horizontal scroller that shows a soft shadow at whichever edge hides more: the covers scroll with the content
   (local), the shadows stay put (scroll). Set --hf to the background the row sits on. */
.hfade { --hf: var(--panel); background:
  linear-gradient(90deg, var(--hf) 30%, transparent) left / 24px 100% no-repeat local,
  linear-gradient(270deg, var(--hf) 30%, transparent) right / 24px 100% no-repeat local,
  radial-gradient(farthest-side at 0 50%, color-mix(in srgb, var(--fg) 16%, transparent), transparent) left / 10px 100% no-repeat scroll,
  radial-gradient(farthest-side at 100% 50%, color-mix(in srgb, var(--fg) 16%, transparent), transparent) right / 10px 100% no-repeat scroll,
  var(--hf); }
/* a section or stat label; the value under it uses the number face */
.eyebrow { font: 500 11px/1.2 var(--sans); letter-spacing: .04em; text-transform: uppercase; color: var(--muted); }
.row-end { display: flex; justify-content: flex-end; gap: 8px; }
:where(.flag) { flex: none; padding: 1px 5px; border-radius: 4px; border: 1px solid var(--line-2); color: var(--muted); font: 600 10px/1.3 var(--sans); letter-spacing: .02em; text-transform: uppercase; }
:where(.flag.down) { color: var(--down); border-color: color-mix(in srgb, var(--down) 40%, transparent); }
/* a hover tooltip for a short label: <button data-tip="Copy address">. Not for elements that already use ::after. */
:where([data-tip]) { position: relative; }
[data-tip]:hover::after, [data-tip]:focus-visible::after { content: attr(data-tip); position: absolute; bottom: calc(100% + 6px); left: 50%; z-index: 60; transform: translateX(-50%); padding: 5px 8px; border: 1px solid var(--line-2); border-radius: 6px; background: var(--panel-2); box-shadow: var(--shadow); color: var(--fg); font: 500 11.5px/1.3 var(--sans); letter-spacing: 0; text-transform: none; white-space: nowrap; pointer-events: none; }
[data-tip][data-tip-pos="bottom"]:hover::after, [data-tip][data-tip-pos="bottom"]:focus-visible::after { bottom: auto; top: calc(100% + 6px); }
@media (hover: none) { [data-tip]:hover::after { display: none; } }

/* ---- coins: the avatar (card.js avatar()), the quick-buy button, and the name / age / socials bits that coin rows
   are built from. The coin card itself (.card.nc) is styled in css/pulse.css. ---- */
.av { width: 52px; height: 52px; border-radius: var(--radius); background: var(--panel-2); border: 1px solid var(--line-2); overflow: hidden; display: grid; place-items: center; font: 600 15px/1 var(--sans); color: var(--muted); position: relative; }
.av img { width: 100%; height: 100%; object-fit: cover; display: block; }
.av .ring { position: absolute; inset: auto 0 0 0; height: 3px; background: var(--line-2); }
.av .ring i { display: block; height: 100%; background: var(--accent); }
.av.sm { width: 32px; height: 32px; border-radius: 3px; font-size: 11px; flex: none; }
/* quick buy: blue text with a bolt, no fill until hovered; .fill is the solid blue "Buy 1 SOL" pill */
.qb { display: inline-flex; align-items: center; justify-content: center; gap: 4px; height: 26px; padding: 0 10px; border-radius: var(--pill); border: 1px solid transparent; background: none; color: var(--accent); font: 600 12px/1 var(--mono); font-variant-numeric: tabular-nums; white-space: nowrap; transition: background-color .12s, border-color .12s, color .12s; }
.qb:hover { background: var(--sel-bg); border-color: var(--sel-line); }
.qb.fill { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); font-weight: 700; }
.qb.fill:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.card.fresh { animation: fresh 1.4s ease-out; }
@keyframes fresh { from { background: color-mix(in srgb, var(--accent) 14%, transparent); } to { background: transparent; } }
:where(.l1) { display: flex; align-items: baseline; gap: 7px; min-width: 0; }
:where(.l2) { display: flex; align-items: center; gap: 10px; color: var(--muted); font-size: 11.5px; min-width: 0; white-space: nowrap; }
:where(.sym) { font-weight: 600; font-size: 14px; letter-spacing: -.01em; white-space: nowrap; }
:where(.nm) { color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
:where(.copy) { flex: none; color: var(--dim); background: none; border: 0; padding: 0; line-height: 0; }
:where(.copy):hover { color: var(--fg); }
:where(.age) { color: var(--up); font-family: var(--mono); font-weight: 500; }
:where(.soc) { display: inline-flex; gap: 6px; }
:where(.soc) a { color: var(--dim); line-height: 0; }
:where(.soc) a:hover { color: var(--fg); }

/* ---- empty and loading states ----
   .empty-state: <div class="empty-state"><span class="es-ic">ICON</span><h3>Title</h3><p>Body</p>
     <ol class="es-steps"><li>…</li></ol><div class="es-acts"><button class="btn btn-accent">…</button></div></div>
   A centred line icon over grey text. .skel: a shimmering placeholder block (size it inline or with a page class);
   still under reduced motion. :where(.empty) is the older one-liner (the router's error text uses it):
   <div class="empty"><b>Title</b><span>…</span></div> */
.empty-state { display: grid; justify-items: center; gap: 10px; max-width: 470px; margin: 0 auto; padding: 48px 20px; text-align: center; color: var(--muted); font-size: 12.5px; line-height: 1.55; }
.empty-state .es-ic { display: grid; place-items: center; width: 48px; height: 48px; color: var(--dim); }
.empty-state .es-ic svg { width: 34px; height: 34px; }
.empty-state h3 { margin: 2px 0 0; color: var(--fg-2); font: 500 14px/1.3 var(--sans); }
.empty-state p { margin: 0; }
.empty-state .es-acts { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 4px; }
.empty-state .es-steps { display: grid; gap: 6px; margin: 6px 0 0; padding: 0; list-style: none; text-align: left; counter-reset: s; }
.empty-state .es-steps li { display: flex; gap: 8px; }
.empty-state .es-steps li::before { counter-increment: s; content: counter(s); flex: none; display: grid; place-items: center; width: 18px; height: 18px; border-radius: 50%; background: var(--fill); color: var(--fg-2); font: 600 10px/1 var(--sans); }
.empty-state a:not(.btn) { color: var(--accent); }
.skel { display: block; border-radius: var(--radius); background: linear-gradient(90deg, var(--panel-2) 0 40%, color-mix(in srgb, var(--panel-2) 50%, var(--line-2)) 50%, var(--panel-2) 60% 100%); background-size: 250% 100%; animation: skel 1.3s linear infinite; }
@keyframes skel { from { background-position: 100% 0; } to { background-position: -150% 0; } }
@media (prefers-reduced-motion: reduce) { .skel { animation: none; } }
:where(.empty) { display: grid; gap: 8px; justify-items: center; max-width: 470px; margin: 0 auto; padding: 40px 18px; color: var(--muted); text-align: center; font-size: 12.5px; line-height: 1.55; }
:where(.empty) > b { color: var(--fg-2); font: 500 14px/1.3 var(--sans); }
:where(.pulse-dot) { display: inline-block; flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); animation: blink 1.2s infinite; }
@keyframes blink { 50% { opacity: .25; } }

/* ---- touch screens: every small control gets a finger-sized hit area ---- */
@media (pointer: coarse) { .seg button, .btn.sm, .qb { min-height: 32px; } }

/* ---- dialogs and toasts ---- */
dialog { padding: 0; border: 1px solid var(--line-2); border-radius: var(--radius-lg); background: var(--panel); box-shadow: var(--shadow-lg); color: var(--fg); width: min(440px, calc(100vw - 32px)); }
dialog::backdrop { background: var(--backdrop); backdrop-filter: blur(2px); }
.dlg { display: grid; gap: 16px; padding: 20px; }
.dlg h2 { margin: 0; font: 600 16px/1.2 var(--sans); }
.dlg p { margin: 0; }
.dlg h2[tabindex="-1"]:focus { outline: 0; } /* the picker focuses its title on open instead of the first wallet row */
.dlg label { display: grid; gap: 8px; font-weight: 500; font-size: 12.5px; }
.dlg .hint { color: var(--muted); font-weight: 400; font-size: 12px; }
.dlg input:where(:not([type="checkbox"], [type="radio"], [type="range"], [type="color"], [type="file"])) { height: 36px; padding: 0 11px; border: 1px solid var(--line); border-radius: 6px; background: var(--panel-2); font: 500 12.5px var(--mono); outline: 0; transition: border-color .12s, box-shadow .12s; }
.dlg input:where(:not([type="checkbox"], [type="radio"], [type="range"], [type="color"], [type="file"])):focus { border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent); }
.dlg hr { border: 0; border-top: 1px solid var(--line); margin: 2px 0; width: 100%; }
.dlg .check { display: flex; align-items: center; gap: 9px; font-weight: 500; }
.dlg .check input { width: 16px; height: 16px; accent-color: var(--accent); }
.dlg-body { display: grid; gap: 16px; }
.dlg-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.dlg-link { color: var(--accent); font-size: 12px; font-weight: 500; }
.dlg-link:hover { color: var(--accent-hover); }
/* P1 / P2 / P3 in the preset dialog: tabs in one box, the open one tinted */
.pre-tabs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2px; padding: 2px; border: 1px solid var(--line); border-radius: var(--radius-md); background: var(--bg); }
.pre-tabs button { height: 30px; border: 0; border-radius: 6px; background: none; color: var(--muted); font: 600 12.5px/1 var(--sans); }
.pre-tabs button:hover { color: var(--fg); }
.pre-tabs button.on { background: var(--sel-bg); color: var(--sel-fg); }
.wallet-list { display: grid; gap: 6px; }
.wallet-list button { display: flex; align-items: center; gap: 11px; height: 48px; padding: 0 12px; border-radius: var(--radius-md); border: 1px solid var(--line); background: var(--panel-2); font-weight: 600; text-align: left; white-space: nowrap; transition: border-color .12s, background-color .12s; }
.wallet-list button:hover { border-color: var(--sel-line); background: color-mix(in srgb, var(--accent) 6%, var(--panel-2)); }
.wallet-list small { margin-left: auto; min-width: 0; color: var(--muted); font-weight: 400; font-size: 11.5px; line-height: 1.3; text-align: right; white-space: normal; } /* the name keeps one line; a long hint wraps */
/* src/ui/shell.js adds the initial tile and marks the Install / Detected labels */
.wallet-list .wl-ic { flex: none; display: grid; place-items: center; width: 24px; height: 24px; border-radius: 6px; border: 1px solid var(--line-2); background: var(--panel); color: var(--fg); font: 700 11.5px/1 var(--sans); }
.wallet-list .wl-ic.local { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 40%, transparent); background: color-mix(in srgb, var(--warn) 9%, transparent); }
.wallet-list small.wl-install { flex: none; white-space: nowrap; padding: 4px 9px; border-radius: var(--pill); background: var(--sel-bg); color: var(--sel-fg); font-weight: 600; }
.wallet-list small.wl-ok { color: var(--up); font-weight: 600; }
/* toasts: compact dark cards; .ok and .err get a status dot. The text flows inline ("Tracking <b>name</b>"); a
   structured toast stacks <span class="t-title">, <span class="t-sub"> and <div class="t-acts"> (css/shell.css). */
.toasts { position: fixed; right: 16px; bottom: 44px; display: grid; gap: 6px; z-index: 50; width: min(340px, calc(100vw - 32px)); }
.toast { position: relative; padding: 10px 12px; border-radius: var(--radius-md); border: 1px solid var(--line-2); background: var(--panel-2); box-shadow: var(--shadow); color: var(--fg); font-size: 12px; line-height: 1.45; animation: tin .18s ease-out; overflow-wrap: anywhere; }
.toast :where(.t-title, .t-sub) { display: block; }
.toast :where(.t-sub) { margin-top: 2px; }
.toast.ok, .toast.err { padding-left: 28px; }
.toast.ok::before, .toast.err::before { content: ""; position: absolute; left: 12px; top: 15px; width: 7px; height: 7px; border-radius: 50%; background: var(--up); box-shadow: 0 0 0 3px color-mix(in srgb, var(--up) 22%, transparent); }
.toast.err::before { background: var(--down); box-shadow: 0 0 0 3px color-mix(in srgb, var(--down) 22%, transparent); }
.toast.err { border-color: color-mix(in srgb, var(--down) 35%, var(--line-2)); }
.toast a { color: var(--accent); font-weight: 500; }
@keyframes tin { from { transform: translateY(6px); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .toast { animation: none; } }
