/* =====================================================================
   Tree News - app.css  (design system, dark-first)
   ---------------------------------------------------------------------
   Single stylesheet for the live pages (index, settings, account,
   leaderboard, claim, tos). Replaces page.css / account.css / theme.css
   and the DarkReader runtime. Light theme is opt-in through
   <html data-theme="light">.

   Sections
     0. Tokens (dark root, light override, legacy --tn-* aliases)
     1. Base (reset, typography, scrollbars, selection, focus, links)
     2. Utilities
     3. Shell (app grid, topbar, rail, bottom tab bar, main)
     4. Buttons
     5. Inputs (input, select, search, switch, segmented, textarea)
     6. Chips, tags, badges, status, avatar
     7. Surfaces (card, section-title, divider, kv, table, empty,
        spinner, loader, alert, skeleton)
     8. Overlays (modal, drawer, dropdown, tabs, toolbar)
     9. Feed (home: columns, news rows, votes, events)
    10. Settings page
    11. Account / leaderboard / claim
    12. Page misc (titles, prose)
    13. Responsive
    14. Motion
   ===================================================================== */

/* ---------------------------------------------------------------------
   0. TOKENS
   --------------------------------------------------------------------- */
:root {
    color-scheme: dark;

    /* surfaces, deepest first: the page behind the panels, the panels (columns, cards), then raised steps. Cool
       near-blacks so the green and the prices glow; elevation is lightness, never a different hue. */
    --bg: #07080a;
    --surface: #0e1013;
    --surface-2: #15181c;
    --surface-3: #1d2025;
    --surface-hover: #121418;
    --surface-raised: #171a1f;   /* floating layers (menus, panels, dialogs) */
    --surface-glass: rgba(9, 10, 12, 0.78);   /* the top bar: the page shows through, blurred */

    /* lines: quiet separators and control borders */
    --border: #1e2127;
    --border-strong: #2d3139;
    --border-glow: rgba(255, 255, 255, 0.06);   /* the 1px top highlight on raised layers */

    /* text: every step clears 4.5:1 on every surface */
    --text: #f3f5f8;
    --text-muted: #aeb4bf;
    --text-faint: #8d94a1;
    --text-on-accent: #03140a;

    /* brand: the logo's green (luminous on black) */
    --accent: #3ddc7a;
    --accent-hover: #5ae690;
    --accent-soft: rgba(61, 220, 122, 0.13);
    --accent-text: #5fe394;
    --accent-glow: rgba(61, 220, 122, 0.35);
    /* price: the exchanges' teal-green up and coral-red down (the only place green and red mean "price") */
    --up: #16c784;
    --up-soft: rgba(22, 199, 132, 0.14);
    --down: #f6465d;
    --down-soft: rgba(246, 70, 93, 0.14);
    --danger: #f6465d;
    --danger-soft: rgba(246, 70, 93, 0.14);
    --warn: #ff8f4a;
    --warn-soft: rgba(255, 143, 74, 0.14);
    /* Big: gold, for the day's biggest stories only */
    --big: #f7b53b;
    --big-text: #2a1803;
    --big-soft: rgba(247, 181, 59, 0.085);
    --big-glow: rgba(247, 181, 59, 0.28);
    /* yours: follows, your own sources */
    --info: #5eaaff;
    --info-soft: rgba(94, 170, 255, 0.14);
    --focus: 0 0 0 3px rgba(61, 220, 122, 0.35);

    /* ---- feed surface helpers (the row's left bar marks a state: Big, followed, yours, open; never the source) */
    --row-bar-w: 2px;
    --feed-scroll-thumb: rgba(255, 255, 255, 0.10);
    --feed-scroll-thumb-hover: rgba(255, 255, 255, 0.20);
    --pct-flat-bg: var(--surface-2);
    --shimmer-band: rgba(255, 255, 255, 0.06);
    --tint-8: rgba(255, 255, 255, 0.045);
    /* the atmosphere behind the panels: a faint green light from the top left */
    --page-glow: none;

    /* type: Geist for words, Geist Mono for every number (times, prices, moves, counts) and code. One family, two cuts:
       the terminal feel comes from the figures, the reading comfort from the sans. */
    --font-ui: 'Geist', 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    --font-mono: 'Geist Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
    --font-code: var(--font-mono);
    --fs-xs: 11px;
    --fs-sm: 12px;
    --fs-md: 13px;
    --fs-base: 14px;
    --fs-lg: 15px;
    --fs-xl: 18px;
    --fs-2xl: 22px;
    --fs-3xl: 28px;
    --lh: 1.45;

    /* shape */
    --radius-sm: 4px;
    --radius-md: 8px;
    --radius-lg: 12px;
    --radius-panel: 12px;       /* the feed columns and page cards */
    --radius-pill: 999px;
    --radius-control: 7px;      /* buttons, inputs, selects, segmented controls */

    /* control heights: sm in bars (top bar, feed toolbar, menus), md in forms (the default), lg for big calls to action */
    --control-h-sm: 30px;
    --control-h-md: 34px;
    --control-h-lg: 42px;
    --chip-h-sm: 20px;          /* chips in rows, column headers, menus */
    --chip-h-md: 24px;          /* chips in bars */

    /* depth: a hairline of light on top, a soft long shadow below */
    --shadow-1: 0 1px 0 rgba(255, 255, 255, 0.035) inset, 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-2: 0 1px 0 rgba(255, 255, 255, 0.05) inset, 0 12px 32px rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(0, 0, 0, 0.4);
    --shadow-3: 0 1px 0 rgba(255, 255, 255, 0.06) inset, 0 24px 64px rgba(0, 0, 0, 0.7), 0 0 0 1px rgba(0, 0, 0, 0.5);
    --shadow-panel: 0 1px 0 rgba(255, 255, 255, 0.03) inset, 0 8px 24px rgba(0, 0, 0, 0.35);

    /* spacing */
    --sp-1: 4px;
    --sp-2: 8px;
    --sp-3: 12px;
    --sp-4: 16px;
    --sp-5: 20px;
    --sp-6: 24px;
    --sp-8: 32px;

    /* layout */
    --topbar-h: 52px;
    --rail-w: 60px;
    --rail-w-open: 224px;
    --rail-ease: 140ms cubic-bezier(0.2, 0.7, 0.2, 1);
    --bottombar-h: 58px;
    --content-max: 1280px;
    --content-narrow: 880px;
    --gutter: 8px;              /* the gap between panels (and around them) */

    /* z-index */
    --z-rail: 90;
    --z-topbar: 100;
    --z-dropdown: 110;
    --z-drawer: 120;
    --z-modal: 1000;
    --z-toast: 2000;

    /* motion */
    --ease: 160ms cubic-bezier(0.2, 0.7, 0.2, 1);
    --ease-slow: 260ms cubic-bezier(0.2, 0.7, 0.2, 1);

    /* ---- legacy aliases (inline styles in JSX may still use --tn-*) */
    --tn-bg: var(--bg);
    --tn-surface: var(--surface);
    --tn-surface-2: var(--surface-2);
    --tn-surface-3: var(--surface-3);
    --tn-border: var(--border);
    --tn-border-strong: var(--border-strong);
    --tn-text: var(--text);
    --tn-text-muted: var(--text-muted);
    --tn-text-faint: var(--text-faint);
    --tn-accent: var(--accent);
    --tn-accent-soft: var(--accent-soft);
    --tn-accent-hover: var(--accent-hover);
    --tn-warn: var(--warn);
    --tn-warn-soft: var(--warn-soft);
    --tn-warn-text: var(--warn);
    --tn-danger: var(--danger);
    --tn-danger-soft: var(--danger-soft);
    --tn-success: var(--up);
    --tn-info: var(--info);
    --tn-radius-sm: var(--radius-sm);
    --tn-radius-md: var(--radius-md);
    --tn-radius-lg: var(--radius-lg);
    --tn-radius-pill: var(--radius-pill);
    --tn-shadow-1: var(--shadow-1);
    --tn-shadow-2: var(--shadow-2);
    --tn-focus: var(--focus);
    --tn-ease: var(--ease);
    --tn-line-height: var(--lh);
    --colorBasePrimary: var(--bg);
    --colorTextPrimary: var(--text);
    --colorfulSignaturePrimary: var(--accent);
    --colorfulSignatureTransparent: var(--accent-soft);
}

:root[data-theme="light"] {
    color-scheme: light;

    /* paper: white panels on a cool light grey page */
    --bg: #eef0f3;
    --surface: #ffffff;
    --surface-2: #f3f4f6;
    --surface-3: #e8eaee;
    --surface-hover: #f7f8fa;
    --surface-raised: #ffffff;
    --surface-glass: rgba(246, 247, 249, 0.8);

    --border: #e6e8ec;
    --border-strong: #d2d6dd;
    --border-glow: rgba(255, 255, 255, 0.9);

    --text: #0e1116;
    --text-muted: #4a515c;
    --text-faint: #636a76;
    --text-on-accent: #ffffff;

    /* the brand green, deep enough for white text (5:1) */
    --accent: #0f7f3c;
    --accent-hover: #0c6c33;
    --accent-soft: rgba(15, 127, 60, 0.10);
    --accent-text: #0f7f3c;
    --accent-glow: rgba(15, 127, 60, 0.22);
    --up: #087f53;
    --up-soft: rgba(8, 127, 83, 0.10);
    --down: #d42a42;
    --down-soft: rgba(212, 42, 66, 0.09);
    --danger: #d42a42;
    --danger-soft: rgba(212, 42, 66, 0.09);
    --warn: #b4460b;
    --warn-soft: rgba(255, 120, 40, 0.12);
    --big: #f2a91f;
    --big-text: #2a1803;
    --big-soft: rgba(242, 169, 31, 0.14);
    --big-glow: rgba(242, 169, 31, 0.30);
    --info: #0b6bcb;
    --info-soft: rgba(11, 107, 203, 0.10);
    --focus: 0 0 0 3px rgba(15, 127, 60, 0.25);

    --shadow-1: 0 1px 2px rgba(15, 20, 30, 0.06);
    --shadow-2: 0 12px 32px rgba(15, 20, 30, 0.12), 0 0 0 1px rgba(15, 20, 30, 0.04);
    --shadow-3: 0 24px 64px rgba(15, 20, 30, 0.18), 0 0 0 1px rgba(15, 20, 30, 0.05);
    --shadow-panel: 0 1px 2px rgba(15, 20, 30, 0.05), 0 4px 16px rgba(15, 20, 30, 0.04);

    --feed-scroll-thumb: rgba(0, 0, 0, 0.16);
    --feed-scroll-thumb-hover: rgba(0, 0, 0, 0.28);
    --shimmer-band: rgba(0, 0, 0, 0.05);
    --tint-8: rgba(0, 0, 0, 0.04);
    --page-glow: none;
}

/* ---------------------------------------------------------------------
   1. BASE
   --------------------------------------------------------------------- */
*,
*::before,
*::after {
    box-sizing: border-box;
}

html {
    height: 100%;
    -webkit-text-size-adjust: 100%;
    scrollbar-width: thin;
    scrollbar-color: var(--surface-3) transparent;
}

html,
body {
    margin: 0;
    padding: 0;
    background: var(--bg);
    color: var(--text);
    font-family: var(--font-ui);
    font-size: var(--fs-base);
    line-height: var(--lh);
    font-weight: 400;
    /* tabular figures everywhere: prices, times and counts line up */
    font-variant-numeric: tabular-nums;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
}

body {
    min-height: 100%;
    /* the atmosphere: a faint green light from the top left, behind every panel */
    background: var(--page-glow), var(--bg);
    background-attachment: fixed;
}

#root {
    min-height: 100vh;
}

h1, h2, h3, h4, h5, h6, p, ul, ol, li, figure, blockquote, dl, dd {
    margin: 0;
    padding: 0;
}

ul, ol {
    list-style: none;
}

img, svg, video {
    max-width: 100%;
    display: inline-block;
    vertical-align: middle;
}

a {
    color: inherit;
    text-decoration: none;
    transition: color var(--ease);
}

a:hover {
    color: var(--accent-hover);
}

button, input, select, textarea {
    font: inherit;
    color: inherit;
    margin: 0;
}

button {
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
}

button:disabled {
    cursor: not-allowed;
}

hr {
    border: 0;
    border-top: 1px solid var(--border);
    margin: var(--sp-4) 0;
}

code, pre, kbd, samp {
    font-family: var(--font-code);
    font-size: 0.92em;
}

::selection {
    background: rgba(61, 220, 122, 0.28);
    color: var(--text);
}

:focus {
    outline: none;
}

:focus-visible {
    outline: none;
    box-shadow: var(--focus);
    border-radius: var(--radius-sm);
}

/* scrollbars (WebKit) */
::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}

::-webkit-scrollbar-track {
    background: transparent;
}

::-webkit-scrollbar-thumb {
    background: var(--surface-3);
    border-radius: var(--radius-pill);
    border: 2px solid transparent;
    background-clip: padding-box;
}

::-webkit-scrollbar-thumb:hover {
    background: var(--border-strong);
    background-clip: padding-box;
    border: 2px solid transparent;
}

::-webkit-scrollbar-corner {
    background: transparent;
}

/* number inputs: no spinners */
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

input[type="number"] {
    -moz-appearance: textfield;
}

/* ---------------------------------------------------------------------
   2. UTILITIES
   --------------------------------------------------------------------- */
.row { display: flex; flex-direction: row; align-items: center; }
.col { display: flex; flex-direction: column; }
.center { justify-content: center; align-items: center; }
.between { justify-content: space-between; }
.end { justify-content: flex-end; }
.start { align-items: flex-start; }
.wrap { flex-wrap: wrap; }
.grow { flex: 1 1 auto; min-width: 0; }
.shrink-0 { flex-shrink: 0; }

.gap-1 { gap: var(--sp-1); }
.gap-2 { gap: var(--sp-2); }
.gap-3 { gap: var(--sp-3); }
.gap-4 { gap: var(--sp-4); }
.gap-6 { gap: var(--sp-6); }

.p-1 { padding: var(--sp-1); }
.p-2 { padding: var(--sp-2); }
.p-3 { padding: var(--sp-3); }
.p-4 { padding: var(--sp-4); }
.px-3 { padding-left: var(--sp-3); padding-right: var(--sp-3); }
.py-2 { padding-top: var(--sp-2); padding-bottom: var(--sp-2); }
.mt-2 { margin-top: var(--sp-2); }
.mt-3 { margin-top: var(--sp-3); }
.mt-4 { margin-top: var(--sp-4); }
.mb-2 { margin-bottom: var(--sp-2); }
.mb-3 { margin-bottom: var(--sp-3); }
.mb-4 { margin-bottom: var(--sp-4); }
.ml-auto { margin-left: auto; }

.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
.tabular { font-variant-numeric: tabular-nums; }
.muted { color: var(--text-muted); }
.faint { color: var(--text-faint); }
.accent { color: var(--accent-text); }
.up { color: var(--up); }
.down { color: var(--down); }
.warn { color: var(--warn); }
.info { color: var(--info); }
.small { font-size: var(--fs-sm); }
.xs { font-size: var(--fs-xs); }
.strong { font-weight: 600; }
.upper { text-transform: uppercase; letter-spacing: 0.06em; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.clamp-2 { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.pointer { cursor: pointer; }
.no-select { user-select: none; -webkit-user-select: none; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
.relative { position: relative; }
.w-full { width: 100%; }
.scroll-y { overflow-y: auto; min-height: 0; }
.scroll-x { overflow-x: auto; }

/* .only-sm / .only-md: shown only at <=700px / <=1100px (hidden above, see section 13) */

/* ---------------------------------------------------------------------
   3. SHELL
   --------------------------------------------------------------------- */
.app {
    min-height: 100vh;
    background: transparent;
}

/* topbar ------------------------------------------------------------- */
.topbar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: var(--topbar-h);
    z-index: var(--z-topbar);
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--sp-3);
    padding: 0 var(--sp-3) 0 var(--sp-3);
    /* glass: the page's glow shows through, blurred */
    background: var(--surface-glass);
    -webkit-backdrop-filter: blur(18px) saturate(1.5);
    backdrop-filter: blur(18px) saturate(1.5);
    border-bottom: 1px solid var(--border);
}

.topbar-left,
.topbar-right {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    min-width: 0;
}

.topbar-center {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 0;
}

.topbar-center > * {
    max-width: 560px;
    width: 100%;
}

.topbar-right {
    justify-content: flex-end;
}

.brand {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    padding: 4px 8px 4px 4px;
    border-radius: var(--radius-md);
    color: var(--text);
    font-weight: 600;
    font-size: 16px;
    letter-spacing: -0.015em;
    white-space: nowrap;
}

.brand:hover {
    color: var(--text);
    background: var(--surface-2);
}

.brand-logo {
    width: 28px;
    height: 28px;
    border-radius: 8px;
    object-fit: cover;
    flex: 0 0 28px;
    /* the mark glows a little, like a status light */
    box-shadow: 0 0 0 1px rgba(61, 220, 122, 0.28), 0 0 18px rgba(61, 220, 122, 0.22);
}

.brand-title {
    font-weight: 600;
}

.brand-sub {
    font-size: var(--fs-xs);
    color: var(--text-faint);
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    margin-left: 2px;
}

/* user pill */
.user-pill {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    height: var(--control-h-md);
    padding: 0 10px 0 4px;
    border-radius: var(--radius-pill);
    border: 1px solid var(--border);
    background: var(--surface-2);
    max-width: 260px;
    min-width: 0;
}

.user-pill .avatar {
    flex: 0 0 auto;
}

.user-pill-name {
    font-size: var(--fs-md);
    font-weight: 500;
    line-height: 1.1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.user-pill-sub {
    font-size: var(--fs-xs);
    color: var(--text-muted);
    line-height: 1.1;
}

.user-pill-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
    gap: 1px;
}

/* the pill is the account menu's button */
button.user-pill {
    font: inherit;
    color: var(--text);
    text-align: left;
    cursor: pointer;
    transition: background var(--ease), border-color var(--ease);
}

button.user-pill:hover {
    background: var(--surface-3);
    border-color: var(--border-strong);
}

.user-pill-caret {
    margin-left: 2px;
    font-size: 10px;
    color: var(--text-faint);
}

/* rail --------------------------------------------------------------- */
/* Always the floating variant: 56px icon rail fixed on the left; on hover
   or keyboard focus it widens to 220px as an OVERLAY above .app-main
   (which keeps its 56px padding-left). */
.rail {
    position: fixed;
    top: var(--topbar-h);
    left: 0;
    bottom: 0;
    width: var(--rail-w);
    z-index: var(--z-rail);
    display: flex;
    flex-direction: column;
    /* the rail sits on the page itself; opened, it becomes a raised sheet over the panels */
    background: transparent;
    border-right: 1px solid transparent;
    overflow: hidden;
    box-shadow: none;
    transition: width var(--rail-ease), box-shadow var(--rail-ease), background var(--rail-ease), border-color var(--rail-ease);
}

.rail:hover,
.rail:focus-within {
    width: var(--rail-w-open);
    background: var(--surface-raised);
    border-right-color: var(--border-strong);
    box-shadow: 12px 0 40px rgba(0, 0, 0, 0.45);
}

:root[data-theme="light"] .rail:hover,
:root[data-theme="light"] .rail:focus-within {
    box-shadow: 6px 0 24px rgba(16, 20, 24, 0.10);
}

.rail-nav {
    display: flex;
    flex-direction: column;
    padding: var(--sp-2) 0;
    gap: 2px;
}

.rail-item {
    position: relative;
    display: flex;
    align-items: center;
    gap: 14px;
    height: 40px;
    margin: 0 var(--sp-2);
    padding: 0 0 0 9px;
    border-radius: var(--radius-md);
    color: var(--text-muted);
    font-size: var(--fs-base);
    font-weight: 500;
    white-space: nowrap;
    cursor: pointer;
    user-select: none;
    transition: background var(--ease), color var(--ease);
    width: calc(100% - var(--sp-2) * 2);
    text-align: left;
}

.rail-item:hover {
    background: var(--surface-2);
    color: var(--text);
}

.rail-item.active {
    color: var(--text);
    background: var(--surface-2);
    box-shadow: inset 0 0 0 1px var(--border);
}

.rail-item.active::before {
    content: "";
    position: absolute;
    left: -8px;
    top: 9px;
    bottom: 9px;
    width: 3px;
    border-radius: 0 3px 3px 0;
    background: var(--accent);
}

.rail-item.active .rail-icon {
    color: var(--accent-text);
}

.rail-item.active .rail-icon {
    color: var(--text);
}

.rail-icon {
    width: 22px;
    flex: 0 0 22px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 16px;
    color: inherit;
}

/* something to do there (a subscriber not in the Discord yet): a small dot on the icon */
.rail-item.has-dot .rail-icon {
    position: relative;
}

.rail-item.has-dot .rail-icon::after {
    content: "";
    position: absolute;
    top: -1px;
    right: -1px;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--accent);
    box-shadow: 0 0 0 2px var(--surface);
}

.rail-label {
    opacity: 0;
    transform: translateX(-4px);
    transition: opacity var(--rail-ease), transform var(--rail-ease);
    overflow: hidden;
    text-overflow: ellipsis;
}

.rail:hover .rail-label,
.rail:focus-within .rail-label {
    opacity: 1;
    transform: none;
}

.rail-item-right {
    margin-left: auto;
    margin-right: 10px;
    opacity: 0;
    transition: opacity var(--rail-ease);
}

.rail:hover .rail-item-right,
.rail:focus-within .rail-item-right {
    opacity: 1;
}

.rail-group-title {
    font-size: var(--fs-xs);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-faint);
    padding: 12px 18px 4px;
    white-space: nowrap;
    opacity: 0;
    transition: opacity var(--rail-ease);
}

.rail:hover .rail-group-title,
.rail:focus-within .rail-group-title {
    opacity: 1;
}

/* the rail's outside links, opened in place under "More links" */
.rail-more-group {
    display: flex;
    flex-direction: column;
}

.rail-extra {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    padding-bottom: var(--sp-2);
}

.rail-footer {
    margin-top: auto;
    border-top: 1px solid transparent;
    padding: var(--sp-2) 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

/* main --------------------------------------------------------------- */
.app-main {
    padding-top: var(--topbar-h);
    padding-left: var(--rail-w);
    min-height: 100vh;
}

.app-main.is-padded .page-container {
    padding: var(--sp-5) var(--sp-6) var(--sp-8);
}

.page-container {
    width: 100%;
    max-width: var(--content-max);
    margin: 0 auto;
}

.page-container.narrow {
    max-width: var(--content-narrow);
}

.page-container.full {
    max-width: none;
}

.app-main.is-full {
    height: 100vh;
    height: 100dvh;
    min-height: 0;
    overflow: hidden;
}

.app-main.is-full > * {
    height: 100%;
}

/* status dot / pill */
.status-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: var(--control-h-sm);
    padding: 0 10px 0 8px;
    border-radius: var(--radius-pill);
    border: 1px solid var(--border);
    background: var(--surface-2);
    font-size: var(--fs-sm);
    color: var(--text-muted);
    white-space: nowrap;
    max-width: 100%;
    min-width: 0;
    box-sizing: border-box;
}

.status-pill-label {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.status-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--text-faint);
    flex: 0 0 8px;
    position: relative;
}

.status-dot.live {
    background: var(--up);
}

.status-dot.down,
.status-dot.off {
    background: var(--down);
}

.status-dot.warn {
    background: var(--warn);
}

/* ---------------------------------------------------------------------
   4. BUTTONS
   --------------------------------------------------------------------- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: var(--control-h-md);
    padding: 0 12px;
    border-radius: var(--radius-control);
    border: 1px solid var(--border-strong);
    background: var(--surface-2);
    color: var(--text);
    font-size: var(--fs-md);
    font-weight: 500;
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    user-select: none;
    text-decoration: none;
    transition: background var(--ease), border-color var(--ease), color var(--ease), opacity var(--ease);
}

.btn:hover {
    background: var(--surface-3);
    color: var(--text);
}

.btn:active {
    transform: translateY(0.5px);
}

.btn:disabled,
.btn.is-disabled {
    opacity: 0.5;
    cursor: not-allowed;
    pointer-events: none;
}

.btn i {
    font-size: 13px;
}

.btn-sm i {
    font-size: 12px;
}

.btn-primary {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--text-on-accent);
    font-weight: 600;
}

.btn-primary:hover {
    background-color: var(--accent-hover);
    border-color: var(--accent-hover);
    color: var(--text-on-accent);
}

.btn-ghost {
    background: transparent;
    border-color: transparent;
    color: var(--text-muted);
}

.btn-ghost:hover {
    background: var(--surface-2);
    color: var(--text);
}

.btn-outline {
    background: transparent;
}

.btn-danger {
    background: var(--danger-soft);
    border-color: rgba(229, 72, 77, 0.35);
    color: var(--down);
}

.btn-danger:hover {
    background: var(--danger);
    border-color: var(--danger);
    color: #fff;
}

.btn-accent-soft {
    background: var(--accent-soft);
    border-color: transparent;
    color: var(--accent-text);
}

.btn-accent-soft:hover {
    background: var(--accent);
    color: var(--text-on-accent);
}

.btn-sm {
    height: var(--control-h-sm);
    padding: 0 10px;
    font-size: var(--fs-sm);
}

.btn-lg {
    height: var(--control-h-lg);
    padding: 0 18px;
    font-size: var(--fs-base);
}

.btn-block {
    width: 100%;
}

.btn.is-loading {
    pointer-events: none;
    opacity: 0.8;
}

.btn-group {
    display: inline-flex;
}

.btn-group .btn {
    border-radius: 0;
}

.btn-group .btn:first-child {
    border-radius: var(--radius-control) 0 0 var(--radius-control);
}

.btn-group .btn:last-child {
    border-radius: 0 var(--radius-control) var(--radius-control) 0;
}

.btn-group .btn + .btn {
    margin-left: -1px;
}

.icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--control-h-md);
    height: var(--control-h-md);
    flex: 0 0 var(--control-h-md);
    border-radius: var(--radius-control);
    border: 1px solid transparent;
    background: transparent;
    color: var(--text-muted);
    font-size: 14px;
    cursor: pointer;
    transition: background var(--ease), color var(--ease), border-color var(--ease);
}

.icon-btn:hover {
    background: var(--surface-2);
    color: var(--text);
}

.icon-btn.active,
.icon-btn.is-active {
    background: var(--accent-soft);
    color: var(--accent-text);
}

.icon-btn.is-bordered {
    border-color: transparent;
    background: transparent;
}

/* a bordered icon button shows hover and "on" like every other control (the rule above used to hide both) */
.icon-btn.is-bordered:hover {
    background: var(--surface-2);
}

.icon-btn.is-bordered.is-active,
.icon-btn.is-bordered.active {
    background: var(--accent-soft);
    border-color: transparent;
    color: var(--accent-text);
}

.icon-btn.icon-btn-sm {
    width: var(--control-h-sm);
    height: var(--control-h-sm);
    flex-basis: var(--control-h-sm);
    font-size: 12px;
}

.icon-btn:disabled {
    opacity: 0.5;
    pointer-events: none;
}

/* a destructive icon button (wallet disconnect): quiet at rest, red when pointed at */
.icon-btn.is-danger {
    color: var(--text-muted);
}

.icon-btn.is-danger:hover {
    background: var(--danger-soft);
    color: var(--danger);
}

.link-btn {
    color: var(--accent-text);
    cursor: pointer;
    font-weight: 500;
}

.link-btn:hover {
    text-decoration: underline;
}

/* ---------------------------------------------------------------------
   5. INPUTS
   --------------------------------------------------------------------- */
.input,
.textarea {
    display: block;
    width: 100%;
    height: var(--control-h-md);
    padding: 0 10px;
    border-radius: var(--radius-control);
    border: 1px solid var(--border-strong);
    background: var(--bg);
    color: var(--text);
    font-size: var(--fs-md);
    transition: border-color var(--ease), box-shadow var(--ease), background var(--ease);
}

.textarea {
    height: auto;
    min-height: 80px;
    padding: 8px 10px;
    resize: vertical;
    line-height: var(--lh);
}

.input::placeholder,
.textarea::placeholder {
    color: var(--text-faint);
}

.input:hover,
.textarea:hover {
    border-color: var(--text-faint);
}

.input:focus,
.textarea:focus,
.input:focus-visible,
.textarea:focus-visible {
    border-color: var(--accent);
    box-shadow: var(--focus);
}

.input:disabled,
.textarea:disabled {
    opacity: 0.5;
    cursor: not-allowed;
    background: var(--surface-2);
}

.input.is-invalid {
    border-color: var(--danger);
}

.input.mono {
    font-family: var(--font-code);
}

.input-sm {
    height: var(--control-h-sm);
    padding: 0 8px;
    font-size: var(--fs-sm);
}

.input-lg {
    height: var(--control-h-lg);
    font-size: var(--fs-base);
}

/* input with prefix / suffix addons */
.input-group {
    display: flex;
    align-items: stretch;
    width: 100%;
}

.input-group .input {
    flex: 1 1 auto;
    min-width: 0;
}

.input-group .input:not(:first-child) {
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
}

.input-group .input:not(:last-child) {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
}

.input-addon {
    display: inline-flex;
    align-items: center;
    padding: 0 10px;
    border: 1px solid var(--border-strong);
    background: var(--surface-2);
    color: var(--text-muted);
    font-size: var(--fs-sm);
    white-space: nowrap;
}

.input-addon:first-child {
    border-right: 0;
    border-radius: var(--radius-control) 0 0 var(--radius-control);
}

.input-addon:last-child {
    border-left: 0;
    border-radius: 0 var(--radius-control) var(--radius-control) 0;
}

.field {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.field-label {
    font-size: var(--fs-sm);
    font-weight: 500;
    color: var(--text-muted);
}

.field-hint {
    font-size: var(--fs-xs);
    color: var(--text-faint);
}

.field-error {
    font-size: var(--fs-xs);
    color: var(--down);
}

/* select */
.select-wrap {
    position: relative;
    display: inline-flex;
    align-items: center;
    width: auto;
    min-width: 0;
}

.select-wrap.w-full {
    width: 100%;
}

.select {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    height: var(--control-h-md);
    width: 100%;
    padding: 0 28px 0 10px;
    border-radius: var(--radius-control);
    border: 1px solid var(--border-strong);
    background: var(--surface-2);
    color: var(--text);
    font-size: var(--fs-md);
    cursor: pointer;
    transition: border-color var(--ease), box-shadow var(--ease), background var(--ease);
}

.select:hover {
    background: var(--surface-3);
}

.select:focus-visible {
    border-color: var(--accent);
    box-shadow: var(--focus);
}

.select:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* a select that is currently narrowing the feed reads as a filter, like the other active controls */
.select.is-active {
    border-color: var(--accent);
    background: var(--accent-soft);
    color: var(--accent-text);
    font-variant-numeric: tabular-nums;
}

.select option {
    background: var(--surface-2);
    color: var(--text);
}

.select-wrap::after {
    content: "";
    position: absolute;
    right: 11px;
    top: 50%;
    width: 6px;
    height: 6px;
    margin-top: -5px;
    border-right: 1.5px solid var(--text-muted);
    border-bottom: 1.5px solid var(--text-muted);
    transform: rotate(45deg);
    pointer-events: none;
}

.select-sm {
    height: var(--control-h-sm);
    padding: 0 24px 0 8px;
    font-size: var(--fs-sm);
}

/* search */
.search {
    position: relative;
    display: flex;
    align-items: center;
    width: 100%;
    min-width: 0;
}

.search-icon {
    position: absolute;
    left: 10px;
    color: var(--text-faint);
    font-size: 12px;
    pointer-events: none;
}

.search .input {
    padding-left: 30px;
    padding-right: calc(var(--control-h-sm) + 2px);
}

.search.has-suffix .input {
    padding-right: calc(2 * var(--control-h-sm) - 2px);
}

/* the clear button and the field's own control (suffix), inside the field on the right */
.search-end {
    position: absolute;
    right: 3px;
    top: 50%;
    transform: translateY(-50%);
    display: inline-flex;
    align-items: center;
    gap: 1px;
}

.search-clear,
.search-addon {
    width: calc(var(--control-h-sm) - 6px);
    height: calc(var(--control-h-sm) - 6px);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-sm);
    color: var(--text-faint);
    font-size: 12px;
}

.search-clear:hover,
.search-addon:hover,
.search-addon.is-active {
    color: var(--text);
    background: var(--surface-3);
}

/* menus made of settings (the feed's Filters and Display): one row per setting */
.menu-rows {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 4px 8px 8px;
    min-width: 240px;
}

.menu-field {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    font-size: var(--fs-sm);
    color: var(--text);
}

.menu-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding-right: 4px;
}

.filter-menu #filterContent {
    max-height: min(50vh, 420px);
    overflow-y: auto;
}

/* switch (a11y toggle) */
.switch {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    user-select: none;
    vertical-align: middle;
    line-height: 1;
}

.switch.is-disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.switch-input {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
    margin: 0;
    pointer-events: none;
}

.switch-track {
    position: relative;
    display: inline-block;
    width: 34px;
    height: 20px;
    flex: 0 0 34px;
    border-radius: var(--radius-pill);
    background: var(--surface-3);
    border: 1px solid var(--border-strong);
    transition: background var(--ease), border-color var(--ease), box-shadow var(--ease);
}

.switch-thumb {
    position: absolute;
    top: 2px;
    left: 2px;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: var(--text-muted);
    transition: transform var(--ease), background var(--ease);
}

.switch:hover .switch-track {
    border-color: var(--text-faint);
}

.switch-input:checked + .switch-track {
    background: var(--accent);
    border-color: var(--accent);
}

.switch-input:checked + .switch-track .switch-thumb {
    transform: translateX(14px);
    background: #fff;
}

.switch-input:focus-visible + .switch-track {
    box-shadow: var(--focus);
}

.switch-label {
    font-size: var(--fs-md);
    color: var(--text);
}

.switch-sm .switch-track {
    width: 28px;
    height: 16px;
    flex-basis: 28px;
}

.switch-sm .switch-thumb {
    width: 10px;
    height: 10px;
}

.switch-sm .switch-input:checked + .switch-track .switch-thumb {
    transform: translateX(12px);
}

/* checkbox (plain) */
.checkbox {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    font-size: var(--fs-md);
}

.checkbox input[type="checkbox"] {
    appearance: none;
    -webkit-appearance: none;
    width: 16px;
    height: 16px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border-strong);
    background: var(--bg);
    display: inline-grid;
    place-content: center;
    cursor: pointer;
    transition: background var(--ease), border-color var(--ease);
}

.checkbox input[type="checkbox"]::before {
    content: "";
    width: 8px;
    height: 8px;
    border-radius: 2px;
    background: var(--text-on-accent);
    transform: scale(0);
    transition: transform var(--ease);
}

.checkbox input[type="checkbox"]:checked {
    background: var(--accent);
    border-color: var(--accent);
}

.checkbox input[type="checkbox"]:checked::before {
    transform: scale(1);
}

.checkbox.is-disabled,
.dropdown-item.is-disabled,
.dropdown-item:disabled {
    opacity: 0.5;
    pointer-events: none;
}

/* segmented control */
.segmented {
    display: inline-flex;
    align-items: stretch;
    height: var(--control-h-md);
    padding: 2px;
    border-radius: var(--radius-control);
    border: 1px solid var(--border-strong);
    background: var(--surface-2);
    gap: 2px;
}

.segmented-item {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 0 12px;
    border-radius: var(--radius-sm);
    color: var(--text-muted);
    font-size: var(--fs-md);
    font-weight: 500;
    cursor: pointer;
    white-space: nowrap;
    transition: background var(--ease), color var(--ease);
}

.segmented-item:hover {
    color: var(--text);
}

.segmented-item.active {
    background: var(--surface-3);
    color: var(--text);
    box-shadow: var(--shadow-1);
}

.segmented-item:focus-visible {
    box-shadow: var(--focus);
}

.segmented-item.active .badge-count {
    background: var(--accent);
    color: var(--text-on-accent);
}

.segmented-sm {
    height: var(--control-h-sm);
}

.segmented-sm .segmented-item {
    padding: 0 9px;
    font-size: var(--fs-sm);
}

.segmented.w-full .segmented-item {
    flex: 1 1 0;
}

/* range */
input[type="range"].range {
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    height: 4px;
    border-radius: var(--radius-pill);
    background: var(--surface-3);
    outline: none;
}

input[type="range"].range::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: var(--accent);
    border: 2px solid var(--surface);
    cursor: pointer;
}

/* ---------------------------------------------------------------------
   6. CHIPS, TAGS, BADGES, AVATAR
   --------------------------------------------------------------------- */
.chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    height: var(--chip-h-md);
    padding: 0 8px;
    border-radius: var(--radius-pill);
    border: 1px solid transparent;
    background: var(--surface-2);
    color: var(--text-muted);
    font-size: var(--fs-sm);
    font-weight: 500;
    line-height: 1;
    white-space: nowrap;
    max-width: 100%;
    transition: background var(--ease), color var(--ease), border-color var(--ease);
}

.chip i {
    font-size: 11px;
}

.chip img {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    object-fit: cover;
}

.chip.is-clickable,
.chip[role="button"],
button.chip {
    cursor: pointer;
}

.chip.is-clickable:hover,
button.chip:hover {
    background: var(--surface-3);
    color: var(--text);
}

.chip-accent {
    background: var(--accent-soft);
    border-color: transparent;
    color: var(--accent-text);
}

.chip-warn {
    background: var(--warn-soft);
    border-color: rgba(245, 184, 61, 0.35);
    color: var(--warn);
}

.chip-info {
    background: var(--info-soft);
    border-color: rgba(77, 163, 255, 0.35);
    color: var(--info);
}

.chip-danger,
.chip-down {
    background: var(--danger-soft);
    border-color: rgba(229, 72, 77, 0.35);
    color: var(--down);
}

.chip-up {
    background: var(--up-soft);
    border-color: rgba(47, 191, 113, 0.35);
    color: var(--up);
}

.chip-muted {
    background: transparent;
    border-color: var(--border);
    color: var(--text-faint);
}

.chip-solid {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--text-on-accent);
}

.chip.is-active {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--text-on-accent);
}

.chip-sm {
    height: var(--chip-h-sm);
    padding: 0 6px;
    font-size: var(--fs-xs);
}

.chip-remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 14px;
    height: 14px;
    margin-right: -3px;
    border-radius: 50%;
    font-size: 10px;
    color: inherit;
    opacity: 0.7;
}

.chip-remove:hover {
    opacity: 1;
    background: rgba(0, 0, 0, 0.2);
}

.chip-row {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: center;
}

/* tag: smaller, square-ish, mono */
.tag {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    height: auto;
    padding: 0;
    border: 0;
    background: none;
    color: var(--text-muted);
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: 0.05em;
    line-height: 1;
    white-space: nowrap;
    text-transform: uppercase;
}

.tag-accent { color: var(--accent-text); }
.tag-warn { color: var(--warn); }
.tag-info { color: var(--info); }
.tag-danger { color: var(--down); }
.tag-up { color: var(--up); }

/* coin chip (ticker) */
.coin-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    height: 18px;
    padding: 0 6px;
    border-radius: var(--radius-sm);
    background: var(--surface-3);
    border: 1px solid var(--border);
    color: var(--text);
    font-family: var(--font-mono);
    font-size: var(--fs-xs);
    font-weight: 600;
    letter-spacing: 0.02em;
    line-height: 1;
    cursor: pointer;
    transition: background var(--ease), border-color var(--ease), color var(--ease);
}

.coin-chip:hover {
    border-color: var(--accent);
    color: var(--accent-text);
}

.coin-chip .coin-change {
    font-weight: 500;
}

.coin-chip .coin-change.up { color: var(--up); }
.coin-chip .coin-change.down { color: var(--down); }

/* percentage pill (generic; used by chips, strip, popover) ---------- */
.pct-pill {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 1px 4px;
    border-radius: 3px;
    background: var(--pct-flat-bg);
    color: var(--text-muted);
    font-family: var(--font-mono);
    font-size: 10.5px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    line-height: 14px;
    letter-spacing: -0.01em;
    white-space: nowrap;
}

.pct-pill.is-up { color: var(--up); background: var(--up-soft); }
.pct-pill.is-down { color: var(--down); background: var(--down-soft); }
.pct-pill.is-flat { color: var(--text-faint); background: var(--pct-flat-bg); }
.pct-pill.is-strong { font-weight: 700; }
.pct-pill.is-ghost { background: transparent; padding-left: 0; padding-right: 0; }
.pct-pill i { font-size: 8px; opacity: 0.9; }

/* ticker chip v2 (live price + change since the news) --------------- */
.ticker-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 22px;
    padding: 0 3px 0 7px;
    border-radius: 6px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    color: var(--text);
    font-family: var(--font-mono);
    font-size: var(--fs-xs);
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    user-select: none;
    vertical-align: middle;
    position: relative;
    overflow: hidden;
    transition: background 140ms ease, border-color 140ms ease, color 140ms ease, box-shadow 140ms ease;
}

.ticker-chip .ticker-coin {
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--text);
}

.ticker-chip .ticker-price {
    color: var(--text-muted);
    font-weight: 500;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.01em;
    transition: color 200ms ease;
}

/* 24h (or provider) change - kept for compatibility */
.ticker-chip .ticker-change {
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    padding: 1px 4px;
    border-radius: 3px;
    background: var(--pct-flat-bg);
    color: var(--text-muted);
    line-height: 14px;
}

/* % move SINCE THE NEWS - the headline datapoint */
.ticker-chip .tk-pct {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 1px 4px;
    border-radius: 3px;
    background: var(--pct-flat-bg);
    color: var(--text-muted);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.01em;
    line-height: 14px;
}

.ticker-chip .tk-pct.is-up,
.ticker-chip.is-up .tk-pct { color: var(--up); background: var(--up-soft); }
.ticker-chip .tk-pct.is-down,
.ticker-chip.is-down .tk-pct { color: var(--down); background: var(--down-soft); }
.ticker-chip .tk-pct.is-flat,
.ticker-chip.is-flat .tk-pct { color: var(--text-faint); background: var(--pct-flat-bg); }

.ticker-chip.is-up .ticker-change {
    color: var(--up);
    background: var(--up-soft);
}

.ticker-chip.is-down .ticker-change {
    color: var(--down);
    background: var(--down-soft);
}

/* the chip stays neutral whichever way the price went: the colour is the % pill's (a row's headline comes first) */

/* stock chips: same chip, marked by a filled corner so equities read apart from coins at a glance */
.ticker-chip.is-stock {
    background: var(--surface-3);
    border-style: dashed;
}
.ticker-chip.is-stock .ticker-coin::before {
    content: "";
    display: inline-block;
    width: 5px;
    height: 5px;
    border-radius: 1px;
    margin-right: 4px;
    background: var(--text-faint);
    vertical-align: middle;
}
.ticker-chip:hover,
.ticker-chip.is-open {
    border-color: var(--accent);
    background: var(--surface-3);
    box-shadow: 0 0 0 1px var(--accent-soft);
}

.ticker-chip.is-open {
    box-shadow: 0 0 0 1px var(--accent-soft), var(--shadow-1);
}

.ticker-chip:hover .ticker-coin,
.ticker-chip.is-open .ticker-coin {
    color: var(--accent-text);
}

.ticker-chip:focus-visible {
    outline: none;
    box-shadow: var(--focus);
}

.ticker-chip.is-nodata {
    border-style: dashed;
}

.ticker-chip.is-nodata .ticker-coin {
    color: var(--text-muted);
}

/* loading skeleton state */
.ticker-chip.is-loading {
    color: transparent;
    border-color: var(--border);
    background: var(--surface-2);
    min-width: 74px;
    pointer-events: none;
}

.ticker-chip.is-loading > * {
    opacity: 0.25;
}

.ticker-chip.is-loading::after {
    content: "";
    position: absolute;
    inset: 0;
    transform: translateX(-100%);
    background: linear-gradient(90deg, transparent, var(--shimmer-band), transparent);
    animation: tn-shimmer 1.3s infinite;
}

/* small variant (compact density / inline in dense meta rows) */
.ticker-chip-sm {
    height: 17px;
    gap: 4px;
    padding: 0 4px 0 5px;
    font-size: 10px;
    border-radius: 3px;
}

.ticker-chip-sm .tk-pct,
.ticker-chip-sm .ticker-change {
    padding: 0 3px;
    line-height: 12px;
}

.ticker-chip .sparkline {
    margin: 0 1px;
}

/* popover v2 - chart dominant */
.ticker-popover {
    position: fixed;
    top: 0;
    left: 0;
    width: 460px;
    max-width: calc(100vw - 16px);
    z-index: var(--z-dropdown);
    padding: 8px 10px 10px;
    background: var(--surface);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-3);
    color: var(--text);
    font-size: var(--fs-md);
    animation: tn-rise var(--ease);
    cursor: default;
    text-align: left;
}

.ticker-pop-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 4px;
}

.ticker-pop-title {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    flex-wrap: wrap;
}

.ticker-pop-coin {
    font-size: var(--fs-lg);
    font-weight: 700;
    letter-spacing: 0.02em;
}

.ticker-pop-symbol {
    color: var(--text-muted);
    font-size: var(--fs-sm);
}

.ticker-pop-markets {
    display: inline-flex;
    gap: 4px;
    align-items: center;
}

.ticker-pop-close {
    flex: 0 0 auto;
    margin-right: -4px;
}

.ticker-pop-price-row {
    display: flex;
    align-items: baseline;
    gap: 8px;
    flex-wrap: wrap;
    margin-bottom: 8px;
}

.ticker-pop-price {
    font-size: var(--fs-2xl);
    font-weight: 600;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.01em;
}

.ticker-pop-price.is-empty {
    color: var(--text-faint);
}

.ticker-pop-change {
    display: inline-flex;
    gap: 6px;
    align-items: baseline;
    font-size: var(--fs-md);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--text-muted);
}

.ticker-pop-change.is-up { color: var(--up); }
.ticker-pop-change.is-down { color: var(--down); }

.ticker-pop-change .ticker-pop-pct {
    padding: 1px 5px;
    border-radius: 3px;
    background: var(--surface-2);
}

.ticker-pop-change.is-up .ticker-pop-pct { background: var(--up-soft); }
.ticker-pop-change.is-down .ticker-pop-pct { background: var(--down-soft); }

.ticker-pop-age {
    margin-left: auto;
    font-size: var(--fs-xs);
    color: var(--text-faint);
    white-space: nowrap;
}

/* chart area - full width of the popover, no wasted margins */
.ticker-chart {
    position: relative;
    width: 100%;
    min-height: 200px;
    max-width: 100%;
    margin: 0;
    border-radius: var(--radius-md);
    background: var(--surface-2);
    border: 1px solid var(--border);
    overflow: hidden;
}

.tk-chart-svg {
    display: block;
    width: 100%;
    height: 100%;
    min-height: 200px;
}

.tk-grid line {
    stroke: var(--border);
    stroke-width: 1;
    shape-rendering: crispEdges;
}

.tk-candle.up { stroke: var(--up); fill: var(--up); }
.tk-candle.down { stroke: var(--down); fill: var(--down); }
.tk-wicks line { stroke-width: 1; }
.tk-bodies rect { stroke: none; }

.tk-axis {
    fill: var(--text-faint);
    font-family: var(--font-mono);
    font-size: 9px;
}

.tk-axis-last { font-weight: 600; }
.tk-lastline.up .tk-axis-last { fill: var(--up); }
.tk-lastline.down .tk-axis-last { fill: var(--down); }
.tk-lastline line { stroke-width: 1; stroke-dasharray: 1 2; opacity: 0.75; }
.tk-lastline.up line { stroke: var(--up); }
.tk-lastline.down line { stroke: var(--down); }

.tk-newsline line {
    stroke: var(--warn);
    stroke-width: 1;
    stroke-dasharray: 4 3;
    opacity: 0.9;
}

.tk-axis-news { fill: var(--warn); font-weight: 600; }

/* the news: one colour for its time (a line with its label on top), its price (a dot, a line, a tag) */
.tk-marker line {
    stroke: var(--warn);
    stroke-width: 1;
    stroke-dasharray: 3 3;
    opacity: 0.7;
}

.tk-news-dot {
    fill: var(--surface);
    stroke: var(--warn);
    stroke-width: 1.5;
}

/* the hour's biggest move, labelled at its candle (the number a row shows) */
.tk-axis-peak { font-weight: 600; }
.tk-axis-peak.up { fill: var(--up); }
.tk-axis-peak.down { fill: var(--down); }

/* the candles before the news: dimmed, so the reaction after it reads first */
.tk-candle.is-pre {
    opacity: 0.4;
}

.ticker-chart-state {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    font-size: var(--fs-sm);
    color: var(--text-muted);
    text-align: center;
    padding: 8px;
}

.ticker-chart-state i {
    font-size: 18px;
    color: var(--text-faint);
}

.ticker-chart-state.is-muted {
    color: var(--text-faint);
}

.ticker-chart-refresh {
    position: absolute;
    top: 6px;
    left: 6px;
    opacity: 0.8;
}

.ticker-pop-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-top: 8px;
}

.ticker-pop-ref {
    font-size: var(--fs-xs);
    color: var(--text-faint);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ---- popover v2 building blocks (tk-*) ---------------------------- */

/* one compact identity line: coin · symbol · markets · close */
.tk-head {
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
    margin-bottom: 2px;
}

.tk-coin {
    font-size: var(--fs-lg);
    font-weight: 700;
    letter-spacing: 0.02em;
    line-height: 1.1;
    white-space: nowrap;
}

.tk-symbol {
    font-family: var(--font-mono);
    font-size: var(--fs-xs);
    color: var(--text-muted);
    letter-spacing: -0.01em;
    white-space: nowrap;
}

.tk-head-spacer {
    flex: 1 1 auto;
    min-width: 4px;
}

.tk-close {
    flex: 0 0 auto;
    margin-right: -2px;
}

/* compact card: coin · price · since-news · market on one line, then the chart */
.tk-head.is-compact {
    margin-bottom: 6px;
    gap: 8px;
}
.tk-head.is-compact .tk-price {
    font-size: var(--fs-lg);
}
.tk-head.is-compact .tk-symbol {
    flex: 0 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* big price + the two pills that matter */
.tk-price-row {
    display: flex;
    align-items: baseline;
    gap: 8px;
    flex-wrap: wrap;
    margin: 2px 0 8px;
    min-width: 0;
}

.tk-price {
    font-family: var(--font-mono);
    font-size: 22px;
    font-weight: 600;
    line-height: 1.05;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.02em;
    color: var(--text);
}

.tk-price.is-empty {
    color: var(--text-faint);
}

.tk-price.is-up { color: var(--up); }
.tk-price.is-down { color: var(--down); }

/* since-news / 24h pills: same shape, different label */
.tk-since,
.tk-24h {
    display: inline-flex;
    align-items: baseline;
    gap: 4px;
    padding: 2px 6px;
    border-radius: var(--radius-sm);
    background: var(--pct-flat-bg);
    color: var(--text-muted);
    font-family: var(--font-mono);
    font-size: var(--fs-sm);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    line-height: 1.2;
    white-space: nowrap;
}

.tk-since.is-up,
.tk-24h.is-up { color: var(--up); background: var(--up-soft); }
.tk-since.is-down,
.tk-24h.is-down { color: var(--down); background: var(--down-soft); }
.tk-since.is-flat,
.tk-24h.is-flat { color: var(--text-faint); background: var(--pct-flat-bg); }

.tk-since-label,
.tk-24h-label {
    font-size: 9.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    opacity: 0.75;
}

.tk-price-meta {
    margin-left: auto;
    font-family: var(--font-mono);
    font-size: var(--fs-xs);
    color: var(--text-faint);
    white-space: nowrap;
}

/* chart header line: title on the left, intervals inline on the right */
.tk-chart-head {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 4px;
    min-height: 22px;
}

.tk-chart-title {
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-faint);
    white-space: nowrap;
}

/* the chart itself - full bleed inside the popover */
.tk-chart {
    position: relative;
    width: 100%;
    min-height: 220px;
    margin: 0;
    border-radius: var(--radius-md);
    background: var(--surface-2);
    border: 1px solid var(--border);
    overflow: hidden;
}

.tk-chart > svg,
.tk-chart .tk-chart-svg {
    display: block;
    width: 100%;
    height: 100%;
    min-height: 220px;
}

.tk-chart-overlay {
    position: absolute;
    top: 4px;
    left: 6px;
    display: flex;
    align-items: center;
    gap: 6px;
    font-family: var(--font-mono);
    font-size: 10px;
    color: var(--text-faint);
    pointer-events: none;
}

.tk-chart-badge {
    padding: 1px 5px;
    border-radius: 3px;
    background: var(--surface-3);
    color: var(--text-muted);
    border: 1px solid var(--border);
}

/* stats grid under the chart */
.tk-stats {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 4px;
    margin-top: 8px;
}

.tk-stats.is-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.tk-stats.is-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* Header variant: the broad market sits in the top bar, so it has to be tighter than the
   toolbar strip - no sparklines, smaller type, no border boxes. */
.market-strip.is-header {
    gap: 2px;
    max-width: min(56vw, 720px);
    overflow: hidden;
    border-color: transparent;
    background: transparent;
}

/* the top bar's "5s delay": words with a clock, a menu behind them, not a pill */
.delay-chip .chip {
    background: transparent;
}

.delay-chip .chip:hover {
    background: var(--surface-2);
}

.market-strip.is-header .market-tile {
    padding: 2px 6px;
    gap: 5px;
    background: transparent;
    border-color: transparent;
}

.market-strip.is-header .market-tile:hover {
    background: var(--surface-2);
    border-color: transparent;
}

.market-strip.is-header .market-tile-label {
    font-size: 9.5px;
}

.market-strip.is-header .market-tile-price {
    font-size: 11.5px;
}

.market-strip.is-header .market-tile-change {
    font-size: 10.5px;
}

/* A tile that links out (TREE -> CoinGecko) */
.market-tile.is-link {
    text-decoration: none;
    cursor: pointer;
}

.market-tile.is-link:hover {
    border-color: var(--border-strong);
    background: var(--surface-3);
}

.market-tile-ext {
    font-size: 8.5px;
    color: var(--text-faint);
    margin-left: 1px;
}

.market-tile.is-link:hover .market-tile-ext {
    color: var(--text-muted);
}

/* Search operator cheatsheet (dropdown next to the search box); each row inserts its snippet. */
.search-help {
    display: flex;
    flex-direction: column;
    min-width: 260px;
    padding: 2px;
}

.search-help-row {
    display: flex;
    align-items: baseline;
    gap: 8px;
    width: 100%;
    padding: 5px 8px;
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text);
    text-align: left;
    cursor: pointer;
    transition: background var(--ease);
}

.search-help-row:hover,
.search-help-row:focus-visible {
    background: var(--surface-3);
}

.search-help-example {
    flex: 0 0 auto;
    font-family: var(--font-code);
    font-size: 11.5px;
    color: var(--accent-text);
    white-space: nowrap;
}

.search-help-desc {
    color: var(--text-muted);
    font-size: 11.5px;
}

/* Secondary numbers as one quiet line instead of a grid of boxes: the headline metric already
   sits next to the price, so this is context, not another six panels to read. */
.tk-statline {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 14px;
    margin-top: 9px;
    padding-top: 8px;
    border-top: 1px solid var(--border);
    font-family: var(--font-mono);
    font-size: 11.5px;
    color: var(--text);
}

.tk-statline-item {
    display: inline-flex;
    align-items: baseline;
    gap: 4px;
    white-space: nowrap;
}

.tk-statline-label {
    color: var(--text-faint);
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.tk-statline-sep {
    color: var(--text-faint);
}

.tk-stat {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    padding: 4px 6px;
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    border: 1px solid var(--border);
}

.tk-stat-label {
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-faint);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.tk-stat-value {
    font-family: var(--font-mono);
    font-size: 12.5px;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.01em;
    color: var(--text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.tk-stat-value.up,
.tk-stat-value.is-up { color: var(--up); }
.tk-stat-value.down,
.tk-stat-value.is-down { color: var(--down); }
.tk-stat-value.is-muted { color: var(--text-muted); }

.tk-stat.is-up { background: var(--up-soft); border-color: rgba(47, 191, 113, 0.28); }
.tk-stat.is-down { background: var(--down-soft); border-color: rgba(229, 72, 77, 0.28); }

/* loading / error / empty states */
.tk-loading {
    position: relative;
    overflow: hidden;
    min-height: 220px;
    border-radius: var(--radius-md);
    background: var(--surface-2);
    border: 1px solid var(--border);
}

.tk-loading::after {
    content: "";
    position: absolute;
    inset: 0;
    transform: translateX(-100%);
    background: linear-gradient(90deg, transparent, var(--shimmer-band), transparent);
    animation: tn-shimmer 1.4s infinite;
}

.tk-loading.is-line {
    min-height: 12px;
    height: 12px;
    border: 0;
    border-radius: var(--radius-sm);
}

.tk-error,
.tk-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    min-height: 220px;
    padding: 12px;
    border-radius: var(--radius-md);
    background: var(--surface-2);
    border: 1px solid var(--border);
    color: var(--text-muted);
    font-size: var(--fs-sm);
    text-align: center;
}

.tk-error i {
    font-size: 18px;
    color: var(--warn);
}

.tk-empty i {
    font-size: 18px;
    color: var(--text-faint);
}

.tk-error .btn,
.tk-empty .btn {
    margin-top: 2px;
}

.ticker-sheet-backdrop {
    position: fixed;
    inset: 0;
    z-index: calc(var(--z-dropdown) - 1);
    background: rgba(5, 7, 10, 0.45);
    animation: tn-fade var(--ease-slow);
}

/* bottom sheet (<= 700px) */
.ticker-popover.is-sheet {
    top: auto;
    left: 0;
    right: 0;
    bottom: 0;
    width: auto;
    max-width: none;
    max-height: 85vh;
    overflow-y: auto;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    border-bottom: 0;
    padding: 12px 14px calc(14px + env(safe-area-inset-bottom));
    animation: tn-slide-up var(--ease-slow);
}

.ticker-popover.is-sheet .ticker-chart {
    width: 100%;
    height: auto;
}

.ticker-popover.is-sheet .tk-chart-svg {
    height: auto;
}

.ticker-popover.is-sheet .ticker-chart-state {
    min-height: 140px;
    position: relative;
}

.ticker-popover.is-sheet .tk-chart,
.ticker-popover.is-sheet .tk-loading,
.ticker-popover.is-sheet .tk-error,
.ticker-popover.is-sheet .tk-empty {
    min-height: 200px;
}

.ticker-popover.is-sheet .tk-chart > svg,
.ticker-popover.is-sheet .tk-chart .tk-chart-svg {
    min-height: 200px;
    height: auto;
}

.ticker-popover.is-sheet .tk-stats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.ticker-popover.is-sheet .tk-price {
    font-size: 24px;
}

/* count badge */
.badge-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: var(--radius-pill);
    background: var(--surface-3);
    color: var(--text-muted);
    font-family: var(--font-mono);
    font-size: var(--fs-xs);
    font-weight: 500;
    line-height: 1;
}

.badge-count.is-accent {
    background: var(--accent);
    color: var(--text-on-accent);
}

.badge-count.is-danger {
    background: var(--danger);
    color: #fff;
}

.badge-dot {
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--accent);
}

/* avatar */
.avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--surface-3);
    color: var(--text-muted);
    font-size: var(--fs-sm);
    font-weight: 600;
    overflow: hidden;
    flex: 0 0 auto;
    border: 1px solid var(--border);
}

.avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.avatar-sm { width: 22px; height: 22px; font-size: var(--fs-xs); }
.avatar-lg { width: 40px; height: 40px; font-size: var(--fs-base); }
.avatar-xl { width: 56px; height: 56px; font-size: var(--fs-xl); }

/* source logo (news row, settings source row) */
.source-logo {
    width: 18px;
    height: 18px;
    border-radius: 50%;
    object-fit: cover;
    background: var(--surface-3);
    flex: 0 0 18px;
}

.source-logo-lg {
    width: 24px;
    height: 24px;
    flex-basis: 24px;
}

/* ---------------------------------------------------------------------
   7. SURFACES
   --------------------------------------------------------------------- */
.card {
    background: var(--surface);
    border: 1px solid transparent;
    border-radius: var(--radius-lg);
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.card.is-flat {
    box-shadow: none;
}

.card.is-elevated {
    box-shadow: var(--shadow-2);
}

.card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-3);
    padding: 12px 16px;
    border-bottom: 1px solid var(--border);
    min-height: 48px;
}

.card-title {
    font-size: var(--fs-lg);
    font-weight: 600;
    color: var(--text);
    line-height: 1.2;
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

.card-title i {
    color: var(--text-muted);
    font-size: 14px;
}

.card-subtitle {
    font-size: var(--fs-sm);
    color: var(--text-muted);
    margin-top: 2px;
    font-weight: 400;
}

.card-actions {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    flex: 0 0 auto;
}

.card-body {
    padding: 16px;
    min-width: 0;
}

.card-body.is-flush {
    padding: 0;
}

.card-footer {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--sp-2);
    padding: 12px 16px;
    border-top: 1px solid var(--border);
    background: var(--surface-2);
    border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}

.card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr));
    gap: var(--sp-4);
}

.section-title {
    font-size: var(--fs-sm);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-muted);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-2);
    margin: 0 0 var(--sp-2);
}

.section-title-right {
    font-weight: 400;
    text-transform: none;
    letter-spacing: 0;
    color: var(--text-faint);
}

.divider {
    height: 1px;
    background: var(--border);
    margin: var(--sp-3) 0;
}

.divider-v {
    width: 1px;
    align-self: stretch;
    background: var(--border);
    margin: 0 var(--sp-2);
}

.divider-label {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    color: var(--text-faint);
    font-size: var(--fs-xs);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    margin: var(--sp-3) 0;
}

.divider-label::before,
.divider-label::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--border);
}

/* key / value */
.kv {
    display: flex;
    flex-direction: column;
}

.kv-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-4);
    padding: 8px 0;
    border-bottom: 1px solid var(--border);
    font-size: var(--fs-md);
}

.kv-row:last-child {
    border-bottom: 0;
}

.kv-key {
    color: var(--text-muted);
    flex: 0 0 auto;
}

.kv-val {
    color: var(--text);
    text-align: right;
    min-width: 0;
    overflow-wrap: anywhere;
}

.kv-val.mono {
    font-family: var(--font-mono);
}

/* table */
.table-wrap {
    width: 100%;
    overflow-x: auto;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface);
}

.table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--fs-md);
}

.table th,
.table td {
    padding: 11px 12px;
    text-align: left;
    border-bottom: 1px solid var(--border);
    vertical-align: middle;
    white-space: nowrap;
}

.table th {
    font-size: var(--fs-xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    background: var(--surface);
    position: sticky;
    top: 0;
    z-index: 1;
}

.table tbody tr {
    transition: background var(--ease);
}

.table tbody tr:hover {
    background: var(--surface-hover);
}

.table tbody tr:last-child td {
    border-bottom: 0;
}

.table tbody tr.is-clickable {
    cursor: pointer;
}

.table tbody tr.is-me,
.table tbody tr.is-highlight {
    background: var(--accent-soft);
}

.table .num,
.table td.mono,
.table th.num {
    text-align: right;
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
}

.table th.num {
    font-family: var(--font-ui);
}

.table td.center,
.table th.center {
    text-align: center;
}

.table td.wrap {
    white-space: normal;
}

.table-dense th,
.table-dense td {
    padding: 5px 10px;
}

.table .rank {
    font-family: var(--font-mono);
    color: var(--text-faint);
    width: 40px;
}

.table .rank.is-top {
    color: var(--warn);
    font-weight: 600;
}

/* empty state */
.empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: 6px;
    padding: 40px 20px;
    color: var(--text-muted);
}

.empty-icon {
    width: 44px;
    height: 44px;
    border-radius: var(--radius-lg);
    background: var(--surface-2);
    border: 1px solid var(--border);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 18px;
    color: var(--text-faint);
    margin-bottom: 6px;
}

.empty-title {
    font-weight: 600;
    color: var(--text);
    font-size: var(--fs-base);
}

.empty-desc {
    font-size: var(--fs-md);
    max-width: 360px;
}

.empty-action {
    margin-top: 8px;
}

/* spinner */
.spinner {
    display: inline-block;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    border: 2px solid var(--border-strong);
    border-top-color: var(--accent);
    animation: tn-spin 0.7s linear infinite;
    flex: 0 0 auto;
}

.spinner-sm { width: 12px; height: 12px; border-width: 2px; }
.spinner-lg { width: 28px; height: 28px; border-width: 3px; }

/* loader (centered block) */
.loader {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 40px;
    color: var(--text-muted);
    font-size: var(--fs-md);
}

.loader-bar {
    position: relative;
    height: 2px;
    width: 100%;
    overflow: hidden;
    background: var(--surface-3);
}

.loader-bar::after {
    content: "";
    position: absolute;
    left: -40%;
    top: 0;
    bottom: 0;
    width: 40%;
    background: var(--accent);
    animation: tn-slide 1.2s ease-in-out infinite;
}

/* alert */
.alert {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 10px 12px;
    border-radius: var(--radius-md);
    border: 1px solid var(--border);
    background: var(--surface-2);
    color: var(--text);
    font-size: var(--fs-md);
    line-height: 1.4;
}

.alert-icon {
    flex: 0 0 auto;
    margin-top: 2px;
    font-size: 13px;
    color: var(--text-muted);
}

.alert-body {
    flex: 1 1 auto;
    min-width: 0;
}

.alert-title {
    font-weight: 600;
    margin-bottom: 2px;
}

.alert-close {
    flex: 0 0 auto;
}

.alert-info { border-color: rgba(77, 163, 255, 0.35); background: var(--info-soft); }
.alert-info .alert-icon { color: var(--info); }
.alert-warn { border-color: rgba(245, 184, 61, 0.35); background: var(--warn-soft); }
.alert-warn .alert-icon { color: var(--warn); }
.alert-danger { border-color: rgba(229, 72, 77, 0.35); background: var(--danger-soft); }
.alert-danger .alert-icon { color: var(--down); }
.alert-success { border-color: rgba(76, 166, 76, 0.35); background: var(--accent-soft); }
.alert-success .alert-icon { color: var(--accent-text); }

/* skeleton */
.skeleton {
    position: relative;
    overflow: hidden;
    background: var(--surface-2);
    border-radius: var(--radius-sm);
    min-height: 12px;
}

.skeleton::after {
    content: "";
    position: absolute;
    inset: 0;
    transform: translateX(-100%);
    background: linear-gradient(90deg, transparent, var(--surface-3), transparent);
    animation: tn-shimmer 1.4s infinite;
}

/* code block */
.code {
    display: block;
    padding: 10px 12px;
    border-radius: var(--radius-md);
    border: 1px solid var(--border);
    background: var(--bg);
    font-family: var(--font-mono);
    font-size: var(--fs-sm);
    color: var(--text);
    overflow-x: auto;
    white-space: pre;
}

.code-inline {
    padding: 1px 5px;
    border-radius: var(--radius-sm);
    background: var(--surface-3);
    font-family: var(--font-mono);
    font-size: 0.9em;
}

.copy-field {
    display: flex;
    align-items: center;
    gap: 6px;
    height: 32px;
    padding: 0 4px 0 10px;
    border-radius: var(--radius-md);
    border: 1px solid var(--border-strong);
    background: var(--bg);
    font-family: var(--font-mono);
    font-size: var(--fs-sm);
    min-width: 0;
}

.copy-field-text {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--text-muted);
}

/* ---------------------------------------------------------------------
   8. OVERLAYS
   --------------------------------------------------------------------- */
.modal-overlay {
    position: fixed;
    inset: 0;
    z-index: var(--z-modal);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--sp-4);
    background: rgba(5, 7, 10, 0.7);
    animation: tn-fade var(--ease-slow);
}

:root[data-theme="light"] .modal-overlay {
    background: rgba(16, 20, 24, 0.45);
}

.modal {
    position: relative;
    width: 100%;
    max-width: 480px;
    max-height: calc(100vh - 32px);
    display: flex;
    flex-direction: column;
    background: var(--surface-raised);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-3);
    animation: tn-rise var(--ease-slow);
    min-width: 0;
}

.modal-sm { max-width: 380px; }
.modal-lg { max-width: 680px; }
.modal-xl { max-width: 900px; }

.modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-3);
    padding: 14px 16px;
    border-bottom: 1px solid var(--border);
}

.modal-title {
    font-size: var(--fs-lg);
    font-weight: 600;
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

.modal-body {
    padding: 16px;
    overflow-y: auto;
    min-height: 0;
    flex: 1 1 auto;
}

.modal-body p + p {
    margin-top: 8px;
}

.modal-footer {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--sp-2);
    padding: 12px 16px;
    border-top: 1px solid var(--border);
    background: var(--surface-2);
    border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}

.modal-footer.is-between {
    justify-content: space-between;
}

body.tn-modal-open {
    overflow: hidden;
}

/* drawer */
.drawer-overlay {
    position: fixed;
    inset: 0;
    z-index: var(--z-drawer);
    background: rgba(5, 7, 10, 0.45);
    animation: tn-fade var(--ease-slow);
}

.drawer {
    position: fixed;
    top: 0;
    bottom: 0;
    right: 0;
    width: 400px;
    max-width: 100vw;
    z-index: calc(var(--z-drawer) + 1);
    display: flex;
    flex-direction: column;
    background: var(--surface-raised);
    border-left: 1px solid var(--border-strong);
    box-shadow: var(--shadow-3);
    animation: tn-slide-in-right var(--ease-slow);
}

/* on wide screens a drawer is a floating panel under the top bar, the same shape as the columns */
@media (min-width: 901px) {
    .drawer:not(.is-left) {
        top: calc(var(--topbar-h) + var(--gutter));
        right: var(--gutter);
        bottom: var(--gutter);
        max-width: calc(100vw - var(--gutter) * 2);
        border: 1px solid var(--border-strong);
        border-radius: var(--radius-panel);
        overflow: hidden;
    }
}

.drawer.is-left {
    right: auto;
    left: 0;
    border-left: 0;
    border-right: 1px solid var(--border-strong);
    animation: tn-slide-in-left var(--ease-slow);
}

.drawer-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-3);
    padding: 0 12px 0 16px;
    height: var(--topbar-h);
    border-bottom: 1px solid var(--border);
    flex: 0 0 auto;
}

.drawer-title {
    font-size: var(--fs-lg);
    font-weight: 600;
    display: flex;
    align-items: center;
    gap: 8px;
}

.drawer-body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 16px 20px;
}

.drawer-footer {
    flex: 0 0 auto;
    padding: 12px 20px;
    border-top: 1px solid var(--border);
    background: var(--surface-raised);
}

/* dropdown */
.dropdown {
    position: relative;
    display: inline-flex;
}

.dropdown-menu {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    min-width: 180px;
    max-width: calc(100vw - 16px);
    z-index: var(--z-dropdown);
    padding: 4px;
    background: var(--surface-raised);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-2);
    animation: tn-rise var(--ease);
}

.dropdown-menu.is-left {
    right: auto;
    left: 0;
}

.dropdown-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 7px 10px;
    border-radius: 6px;
    color: var(--text);
    font-size: var(--fs-md);
    text-align: left;
    cursor: pointer;
    white-space: nowrap;
}

.dropdown-item i {
    width: 14px;
    color: var(--text-muted);
    text-align: center;
}

.dropdown-item:hover {
    background: var(--surface-2);
    color: var(--text);
}

.dropdown-item.active {
    background: var(--accent-soft);
    color: var(--accent-text);
}

.dropdown-item.is-danger {
    color: var(--down);
}

.dropdown-sep {
    height: 1px;
    background: var(--border);
    margin: 4px 0;
}

.dropdown-label {
    padding: 6px 10px 2px;
    font-size: var(--fs-xs);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-faint);
}

/* tabs */
.tabs {
    display: flex;
    align-items: flex-end;
    gap: 2px;
    border-bottom: 1px solid var(--border);
    overflow-x: auto;
    scrollbar-width: none;
}

.tabs::-webkit-scrollbar {
    display: none;
}

.tab {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 36px;
    padding: 0 12px;
    color: var(--text-muted);
    font-size: var(--fs-md);
    font-weight: 500;
    white-space: nowrap;
    cursor: pointer;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    transition: color var(--ease), border-color var(--ease);
}

.tab:hover {
    color: var(--text);
}

.tab.active {
    color: var(--text);
    border-bottom-color: var(--accent);
}

.tab .badge-count {
    margin-left: 2px;
}

.tab-panel {
    padding-top: var(--sp-4);
}

/* toolbar */
.toolbar {
    position: sticky;
    top: 0;
    z-index: 3;
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    min-height: 44px;
    padding: 6px 12px;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    flex-wrap: wrap;
}

.toolbar.is-static {
    position: static;
}

/* 1360px and up: the toolbar sits in the top bar (src/index.js inHeader) */
.page-news .topbar-center {
    justify-content: flex-start;
}

.topbar-center > .toolbar.in-header {
    max-width: none;
}

.toolbar.in-header {
    position: static;
    width: 100%;
    min-height: 0;
    padding: 0;
    background: transparent;
    border-bottom: 0;
    flex-wrap: nowrap;
}

.toolbar.in-header .search {
    max-width: 320px;
    flex: 1 1 220px;
}

/* the coin prices take whatever room the header has left (MarketStrip shows the leading tiles that fit, or none) */
.toolbar.in-header .market-strip {
    background: transparent;
    border-color: var(--border);
}

.toolbar-spacer {
    flex: 1 1 auto;
}

.toolbar .search {
    max-width: 360px;
    flex: 1 1 200px;
}

/* tooltip (pure css, data-tip) */
[data-tip] {
    position: relative;
}

[data-tip]:hover::after {
    content: attr(data-tip);
    position: absolute;
    left: 50%;
    bottom: calc(100% + 6px);
    transform: translateX(-50%);
    z-index: var(--z-dropdown);
    padding: 4px 8px;
    border-radius: var(--radius-sm);
    background: var(--surface-3);
    border: 1px solid var(--border-strong);
    color: var(--text);
    font-size: var(--fs-xs);
    font-weight: 400;
    white-space: nowrap;
    box-shadow: var(--shadow-2);
    pointer-events: none;
}

/* ---------------------------------------------------------------------
   9. FEED (home)
   --------------------------------------------------------------------- */
.feed {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--gutter);
    padding: var(--gutter);
    height: calc(100vh - var(--topbar-h));
    height: calc(100dvh - var(--topbar-h));
    min-height: 0;
    background: transparent;
}

.feed.is-single {
    grid-template-columns: minmax(0, 1fr);
}

.feed.has-sidebar {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) 320px;
}

.feed-col {
    position: relative;
    display: flex;
    flex-direction: column;
    min-width: 0;
    min-height: 0;
    background: var(--surface);
    border-radius: var(--radius-panel);
    overflow: hidden;
}

.feed-col-header {
    position: sticky;
    top: 0;
    z-index: 2;
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    height: 44px;
    padding: 0 10px 0 14px;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    flex: 0 0 auto;
}

/* the first column's live dot: the one news connection */
.feed-live {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: var(--fs-xs);
    color: var(--text-muted);
}

.feed-live.is-off {
    color: var(--warn);
}

.feed-live .status-dot {
    width: 6px;
    height: 6px;
    flex: 0 0 6px;
}

.feed-col-title {
    font-size: var(--fs-base);
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--text);
    display: flex;
    align-items: center;
    gap: 8px;
    white-space: nowrap;
}

.feed-col-title i {
    color: var(--text-muted);
    font-size: 15px;
}

.feed-col-actions {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 4px;
}

.feed-col-body {
    position: relative;
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
}

.feed-col-body > div {
    height: 100%;
}

.feed-side {
    display: flex;
    flex-direction: column;
    min-width: 0;
    min-height: 0;
    overflow-y: auto;
    background: transparent;
    padding: var(--sp-3);
    gap: var(--sp-3);
}

/* filter bar above the columns */
.feed-toolbar {
    grid-column: 1 / -1;
}

.feed-wrap {
    display: flex;
    flex-direction: column;
    height: calc(100vh - var(--topbar-h));
    height: calc(100dvh - var(--topbar-h));
    min-height: 0;
}

.feed-wrap > .feed {
    flex: 1 1 auto;
    height: auto;
    min-height: 0;
}

/* news row ----------------------------------------------------------- */
.news-row {
    display: grid;
    grid-template-columns: 58px 22px minmax(0, 1fr) auto;
    grid-template-areas: "time logo body actions";
    column-gap: 12px;
    align-items: start;
    padding: 11px 12px 11px 14px;
    border-bottom: 1px solid var(--border);
    background: var(--surface);
    transition: background 140ms ease, box-shadow 140ms ease, opacity 140ms ease;
    position: relative;
    outline: none;
}

/* the left edge bar: a state only (Big, followed, yours, downvoted, open); the logo already says who posted */
.news-row::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    bottom: -1px;
    width: var(--row-bar-w);
    background: transparent;
    transition: background 140ms ease;
    pointer-events: none;
}

.news-row:hover {
    background: var(--surface-hover);
}

/* who posted reads like X / TweetDeck: a person's name in the text colour (handle muted), outlets as a muted kicker */
.news-row.tweet-row .news-head .news-source-name {
    color: var(--text);
}

/* --- row states ----------------------------------------------------- */
.news-row.is-downvoted {
    opacity: 0.72;
}

.news-row.is-downvoted::before {
    background: var(--down);
    opacity: 1;
}

.news-row.is-custom::before,
.news-row.is-followed::before {
    background: var(--info);
}

/* a "BREAKING:" opening or an all-caps wire flash: the headline in bold (yellow is Big's) */
.news-row.is-breaking .news-title {
    font-weight: 600;
    color: var(--text);
}

.news-row.is-new {
    animation: tn-flash 1.6s ease-out;
}

/* fresh = published < 60s ago: a green light washes in from the left and fades */
.news-row.is-fresh::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: var(--accent-soft);
    box-shadow: inset 2px 0 0 var(--accent);
    animation: tn-row-fresh 4s ease-out forwards;
}

.news-row.is-entering {
    animation: tn-row-in 180ms ease-out;
}

.news-row.is-dim {
    opacity: 0.55;
}

.news-row:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: -2px;
    box-shadow: var(--focus);
    z-index: 1;
}

/* the structural topic tag (PROFILE) */
.news-src-tag {
    background: var(--tint-8);
    border-color: var(--border);
    color: var(--text-muted);
    text-transform: uppercase;
}

/* every badge on the source line has this one shape */
.news-big,
.news-follow,
.news-repeat,
.news-score,
.news-src-tag,
.news-head .tag {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    height: 18px;
    padding: 0 6px;
    border: 1px solid transparent;
    border-radius: 5px;
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.03em;
    line-height: 1;
    white-space: nowrap;
    flex: 0 0 auto;
}

.news-head .tag {
    border-color: var(--border);
    font-weight: 600;
}

/* inline mono metrics (impact, volume, followers, …) */
.news-metrics {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    font-family: var(--font-mono);
    font-size: 10.5px;
    color: var(--text-faint);
    font-variant-numeric: tabular-nums;
}

.news-metric {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    white-space: nowrap;
}

.news-metric i {
    font-size: 9px;
    opacity: 0.8;
}

.news-metric b {
    font-weight: 600;
    color: var(--text-muted);
}

.news-metric.is-up b { color: var(--up); }
.news-metric.is-down b { color: var(--down); }

.news-time {
    grid-area: time;
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    font-size: var(--fs-sm);
    letter-spacing: -0.01em;
    color: var(--text-muted);
    line-height: 19px;
    white-space: nowrap;
    display: flex;
    flex-direction: column;
    gap: 0;
    padding-top: 1px;
    transition: color 140ms ease;
}

.news-row:hover .news-time {
    color: var(--text);
}

.news-time-ago {
    font-size: var(--fs-xs);
    color: var(--text-faint);
    line-height: 12px;
}

.news-source {
    grid-area: logo;
    display: flex;
    align-items: flex-start;
    height: 22px;
    padding-top: 0;
}

.news-source .source-logo {
    width: 22px;
    height: 22px;
    flex-basis: 22px;
}

/* outlets and exchanges: rounded squares (their logos are marks, not faces) */
.news-row:not(.tweet-row) .news-source .source-logo,
.news-row:not(.tweet-row) .news-source-fallback {
    border-radius: 6px;
}

.news-source-fallback {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    color: var(--text-muted);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 10px;
}

.news-body {
    grid-area: body;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.news-head {
    display: flex;
    align-items: center;
    gap: 5px;
    flex-wrap: wrap;
    min-width: 0;
    line-height: 18px;
    min-height: 18px;
}

.news-source-name {
    font-size: var(--fs-sm);
    font-weight: 600;
    letter-spacing: 0.01em;
    color: var(--text-muted);
    white-space: nowrap;
}

/* outlets and exchanges arrive as "THE STREET", "CoinDesk", "Upbit": one small-caps kicker for all (people's names on
   tweets stay as written) */
.news-row:not(.tweet-row) .news-head .news-source-name {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

.news-source-name a:hover {
    color: var(--accent-text);
}

.news-handle {
    font-size: var(--fs-sm);
    color: var(--text-faint);
}

.news-title {
    font-size: var(--fs-lg);
    line-height: 1.47;
    letter-spacing: -0.004em;
    color: var(--text);
    font-weight: 500;
    overflow-wrap: anywhere;
    word-break: break-word;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Publication badge: the "PUBLICATION: " prefix lifted out of the headline (news.sourceName).
   Inline so it flows with the clamped headline text instead of stealing a line. */

.news-title a {
    color: inherit;
}

.news-title a:hover {
    color: var(--accent-hover);
}

.news-title a:visited {
    color: var(--text-muted);
}

/* the headline lights up while the pointer is anywhere on it: on the link alone it went off in the gap between two lines
   (an inline link's box is its text, line by line) and on again on the next, so moving down a long post flickered */
.news-title:hover a {
    color: var(--accent-hover);
}

.news-title.is-strong {
    font-weight: 500;
}

.news-title mark,
.news-body mark {
    background: var(--warn-soft);
    color: var(--warn);
    padding: 0 2px;
    border-radius: 2px;
}

.news-text {
    font-size: var(--fs-base);
    color: var(--text);
    line-height: 1.45;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.news-text a {
    color: var(--accent-text);
}

.news-text a:hover {
    text-decoration: underline;
}

.news-quote {
    margin-top: 4px;
    padding: 9px 12px;
    border: 1px solid var(--border);
    background: var(--tint-8);
    border-radius: var(--radius-md);
    font-size: var(--fs-md);
    line-height: 1.5;
    color: var(--text-muted);
}

.news-quote .news-source-name {
    color: var(--text);
}

.news-meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 4px 5px;
    margin-top: 1px;
    font-size: var(--fs-sm);
    color: var(--text-muted);
    min-width: 0;
}

.news-meta-sep {
    color: var(--text-faint);
}

.news-image-link {
    display: inline-block;
    max-width: 100%;
}

.news-image {
    display: block;
    max-width: min(340px, 100%);
    max-height: 180px;
    width: auto;
    border-radius: 10px;
    border: 1px solid var(--border);
    margin-top: 2px;
    object-fit: cover;
    cursor: pointer;
}

.news-images {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 4px;
}

.news-images .news-image {
    max-height: 160px;
    margin-top: 0;
}

.news-actions {
    grid-area: actions;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 4px;
    min-height: 20px;
    opacity: 1;
    position: relative;
    /* the market reaction (first coin); the hover bar (votes, details, open, copy link, copy time) opens at its left,
       over the end of the headline's first line */
    min-width: 0;
}

.news-actions-sep {
    width: 1px;
    height: 14px;
    margin: 0 3px;
    background: var(--border-strong);
}

/* a row's community score, shown only when it is not zero (the arrows themselves are in the hover bar) */
.news-score {
    color: var(--text-muted);
    background: var(--tint-8);
    border-color: var(--border);
}

.news-score i {
    font-size: 10px;
}

.news-score.is-up {
    color: var(--up);
    background: var(--up-soft);
    border-color: transparent;
}

.news-score.is-down {
    color: var(--down);
    background: var(--down-soft);
    border-color: transparent;
}

.news-score.is-mine {
    box-shadow: inset 0 0 0 1px currentColor;
}

/* Everything except the votes is hidden until the row is hovered or
   focused. Votes (.vote / .vote-count) are ALWAYS visible. */
.news-actions .news-action-btn,
.news-actions .icon-btn,
.news-actions-extra {
    opacity: 0;
    visibility: hidden;
    transform: translateX(2px);
    transition: opacity 140ms ease, visibility 140ms ease, transform 140ms ease;
}

.news-row:hover .news-actions .news-action-btn,
.news-row:hover .news-actions .icon-btn,
.news-row:hover .news-actions-extra,
.news-row:focus-within .news-actions .news-action-btn,
.news-row:focus-within .news-actions .icon-btn,
.news-row:focus-within .news-actions-extra {
    opacity: 1;
    visibility: visible;
    transform: none;
}

.news-actions-extra {
    position: absolute;
    top: -2px;
    height: 26px;
    right: calc(100% + 6px);
    display: flex;
    align-items: center;
    gap: 1px;
    padding: 0 3px;
    border-radius: var(--radius-md);
    background: var(--surface-raised);
    box-shadow: var(--shadow-2);
}

.vote {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: 5px;
    color: var(--text-faint);
    font-size: 11px;
    cursor: pointer;
    transition: background 140ms ease, color 140ms ease, transform 140ms ease;
}

.vote:active {
    transform: scale(0.9);
}

.vote:hover {
    background: var(--surface-3);
    color: var(--text);
}

.vote.up.active,
.vote.up.is-active {
    color: var(--up);
    background: var(--up-soft);
}

.vote.down.active,
.vote.down.is-active {
    color: var(--down);
    background: var(--down-soft);
}

.vote-count {
    min-width: 18px;
    text-align: center;
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    font-size: 11px;
    letter-spacing: -0.02em;
    color: var(--text-faint);
}

.vote-count.up { color: var(--up); }
.vote-count.down { color: var(--down); }

.icon-btn.news-action-btn {
    width: 22px;
    height: 22px;
    flex-basis: 22px;
    font-size: 11px;
}

/* day separator inside the list */
.news-day {
    padding: 6px 14px;
    background: var(--surface);
    background: color-mix(in srgb, var(--surface) 86%, transparent);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--border);
    font-family: var(--font-mono);
    font-size: 10.5px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--text-muted);
}

/* the day of the rows at a column's top, held there while they scroll by (src/index.js setDayInView); the list's own
   labels pass under it */
.feed-col-body > .news-day-float {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    z-index: 2;
    height: auto;
    pointer-events: none;
}

/* "new items" pill floating at column top */
.feed-new-pill {
    position: absolute;
    top: 8px;
    left: 50%;
    transform: translate(-50%, 0);
    z-index: 3;
    height: 24px;
    padding: 0 10px;
    border-radius: var(--radius-pill);
    background: var(--accent);
    border: 1px solid var(--accent-hover);
    color: var(--text-on-accent);
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.02em;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    box-shadow: var(--shadow-2);
    cursor: pointer;
    white-space: nowrap;
    animation: tn-pill-drop 200ms cubic-bezier(0.2, 0.7, 0.2, 1);
    transition: background 140ms ease, transform 140ms ease, box-shadow 140ms ease;
}

.feed-new-pill:hover {
    background: var(--accent-hover);
    transform: translate(-50%, 1px);
    box-shadow: var(--shadow-3);
}

.feed-new-pill i {
    font-size: 9px;
}

/* filters */
.filter-bar {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}

.filter-panel {
    padding: 10px 12px;
    background: var(--surface-2);
    border-bottom: 1px solid var(--border);
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: center;
}

/* a stock chip shows the change today (a coin chip: the move since the news), so it says so */
.tk-pct-unit {
    margin-left: 3px;
    font-size: 0.85em;
    opacity: 0.7;
}

/* "+N": coins the row does not show (their names in the tooltip) */
.ticker-more {
    display: inline-flex;
    align-items: center;
    height: 20px;
    padding: 0 6px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border);
    color: var(--text-muted);
    font-family: var(--font-mono);
    font-size: var(--fs-xs);
}

/* calendar / events (drawer content) */
.calendar-tab {
    position: fixed;
    right: 0;
    top: 40%;
    z-index: var(--z-rail);
    writing-mode: vertical-rl;
    padding: 10px 6px;
    border-radius: var(--radius-md) 0 0 var(--radius-md);
    background: var(--accent);
    color: var(--text-on-accent);
    font-size: var(--fs-sm);
    font-weight: 600;
    letter-spacing: 0.06em;
    cursor: pointer;
    box-shadow: var(--shadow-2);
    user-select: none;
}

.calendar-tab:hover {
    background: var(--accent-hover);
    color: var(--text-on-accent);
}

.event-list {
    display: flex;
    flex-direction: column;
}

.event-day {
    position: sticky;
    top: 0;
    z-index: 1;
    padding: 12px 0 6px;
    background: var(--surface-raised);
    border-bottom: 1px solid var(--border);
    font-family: var(--font-mono);
    font-size: 10.5px;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--text-muted);
    font-weight: 500;
}

.event-item {
    display: grid;
    grid-template-columns: 48px 64px minmax(0, 1fr);
    gap: 8px;
    align-items: start;
    padding: 7px 0;
    border-bottom: 1px solid var(--border);
    font-size: var(--fs-md);
}

.event-item:last-child {
    border-bottom: 0;
}

.event-time {
    font-family: var(--font-mono);
    font-size: var(--fs-sm);
    color: var(--text-muted);
    white-space: nowrap;
    padding-top: 1px;
}

.event-coin {
    min-width: 0;
}

.event-name {
    min-width: 0;
    overflow-wrap: anywhere;
}

.event-name a {
    color: var(--text);
}

.event-name a:hover {
    color: var(--accent-text);
    text-decoration: underline;
    text-underline-offset: 3px;
}

.event-credit {
    font-size: var(--fs-xs);
    color: var(--text-faint);
}

/* ---- the market reaction (src/components/ticker.js TickerReaction): a row's first coin, the biggest move within the
   hour after the news, and its price around the news on one time axis (the news sits at the same x on every row) */
.rx {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 3px;
    width: 124px;
    padding: 5px 6px 4px;
    border-radius: var(--radius-md);
    border: 1px solid transparent;
    background: transparent;
    color: var(--text);
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: background 140ms ease, border-color 140ms ease, box-shadow 140ms ease;
}

.rx:hover,
.rx.is-open {
    background: var(--surface-2);
    border-color: var(--border-strong);
}

.rx.is-up:hover,
.rx.is-up.is-open {
    box-shadow: 0 0 0 1px rgba(22, 199, 132, 0.18), 0 6px 18px -8px rgba(22, 199, 132, 0.45);
}

.rx.is-down:hover,
.rx.is-down.is-open {
    box-shadow: 0 0 0 1px rgba(246, 70, 93, 0.18), 0 6px 18px -8px rgba(246, 70, 93, 0.45);
}

.rx-top {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 6px;
    font-family: var(--font-mono);
    line-height: 14px;
}

.rx-coin {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.03em;
    color: var(--text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

.rx-pct {
    font-size: 13px;
    font-weight: 600;
    letter-spacing: -0.02em;
    white-space: nowrap;
    color: var(--text-muted);
}

.rx-pct.is-up { color: var(--up); }
.rx-pct.is-down { color: var(--down); }
.rx-pct.is-flat { color: var(--text-faint); font-weight: 500; font-size: 11.5px; }

.rx-spark {
    display: block;
    overflow: visible;
}

.rx-spark path,
.rx-spark line,
.rx-spark circle {
    vector-effect: non-scaling-stroke;
}

.rx-pre {
    fill: none;
    stroke: var(--text-faint);
    stroke-width: 1.25;
    stroke-linejoin: round;
    stroke-linecap: round;
    opacity: 0.55;
}

.rx-post {
    fill: none;
    stroke: var(--text-muted);
    stroke-width: 1.5;
    stroke-linejoin: round;
    stroke-linecap: round;
}

.rx-area {
    fill: var(--text-faint);
    opacity: 0.12;
    stroke: none;
}

.rx-spark.is-up .rx-post { stroke: var(--up); }
.rx-spark.is-up .rx-area { fill: var(--up); opacity: 0.16; }
.rx-spark.is-down .rx-post { stroke: var(--down); }
.rx-spark.is-down .rx-area { fill: var(--down); opacity: 0.16; }

/* the news minute: a hairline, a dot at the price, and that price carried on, dashed */
.rx-news {
    stroke: var(--text-faint);
    stroke-width: 1;
    stroke-dasharray: 2 2;
    opacity: 0.55;
}

.rx-base {
    stroke: var(--text-faint);
    stroke-width: 1;
    stroke-dasharray: 1 3;
    opacity: 0.6;
}

.rx-dot {
    fill: var(--text);
    stroke: var(--surface);
    stroke-width: 1.5;
}



/* the first hour still running: "now" breathes */
.rx-now {
    fill: var(--text);
}

.rx-spark.is-up .rx-now { fill: var(--up); }
.rx-spark.is-down .rx-now { fill: var(--down); }


.rx-skel {
    stroke: var(--surface-3);
    stroke-width: 2;
    stroke-linecap: round;
    stroke-dasharray: 3 4;
}

.rx.is-loading .rx-skel {
    animation: tn-fade-pulse 1.4s ease-in-out infinite;
}

@keyframes tn-fade-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.4; }
}

.rx.is-nochart {
    padding-bottom: 5px;
}

/* compact rows: one line, a small chart */
.feed.is-compact .rx,
.feed-col.is-compact .rx {
    flex-direction: row;
    align-items: center;
    width: auto;
    padding: 1px 4px;
    gap: 6px;
}

.feed.is-compact .rx-top,
.feed-col.is-compact .rx-top {
    gap: 6px;
}

/* ---- the story panel's market view (StoryMarket) */
.story-market {
    gap: 10px;
}

.story-label-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    min-width: 0;
}

.story-coin-tabs {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-wrap: wrap;
    justify-content: flex-end;
}

.story-coin-tab {
    height: 24px;
    padding: 0 8px;
    border-radius: 6px;
    border: 1px solid var(--border);
    background: transparent;
    color: var(--text-muted);
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.02em;
    cursor: pointer;
    transition: background 140ms ease, color 140ms ease, border-color 140ms ease;
}

.story-coin-tab:hover {
    color: var(--text);
    background: var(--surface-2);
}

.story-coin-tab.is-active {
    color: var(--text);
    background: var(--surface-3);
    border-color: var(--border-strong);
}

.story-coin-more {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--text-faint);
}

.sm {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    overflow: hidden;
}

.sm-head {
    display: flex;
    align-items: baseline;
    gap: 10px;
    padding: 12px 14px 4px;
    font-family: var(--font-mono);
    min-width: 0;
}

.sm-coin {
    font-size: 15px;
    font-weight: 600;
    letter-spacing: 0.01em;
    color: var(--text);
}

.sm-price {
    font-size: 15px;
    color: var(--text);
    letter-spacing: -0.02em;
}

.sm-since {
    font-size: 13px;
    font-weight: 600;
    color: var(--text-muted);
}

.sm-since.is-up { color: var(--up); }
.sm-since.is-down { color: var(--down); }

.sm-unit {
    margin-left: 5px;
    font-size: 10.5px;
    font-weight: 500;
    color: var(--text-faint);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

.sm-spacer {
    flex: 1 1 auto;
}

.sm-market {
    font-size: 11px;
    color: var(--text-faint);
    white-space: nowrap;
}

.sm-chart {
    position: relative;
    height: 240px;
    padding: 0 4px;
}

.sm-chart .tk-chart {
    width: 100%;
    height: 100%;
    min-height: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
}

.sm-chart .tk-chart-svg {
    min-height: 0;
}

.sm-chart.is-loading {
    margin: 8px 14px;
    height: 224px;
    border-radius: var(--radius-md);
    background: linear-gradient(90deg, var(--surface-2) 0%, var(--surface-3) 50%, var(--surface-2) 100%);
    background-size: 200% 100%;
    animation: sm-shimmer 1.4s linear infinite;
}

@keyframes sm-shimmer {
    from { background-position: 100% 0; }
    to { background-position: -100% 0; }
}

.sm-chart.is-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    height: 160px;
    color: var(--text-faint);
    font-size: var(--fs-md);
}

.sm-chart.is-empty i {
    font-size: 20px;
}

.sm-stats {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    border-top: 1px solid var(--border);
}

.sm-stat {
    display: flex;
    flex-direction: column;
    gap: 3px;
    padding: 10px 12px;
    border-right: 1px solid var(--border);
    min-width: 0;
}

.sm-stat:last-child {
    border-right: 0;
}

.sm-stat-label {
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 500;
    color: var(--text-faint);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    white-space: nowrap;
}

.sm-stat-value {
    font-family: var(--font-mono);
    font-size: 14px;
    font-weight: 600;
    letter-spacing: -0.02em;
    color: var(--text-muted);
    white-space: nowrap;
}

.sm-stat-value.is-up { color: var(--up); }
.sm-stat-value.is-down { color: var(--down); }

.sm-stat.is-peak {
    background: var(--tint-8);
}

/* ---- a phone's row: a small reaction for each coin under the headline (src/index.js getDiv) */
.news-reactions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    order: 1;
    margin-top: 2px;
}

.news-reactions .rx-mini {
    flex: 0 0 auto;
    width: auto;
    flex-direction: row;
    align-items: center;
    gap: 8px;
    padding: 4px 8px;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    background: var(--tint-8);
}

.news-reactions .rx-mini .rx-top {
    flex: 0 0 auto;
    gap: 6px;
}

.news-reactions .rx-coin {
    font-size: 10.5px;
}

.news-reactions .rx-pct {
    font-size: 12px;
}

/* ---- a reaction without its card: in a Big card (a line), or one pick in a story page's list of coins */
.rx-mini {
    width: auto;
    cursor: default;
}

.rx-mini:hover {
    background: transparent;
    border-color: transparent;
    box-shadow: none;
}

.rx-mini.is-selectable {
    cursor: pointer;
    border-color: transparent;
    background: var(--tint-8);
    padding: 7px 9px 6px;
}

.rx-mini.is-selectable:hover {
    background: var(--surface-2);
    border-color: var(--border-strong);
}

.rx-mini.is-selectable.is-active {
    background: var(--surface-2);
    border-color: var(--text-faint);
    box-shadow: inset 0 0 0 1px var(--text-faint);
}

.story-reactions {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(116px, 1fr));
    gap: 6px;
}

.story-label-note {
    font-size: 11px;
    color: var(--text-faint);
}

/* the story panel's way into the coin view */
.sm-focus {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    height: 24px;
    padding: 0 9px;
    margin-left: 4px;
    border-radius: 6px;
    border: 1px solid var(--border-strong);
    background: transparent;
    color: var(--text-muted);
    font-family: var(--font-ui);
    font-size: 11.5px;
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
    transition: color 140ms ease, border-color 140ms ease, background 140ms ease;
    align-self: center;
}

.sm-focus:hover {
    color: var(--text);
    border-color: var(--accent);
    background: var(--accent-soft);
}

/* ---- the coin view (ticker.js CoinFocus): one coin's price with its stories on it */
.coin-focus {
    margin: var(--gutter) var(--gutter) 0;
    display: flex;
    flex-direction: column;
    background: var(--surface);
    border-radius: var(--radius-panel);
    overflow: hidden;
    flex: 0 0 auto;
    animation: tn-rise 220ms cubic-bezier(0.2, 0.7, 0.2, 1);
}


.cf-head {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 12px 12px 4px 16px;
    min-width: 0;
    flex-wrap: wrap;
}

.cf-id {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
}

.cf-coin {
    font-family: var(--font-mono);
    font-size: 18px;
    font-weight: 600;
    letter-spacing: 0.01em;
    line-height: 1.1;
}

.cf-market {
    font-family: var(--font-mono);
    font-size: 10.5px;
    color: var(--text-faint);
    white-space: nowrap;
}

.cf-price {
    font-family: var(--font-mono);
    font-size: 24px;
    font-weight: 500;
    letter-spacing: -0.03em;
    color: var(--text);
}

.cf-change {
    font-family: var(--font-mono);
    font-size: 14px;
    font-weight: 600;
    color: var(--text-muted);
}

.cf-change.is-up { color: var(--up); }
.cf-change.is-down { color: var(--down); }

.cf-change-unit {
    margin-left: 6px;
    font-size: 10.5px;
    font-weight: 500;
    color: var(--text-faint);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

.cf-day {
    display: inline-flex;
    align-items: baseline;
    gap: 14px;
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--text-muted);
    white-space: nowrap;
}

.cf-day-label {
    margin-right: 6px;
    font-family: var(--font-ui);
    font-size: 10.5px;
    color: var(--text-faint);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

.cf-spacer {
    flex: 1 1 auto;
}

.cf-ranges {
    display: inline-flex;
    padding: 2px;
    gap: 2px;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-control);
    background: var(--surface-2);
}

.cf-range {
    height: 24px;
    padding: 0 10px;
    border-radius: 5px;
    color: var(--text-muted);
    font-family: var(--font-mono);
    font-size: 11.5px;
    font-weight: 500;
    cursor: pointer;
    transition: background 140ms ease, color 140ms ease;
}

.cf-range:hover {
    color: var(--text);
}

.cf-range.is-active {
    background: var(--surface-3);
    color: var(--text);
    box-shadow: 0 1px 0 rgba(255, 255, 255, 0.04) inset, 0 1px 2px rgba(0, 0, 0, 0.3);
}

.cf-body {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 280px;
    min-height: 0;
}

.cf-chart {
    position: relative;
    height: 220px;
    min-width: 0;
}

.cf-svg {
    display: block;
    width: 100%;
    height: 100%;
    overflow: visible;
}

.cf-grid line {
    stroke: var(--border);
    stroke-width: 1;
    shape-rendering: crispEdges;
}

.cf-axis text {
    fill: var(--text-faint);
    font-family: var(--font-mono);
    font-size: 10.5px;
}

.cf-line {
    fill: none;
    stroke: var(--text-muted);
    stroke-width: 1.75;
    stroke-linejoin: round;
    stroke-linecap: round;
}

.cf-line.is-up { stroke: var(--up); }
.cf-line.is-down { stroke: var(--down); }

.cf-grad-top { stop-color: var(--text-faint); stop-opacity: 0.14; }
.cf-grad-top.is-up { stop-color: var(--up); stop-opacity: 0.22; }
.cf-grad-top.is-down { stop-color: var(--down); stop-opacity: 0.2; }
.cf-grad-bottom { stop-color: var(--surface); stop-opacity: 0; }

.cf-rug line {
    stroke: var(--text-faint);
    stroke-width: 1.5;
    opacity: 0.7;
}

.cf-rug line.is-big {
    stroke: var(--big);
    opacity: 1;
}

/* a story on the line: a dot ringed with the panel colour; Big stories gold and lit */
.cf-dot {
    fill: var(--text);
    stroke: var(--surface);
    stroke-width: 2;
    transform-box: fill-box;
    transform-origin: center;
    transition: transform 120ms ease;
}

.cf-dot.is-big {
    fill: var(--big);
}

.cf-dot.is-hover {
    transform: scale(1.6);
}

.cf-now line {
    stroke: var(--text-faint);
    stroke-width: 1;
    stroke-dasharray: 2 3;
    opacity: 0.6;
}

.cf-now rect {
    fill: var(--surface-3);
}

.cf-now.is-up rect { fill: var(--up); }
.cf-now.is-down rect { fill: var(--down); }

.cf-now text {
    fill: var(--text);
    font-family: var(--font-mono);
    font-size: 10.5px;
    font-weight: 600;
}

.cf-now.is-up text,
.cf-now.is-down text {
    fill: #05070a;
}

.cf-cross {
    stroke: var(--text-faint);
    stroke-width: 1;
    stroke-dasharray: 2 3;
    pointer-events: none;
}

.cf-tip {
    position: absolute;
    z-index: 3;
    width: 300px;
    max-width: calc(100% - 24px);
    padding: 10px 12px;
    background: var(--surface-raised);
    border: 1px solid var(--border-strong);
    border-radius: 10px;
    box-shadow: var(--shadow-2);
    pointer-events: none;
    display: flex;
    flex-direction: column;
    gap: 5px;
}

.cf-tip.is-right { transform: translate(14px, -50%); }
.cf-tip.is-left { transform: translate(calc(-100% - 14px), -50%); }

.cf-tip.is-big {
    border-color: rgba(247, 181, 59, 0.45);
    box-shadow: var(--shadow-2);
}

.cf-tip.is-price {
    width: auto;
    flex-direction: row;
    align-items: baseline;
    gap: 10px;
    padding: 6px 10px;
    transform: translate(10px, 0);
}

.cf-tip.is-price.is-left {
    transform: translate(calc(-100% - 10px), 0);
}

.cf-tip-meta {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 11px;
    color: var(--text-faint);
    min-width: 0;
}

.cf-tip-source {
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-size: 10.5px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cf-tip-time,
.cf-tip-price {
    font-family: var(--font-mono);
    white-space: nowrap;
}

.cf-tip-price {
    font-size: 13px;
    color: var(--text);
}

.cf-tip-title {
    font-size: 13.5px;
    font-weight: 500;
    line-height: 1.4;
    color: var(--text);
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.cf-tip-foot {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 11px;
    color: var(--text-faint);
}

.cf-tip-move {
    font-family: var(--font-mono);
    font-weight: 600;
    font-size: 12px;
}

.cf-tip-move span {
    font-family: var(--font-ui);
    font-weight: 400;
    font-size: 11px;
    color: var(--text-faint);
}

.cf-tip-move.is-up { color: var(--up); }
.cf-tip-move.is-down { color: var(--down); }

.cf-loading {
    position: absolute;
    inset: 16px 70px 34px 12px;
    border-radius: var(--radius-md);
    background: linear-gradient(90deg, var(--surface-2) 0%, var(--surface-3) 50%, var(--surface-2) 100%);
    background-size: 200% 100%;
    animation: sm-shimmer 1.4s linear infinite;
}

.cf-empty {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    color: var(--text-faint);
    font-size: var(--fs-md);
}

.cf-side {
    display: flex;
    flex-direction: column;
    border-left: 1px solid var(--border);
    min-width: 0;
}

.cf-stat {
    display: flex;
    flex-direction: column;
    gap: 3px;
    padding: 11px 14px;
    border: 0;
    border-bottom: 1px solid var(--border);
    background: transparent;
    color: var(--text);
    font: inherit;
    text-align: left;
    min-width: 0;
}

.cf-stat:last-child {
    border-bottom: 0;
}

.cf-stat.is-link {
    cursor: pointer;
    transition: background 140ms ease;
}

.cf-stat.is-link:hover {
    background: var(--surface-2);
}

.cf-stat-label {
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-faint);
}

.cf-stat-value {
    font-family: var(--font-mono);
    font-size: 18px;
    font-weight: 600;
    letter-spacing: -0.02em;
    color: var(--text);
}

.cf-stat-value.is-up { color: var(--up); }
.cf-stat-value.is-down { color: var(--down); }

.cf-stat-title {
    font-size: 12.5px;
    line-height: 1.4;
    color: var(--text-muted);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.cf-stat.is-link:hover .cf-stat-title {
    color: var(--text);
}

/* ---- "Today's biggest stories": the news desk's picks of the last 24 hours as cards above the columns */
.big-strip {
    margin: var(--gutter) var(--gutter) 0;
    flex: 0 0 auto;
    /* the gold wash of Big, faint (2026-10-04: "the yellow on the top stories was ok") */
    background: linear-gradient(180deg, var(--big-soft), transparent 75%), var(--surface);
    border-radius: var(--radius-panel);
    overflow: hidden;
}

.big-strip-head {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px 4px 14px;
    min-width: 0;
}

.big-strip-title {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: -0.01em;
    white-space: nowrap;
}

.big-strip-title i {
    color: var(--big);
}

.big-strip-count {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--text-faint);
}

.big-strip-latest {
    font-size: 12.5px;
    color: var(--text-muted);
    min-width: 0;
}

.big-strip-spacer {
    flex: 1 1 auto;
}

.big-strip.is-folded .big-strip-head {
    padding-bottom: 6px;
}

/* one row of cards filling the width: src/index.js FillRow sets how many columns fit (TOP_CARD_MIN, TOP_CARD_GAP) */
.big-strip-cards {
    display: grid;
    gap: 8px;
    padding: 4px 14px 12px;
}

/* phones: every card, on a line that scrolls sideways */
.big-strip-cards.is-scroll {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    scrollbar-width: thin;
}

.big-card {
    position: relative;
    flex: 0 0 290px;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 7px;
    min-height: 112px;
    padding: 10px 12px 10px 14px;
    border: 1px solid transparent;
    border-radius: 10px;
    background: var(--surface-2);
    color: var(--text);
    font: inherit;
    text-align: left;
    cursor: pointer;
    scroll-snap-align: start;
    overflow: hidden;
    transition: border-color 140ms ease, transform 140ms ease, box-shadow 140ms ease, background 140ms ease;
}

/* the gold edge every Big row has, here as the card's left side (a story the desk rated but did not post: none) */
.big-card.is-big::before {
    content: "";
    position: absolute;
    left: 0;
    top: 10px;
    bottom: 10px;
    width: 2px;
    border-radius: 0 2px 2px 0;
    background: var(--big);
}

.big-card:hover {
    color: var(--text);
}

.big-card:hover,
.big-card.is-open {
    background: var(--surface-3);
}

.big-card-meta {
    display: flex;
    align-items: center;
    gap: 7px;
    min-width: 0;
    font-size: 11px;
}

.big-card-meta .source-logo,
.big-card-meta .news-source-fallback {
    width: 16px;
    height: 16px;
    flex: 0 0 16px;
    border-radius: 4px;
    font-size: 9px;
}

.big-card-source {
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-size: 10.5px;
    color: var(--text-muted);
    min-width: 0;
}

/* a person (a post) keeps their name as written */
.big-card-source.is-person,
.cf-tip-source.is-person {
    text-transform: none;
    letter-spacing: 0;
    font-size: 12px;
    color: var(--text);
}

/* the plan a wire's card comes live with (wirePlanOf): Sprout for Headlines, Sapling for Headlines+ */
.big-card-plan {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    font-size: 10.5px;
    font-weight: 600;
    color: var(--accent-text);
    white-space: nowrap;
}

.big-card-plan i {
    font-size: 11px;
}

.big-card-time {
    margin-left: auto;
    font-family: var(--font-mono);
    color: var(--text-faint);
    white-space: nowrap;
}

.big-card-title {
    font-size: 13.5px;
    font-weight: 500;
    line-height: 1.38;
    letter-spacing: -0.01em;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* the card's move: a pill as wide as what it says (coin, move, the line), like the phone rows' ("this should be a
   pill, not a whole width thing") */
.big-card .rx-mini {
    margin-top: auto;
    align-self: flex-start;
    flex: 0 0 auto;
    width: auto;
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    gap: 8px;
    padding: 4px 8px;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    background: var(--tint-8);
}

.big-card .rx-mini .rx-top {
    gap: 8px;
}

/* ---- a day's top stories (/top/<YYYY-MM-DD>, src/index.js dayPageBody): ranked rows, the days around it */
.big-strip-more {
    font-size: 12px;
    color: var(--text-muted);
    text-decoration: none;
    padding: 2px 6px;
    border-radius: 6px;
}

.big-strip-more:hover {
    color: var(--text);
    background: var(--hover);
}

/* the Stocks feed (src/index.js stocksCol): the free plan's delay, said where "Live" is */
.feed-delay-note {
    font-size: 12px;
    color: var(--text-muted);
    text-decoration: none;
    padding: 2px 8px;
    border: 1px solid var(--border);
    border-radius: 999px;
    white-space: nowrap;
}

.feed-delay-note:hover {
    color: var(--text);
    border-color: var(--border-strong);
}

/* the strip's alert bell: gold while top story alerts are on */
.big-strip-alert.is-on {
    color: var(--big);
}

.day-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    margin: 6px 0 16px;
}

.day-title {
    font-size: 28px;
    font-weight: 600;
    letter-spacing: -0.02em;
    margin: 2px 0 4px;
}

.day-sub {
    color: var(--text-muted);
    font-size: 13.5px;
    margin: 0;
}

.day-nav {
    display: flex;
    gap: 6px;
}

.day-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.day-item {
    display: grid;
    grid-template-columns: 30px minmax(0, 1fr);
    align-items: start;
}

.day-rank {
    font-family: var(--font-mono);
    font-size: 14px;
    color: var(--text-faint);
    padding: 12px 8px 0 0;
    text-align: right;
}

/* the day's first three: the gold Big wears */
.day-item:nth-child(-n+3) .day-rank {
    color: var(--big);
}

/* ---- a story's own page (/news/<slug>?id=<id>, src/index.js storyPageBody): the story and its market on the left, what to
   read next on the right. It is a layer over the feed, which stays where it was underneath (its place, its live socket). */
.story-layer {
    position: fixed;
    top: var(--topbar-h);
    left: var(--rail-w);
    right: 0;
    bottom: 0;
    z-index: 80;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 20px 24px 48px;
    background: var(--page-glow), var(--bg);
    background-attachment: fixed;
    animation: tn-fade 160ms ease-out;
}
.story-page {
    display: flex;
    flex-direction: column;
    gap: 12px;
    max-width: 1180px;
    margin: 0 auto;
}

.sp-back {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    align-self: flex-start;
    height: 28px;
    padding: 0 10px 0 6px;
    border-radius: var(--radius-control);
    color: var(--text-muted);
    font-size: var(--fs-md);
    font-weight: 500;
    transition: background 140ms ease, color 140ms ease;
}

.sp-back:hover {
    color: var(--text);
    background: var(--surface-2);
}

.sp-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 340px;
    gap: 16px;
    align-items: start;
}

.sp-main,
.sp-side {
    display: flex;
    flex-direction: column;
    gap: 16px;
    min-width: 0;
}

.sp-side {
    position: sticky;
    top: 0;
}

.sp-article {
    position: relative;
    gap: 16px;
    padding: 24px 28px;
    overflow: hidden;
}

.sp-article.is-big::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 3px;
    background: var(--big);
}


.sp-source {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    min-width: 0;
    font-size: var(--fs-md);
}

.sp-source .source-logo,
.sp-source .news-source-fallback {
    width: 24px;
    height: 24px;
    flex: 0 0 24px;
}

.sp-source-name {
    font-weight: 600;
    color: var(--text);
}

.sp-handle,
.sp-sep {
    color: var(--text-faint);
}

.sp-time {
    font-family: var(--font-mono);
    font-size: var(--fs-sm);
    color: var(--text-muted);
}

.sp-ago {
    font-family: var(--font-mono);
    font-size: var(--fs-sm);
    color: var(--text-faint);
}

.sp-title {
    margin: 0;
    font-size: 28px;
    font-weight: 600;
    line-height: 1.25;
    letter-spacing: -0.02em;
    color: var(--text);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

/* a post reads as prose */
.sp-title.is-post {
    font-size: 20px;
    font-weight: 400;
    line-height: 1.55;
    letter-spacing: -0.005em;
}

.sp-title a {
    color: var(--accent-text);
}

/* a blog's summary on its page: the model's 2 or 3 lines from the article (server.js blogSummaryOf) */
.sp-summary {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 14px 16px;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--tint-8);
}

.sp-summary ul {
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.sp-summary li {
    position: relative;
    padding-left: 16px;
    font-size: 15px;
    line-height: 1.55;
    color: var(--text);
}

.sp-summary li::before {
    content: "";
    position: absolute;
    left: 2px;
    top: 0.62em;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--accent);
}

/* Tree News's own story (server tree_stories.js): what each follow-up changed, above the article, and its sources under it */
.sp-updates {
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-size: 14px;
    line-height: 1.55;
    color: var(--text);
}

.sp-updates p {
    margin: 0;
}

.sp-updates b {
    color: var(--accent-text);
    font-weight: 600;
}

/* its sources: one line at the foot, only what the text does not already link (2026-10-10: "should be a footer at most") */
.sp-sources {
    font-size: 13px;
    line-height: 1.6;
    color: var(--text-muted);
    opacity: 0.85;
    overflow-wrap: anywhere;
}

.sp-sources a {
    color: var(--accent-text);
}

/* its formatting: a subheading, a list of parallel facts, the figure or two it turns on, the links where it quotes */
.sp-story h2.sp-sub {
    margin: 4px 0 -4px;
    font-size: 16px;
    font-weight: 600;
    line-height: 1.4;
    color: var(--text);
}

.sp-story ul {
    margin: 0;
    padding-left: 20px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.sp-story strong {
    font-weight: 600;
    color: var(--text);
}

/* a post on X shown as itself in the story: the site's quote card, set off from the prose */
.sp-story .sp-embed {
    margin: 2px 0;
    max-width: 560px;
}

/* the story's picture, the money's path on the chain, whole at any width (a flow is read end to end, never cropped) */
.sp-story .sp-figure {
    margin: 2px 0;
}

.sp-story .sp-figure img {
    display: block;
    width: 100%;
    height: auto;
    border: 1px solid var(--border);
    border-radius: 12px;
}

.sp-embed-foot {
    display: flex;
    gap: 10px;
    align-items: baseline;
    margin-top: 8px;
    font-size: 12.5px;
    color: var(--text-muted);
}

.sp-embed-foot a {
    color: var(--accent-text);
}

/* a press item's article under its headline (page and panel) */
.sp-body,
.story-body {
    display: flex;
    flex-direction: column;
    gap: 12px;
    font-size: 15px;
    line-height: 1.65;
    color: var(--text-muted);
    overflow-wrap: anywhere;
}

.story-body {
    font-size: 14px;
    gap: 10px;
}

.sp-body p,
.story-body p {
    margin: 0;
}

.sp-body a,
.story-body a {
    color: var(--accent-text);
}

.sp-image {
    max-height: 480px;
}

.sp-actions {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    padding-top: 4px;
}

.sp-actions .story-votes {
    margin-left: auto;
}

.sp-market {
    gap: 12px;
    padding: 18px 20px 20px;
}

.sp-list {
    padding: 6px 0;
}

/* "When this happened before" (src/index.js analogsSection): the summary line over the earlier stories */
.sp-analogs {
    margin-top: var(--gutter);
}

.sp-analogs-sum {
    margin: 0;
    padding: 0 16px 8px;
    font-size: 14px;
    line-height: 1.5;
    color: var(--text-muted);
}

.sp-analogs-sum b {
    color: var(--text);
    font-weight: 600;
}

.sp-analogs-pct {
    font-family: var(--font-mono);
    font-weight: 500;
    color: var(--text);
}

.sp-analogs-pct.is-up {
    color: var(--up);
}

.sp-analogs-pct.is-down {
    color: var(--down);
}

.sp-list-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 8px 16px 6px;
}

.sp-list-link {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 12px;
    font-weight: 600;
    color: var(--text-muted);
}

.sp-list-link:hover {
    color: var(--accent-text);
}

.sp-item {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 10px 16px;
    border-top: 1px solid var(--border);
    color: var(--text);
    transition: background 140ms ease;
}

.sp-item:hover {
    background: var(--surface-2);
    color: var(--text);
}

.sp-item-meta {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    font-size: 11px;
    color: var(--text-faint);
}

.sp-item-time {
    font-family: var(--font-mono);
    flex: 0 0 auto;
}

.sp-item-source {
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-size: 10.5px;
    color: var(--text-muted);
    min-width: 0;
}

.sp-item-source.is-person {
    text-transform: none;
    letter-spacing: 0;
    font-size: 11.5px;
}

.sp-item-move {
    margin-left: auto;
    flex: 0 0 auto;
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 600;
}

.sp-item-move.is-up { color: var(--up); }
.sp-item-move.is-down { color: var(--down); }

.sp-item-title {
    font-size: 13.5px;
    font-weight: 500;
    line-height: 1.4;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.story-page.is-missing .empty {
    margin-top: 10vh;
}

@media (max-width: 1000px) {
    .sp-layout {
        grid-template-columns: minmax(0, 1fr);
    }

    .sp-side {
        position: static;
    }
}

@media (max-width: 700px) {
    .sp-article {
        padding: 18px 16px;
    }

    .sp-title {
        font-size: 22px;
    }

    .sp-title.is-post {
        font-size: 17px;
    }

    .story-layer {
        left: 0;
        bottom: var(--bottombar-h);
        padding: 12px 12px 32px;
    }

    .sp-market {
        padding: 14px 12px 16px;
    }

    .sm-stat {
        padding: 9px 7px;
    }

    .sm-stat-value {
        font-size: 13px;
    }

    .sm-stat-label {
        letter-spacing: 0.04em;
    }
}

/* rows open their story panel on click (outside their links and buttons); the open one stays marked */
.news-row {
    cursor: pointer;
}

.news-row.is-open {
    background: var(--surface-2);
}

.news-row.is-open::before {
    background: var(--accent);
}

/* a story's source line (its page) */
.story-source {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    font-size: var(--fs-md);
    font-weight: 600;
}

.story-source .source-logo,
.story-source .news-source-fallback {
    width: 20px;
    height: 20px;
    flex: 0 0 20px;
}

.story-handle {
    color: var(--text-muted);
    font-weight: 400;
    white-space: nowrap;
}

.story {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.story-badges {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
}

.story-title {
    margin: 0;
    font-size: 21px;
    font-weight: 600;
    line-height: 1.32;
    letter-spacing: -0.02em;
    color: var(--text);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

/* a post reads as prose */
.story.is-post .story-title {
    font-size: var(--fs-lg);
    font-weight: 400;
    line-height: 1.6;
    letter-spacing: 0;
}

.story-title a,
.story-quote a {
    color: var(--accent-text);
}

.story-title a:hover,
.story-quote a:hover {
    text-decoration: underline;
}

.story-time {
    display: flex;
    align-items: center;
    gap: 6px;
    font-family: var(--font-mono);
    font-size: var(--fs-sm);
    color: var(--text-muted);
}

.story-time i {
    font-size: 12px;
    color: var(--text-faint);
}

.story-time-sep {
    color: var(--text-faint);
}

.story-quote {
    margin: 0;
    padding: 10px 12px;
    border-left: 2px solid var(--border-strong);
    border-radius: 0 var(--radius-md) var(--radius-md) 0;
    background: var(--surface-2);
    font-size: var(--fs-md);
    line-height: 1.55;
    color: var(--text-muted);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.story-quote .news-source-name {
    color: var(--text);
}

.story-image-link {
    display: block;
}

.story-image {
    display: block;
    width: 100%;
    max-height: 360px;
    object-fit: contain;
    border-radius: var(--radius-md);
    border: 1px solid var(--border);
    background: var(--surface-2);
}

.story-section {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.story-label {
    font-size: var(--fs-xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted);
}

.story-coins {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.story-foot {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
}

.story-votes {
    display: inline-flex;
    align-items: center;
    gap: 1px;
    margin-left: auto;
}

/* tweet-specific: a post is prose, so regular weight (news headlines are medium) */
.tweet-row .news-title {
    font-weight: 400;
}

.tweet-card {
    margin-top: 4px;
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface-2);
}

.tweet-stats {
    display: flex;
    gap: 12px;
    font-family: var(--font-mono);
    font-size: var(--fs-xs);
    color: var(--text-faint);
}

/* ---------------------------------------------------------------------
   9b. FEED - density, market strip, sparklines, keyboard help
   --------------------------------------------------------------------- */

/* --- density toggle -------------------------------------------------
   Default = comfortable. Add .is-compact to .feed (or .feed-col, or the
   row itself) to switch the whole column to the dense variant.        */
.feed.is-comfortable .news-row {
    padding: 7px 10px 7px 13px;
}

.feed.is-compact .news-row,
.feed-col.is-compact .news-row,
.news-row.is-compact {
    grid-template-columns: 52px 18px minmax(0, 1fr) auto;
    column-gap: 8px;
    padding: 3px 10px 3px 13px;
}

/* compact = one line per item: time, logo, source, the headline cut with an ellipsis, coins, votes (phones keep their
   two lines: time and source, then the headline) */
.feed.is-compact .news-body,
.feed-col.is-compact .news-body,
.news-row.is-compact .news-body {
    flex-direction: row;
    align-items: center;
    gap: 6px;
}

.feed.is-compact .news-head,
.feed-col.is-compact .news-head,
.news-row.is-compact .news-head {
    flex: 0 0 auto;
    flex-wrap: nowrap;
    max-width: 40%;
    overflow: hidden;
    line-height: 16px;
    min-height: 16px;
    gap: 4px;
}

.feed.is-compact .news-title,
.feed-col.is-compact .news-title,
.news-row.is-compact .news-title {
    flex: 1 1 auto;
    min-width: 0;
    display: block;
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
    font-size: var(--fs-md);
    line-height: 20px;
    /* beats the legacy inline -webkit-line-clamp on .news-title */
    -webkit-line-clamp: 1 !important;
}

.feed.is-compact .news-metrics,
.feed-col.is-compact .news-metrics,
.news-row.is-compact .news-metrics,
.feed.is-compact .news-image-link,
.feed-col.is-compact .news-image-link,
.news-row.is-compact .news-image-link {
    display: none;
}

/* ...except a post that is only a picture: there it is the post, so it stays, as a thumbnail */
.feed.is-compact .news-row.is-image-only .news-image-link,
.feed-col.is-compact .news-row.is-image-only .news-image-link,
.news-row.is-compact.is-image-only .news-image-link {
    display: block;
}
.feed.is-compact .news-row.is-image-only .news-image,
.feed-col.is-compact .news-row.is-image-only .news-image,
.news-row.is-compact.is-image-only .news-image {
    display: block;
    max-height: 96px;
    width: auto;
    max-width: 100%;
}

.feed.is-compact .news-time,
.feed-col.is-compact .news-time,
.news-row.is-compact .news-time {
    font-size: 11px;
    line-height: 17px;
    flex-direction: row;
    gap: 5px;
    align-items: baseline;
}

.feed.is-compact .news-time-ago,
.feed-col.is-compact .news-time-ago,
.news-row.is-compact .news-time-ago {
    display: none;
}

.feed.is-compact .news-source,
.feed-col.is-compact .news-source,
.news-row.is-compact .news-source {
    height: 17px;
}

.feed.is-compact .news-source .source-logo,
.feed-col.is-compact .news-source .source-logo,
.news-row.is-compact .news-source .source-logo,
.feed.is-compact .news-source-fallback,
.feed-col.is-compact .news-source-fallback,
.news-row.is-compact .news-source-fallback {
    width: 16px;
    height: 16px;
    flex-basis: 16px;
}

.feed.is-compact .news-quote,
.feed-col.is-compact .news-quote,
.news-row.is-compact .news-quote,
.feed.is-compact .news-image,
.feed-col.is-compact .news-image,
.news-row.is-compact .news-image,
.feed.is-compact .news-images,
.feed-col.is-compact .news-images,
.news-row.is-compact .news-images {
    display: none;
}

.feed.is-compact .news-text,
.feed-col.is-compact .news-text,
.news-row.is-compact .news-text {
    font-size: 12.5px;
    line-height: 1.35;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.feed.is-compact .news-meta,
.feed-col.is-compact .news-meta,
.news-row.is-compact .news-meta {
    flex: 0 0 auto;
    flex-wrap: nowrap;
    max-width: 35%;
    overflow: hidden;
    gap: 3px 4px;
    margin-top: 0;
}

.feed.is-compact .ticker-chip,
.feed-col.is-compact .ticker-chip,
.news-row.is-compact .ticker-chip {
    height: 17px;
    gap: 4px;
    padding: 0 4px 0 5px;
    font-size: 10px;
}

.feed.is-compact .vote,
.feed-col.is-compact .vote,
.news-row.is-compact .vote,
.feed.is-compact .news-action-btn,
.feed-col.is-compact .news-action-btn,
.news-row.is-compact .news-action-btn {
    width: 20px;
    height: 20px;
    flex-basis: 20px;
}

.feed.is-compact .news-day,
.feed-col.is-compact .news-day {
    padding: 2px 12px;
}

/* --- market strip (toolbar-friendly, place agnostic) ---------------- */
.market-strip {
    display: flex;
    align-items: stretch;
    height: var(--control-h-sm);
    min-width: 0;
    max-width: 100%;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
    -ms-overflow-style: none;
    border: 1px solid var(--border);
    border-radius: var(--radius-control);
    background: var(--surface-2);
    flex: 0 1 auto;
}

.market-strip::-webkit-scrollbar {
    display: none;
}

/* toolbar strip with no tile that fits the row: gone rather than crowding the toolbar onto a second line */
.market-strip.is-collapsed {
    display: none;
}

.market-tile {
    display: flex;
    align-items: center;
    gap: 5px;
    flex: 0 0 auto;
    padding: 0 9px;
    border-right: 1px solid var(--border);
    white-space: nowrap;
    transition: background 140ms ease;
}

.market-tile:last-child {
    border-right: 0;
}

.market-tile.is-clickable,
a.market-tile,
button.market-tile {
    cursor: pointer;
}

.market-tile.is-clickable:hover,
a.market-tile:hover,
button.market-tile:hover {
    background: var(--surface-3);
}

.market-tile-label,
.mk-label {
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-faint);
}

.market-tile-price,
.mk-price {
    font-family: var(--font-mono);
    font-size: 13px;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.02em;
    color: var(--text);
}

.market-tile-change,
.mk-change {
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.01em;
    color: var(--text-muted);
}

.market-tile-change.up,
.market-tile-change.is-up,
.mk-change.up,
.mk-change.is-up { color: var(--up); }

.market-tile-change.down,
.market-tile-change.is-down,
.mk-change.down,
.mk-change.is-down { color: var(--down); }

.market-tile.is-up .market-tile-price,
.market-tile.is-up .mk-price { color: var(--text); }

.market-tile.is-flash-up .market-tile-price,
.market-tile.is-flash-up .mk-price { color: var(--up); }

.market-tile.is-flash-down .market-tile-price,
.market-tile.is-flash-down .mk-price { color: var(--down); }

.market-tile-price,
.mk-price {
    transition: color 240ms ease;
}

.market-strip.is-loading .market-tile {
    position: relative;
    overflow: hidden;
}

.market-strip.is-loading .market-tile::after {
    content: "";
    position: absolute;
    inset: 0;
    transform: translateX(-100%);
    background: linear-gradient(90deg, transparent, var(--shimmer-band), transparent);
    animation: tn-shimmer 1.4s infinite;
}

.market-strip .sparkline {
    margin-left: 1px;
}

/* vertical hairline for grouping toolbar controls */
.toolbar-sep {
    width: 1px;
    height: 20px;
    flex: 0 0 auto;
    margin: 0 2px;
    background: var(--border);
}

/* small mono counter for column headers */
/* --- sparkline ------------------------------------------------------ */
.sparkline {
    display: inline-block;
    width: 64px;
    height: 20px;
    line-height: 0;
    vertical-align: middle;
    flex: 0 0 auto;
    color: var(--text-faint);
}

.sparkline > svg {
    display: block;
    width: 100%;
    height: 100%;
    overflow: visible;
}

.sparkline-path {
    fill: none;
    stroke: currentColor;
    stroke-width: 1.25;
    stroke-linecap: round;
    stroke-linejoin: round;
    vector-effect: non-scaling-stroke;
}

.sparkline-area {
    fill: currentColor;
    opacity: 0.12;
    stroke: none;
}

.sparkline-dot {
    fill: currentColor;
    stroke: none;
}

.sparkline-base {
    stroke: var(--border-strong);
    stroke-width: 1;
    stroke-dasharray: 2 2;
    fill: none;
    vector-effect: non-scaling-stroke;
}

.sparkline.is-up { color: var(--up); }
.sparkline.is-down { color: var(--down); }
.sparkline.is-flat { color: var(--text-faint); }

.sparkline-sm { width: 48px; height: 16px; }
.sparkline-lg { width: 96px; height: 28px; }

/* --- feed scrollbars (quieter than the global ones) ----------------- */
.feed-col-body,
.feed-col-body > div,
.feed-side {
    scrollbar-width: thin;
    scrollbar-color: var(--feed-scroll-thumb) transparent;
}

.feed-col-body::-webkit-scrollbar,
.feed-col-body ::-webkit-scrollbar,
.feed-side::-webkit-scrollbar {
    width: 10px;
    height: 10px;
}

.feed-col-body::-webkit-scrollbar-thumb,
.feed-col-body ::-webkit-scrollbar-thumb,
.feed-side::-webkit-scrollbar-thumb {
    background: var(--feed-scroll-thumb);
    border-radius: var(--radius-pill);
    border: 3px solid transparent;
    background-clip: padding-box;
}

.feed-col-body::-webkit-scrollbar-thumb:hover,
.feed-col-body ::-webkit-scrollbar-thumb:hover,
.feed-side::-webkit-scrollbar-thumb:hover {
    background: var(--feed-scroll-thumb-hover);
    border: 3px solid transparent;
    background-clip: padding-box;
}

/* ---------------------------------------------------------------------
   10. SETTINGS
   --------------------------------------------------------------------- */
.settings-layout {
    display: grid;
    grid-template-columns: 220px minmax(0, 1fr);
    gap: var(--sp-6);
    align-items: start;
    width: 100%;
    max-width: var(--content-max);
    margin: 0 auto;
}

.settings-nav {
    position: sticky;
    top: calc(var(--topbar-h) + var(--sp-5));
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 6px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
}

.settings-nav-item {
    display: flex;
    align-items: center;
    gap: 10px;
    height: 34px;
    padding: 0 10px;
    border-radius: var(--radius-md);
    color: var(--text-muted);
    font-size: var(--fs-md);
    font-weight: 500;
    cursor: pointer;
    white-space: nowrap;
    transition: background var(--ease), color var(--ease);
}

.settings-nav-item i {
    width: 16px;
    text-align: center;
    font-size: 13px;
    color: var(--text-faint);
}

.settings-nav-item:hover {
    background: var(--surface-2);
    color: var(--text);
}

.settings-nav-item.active {
    background: var(--accent-soft);
    color: var(--text);
}

.settings-nav-item.active i {
    color: var(--accent-text);
}

.settings-nav-item .badge-count {
    margin-left: auto;
}

.settings-content {
    display: flex;
    flex-direction: column;
    gap: var(--sp-4);
    min-width: 0;
}

.settings-section {
    scroll-margin-top: calc(var(--topbar-h) + var(--sp-4));
}

.settings-section-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--sp-3);
    padding: 14px 16px;
    border-bottom: 1px solid var(--border);
}

.settings-section-title {
    font-size: var(--fs-lg);
    font-weight: 600;
    display: flex;
    align-items: center;
    gap: 8px;
}

.settings-section-title i {
    color: var(--text-muted);
    font-size: 14px;
}

.settings-section-desc {
    font-size: var(--fs-md);
    color: var(--text-muted);
    margin-top: 2px;
}

.settings-section-actions {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    flex: 0 0 auto;
}

.setting-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-4);
    padding: 10px 16px;
    border-bottom: 1px solid var(--border);
    min-height: 48px;
}

.setting-row:last-child {
    border-bottom: 0;
}

.setting-row.is-sub {
    padding-left: 36px;
    background: var(--surface-2);
}

.setting-row.is-disabled {
    opacity: 0.5;
}

.setting-label {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.setting-name {
    font-size: var(--fs-base);
    font-weight: 500;
    color: var(--text);
    display: flex;
    align-items: center;
    gap: 8px;
}

.setting-desc {
    font-size: var(--fs-sm);
    color: var(--text-muted);
}

.setting-control {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    flex: 0 0 auto;
}

.setting-control .input,
.setting-control .select-wrap {
    width: 200px;
}

.setting-control .input-sm {
    width: 120px;
}

/* source lists */
.source-list {
    display: flex;
    flex-direction: column;
}

.list-search {
    position: sticky;
    top: 0;
    z-index: 2;
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    padding: 8px 16px;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
}

.list-search .search {
    max-width: 320px;
}

.source-head {
    display: grid;
    grid-template-columns: 28px minmax(0, 1fr) auto;
    align-items: center;
    gap: 10px;
    height: 28px;
    padding: 0 16px;
    background: var(--surface-2);
    border-bottom: 1px solid var(--border);
    font-size: var(--fs-xs);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-faint);
    position: sticky;
    top: 49px;
    z-index: 1;
}

.source-head.no-search {
    top: 0;
}

.source-row {
    display: grid;
    grid-template-columns: 28px minmax(0, 1fr) auto;
    align-items: center;
    gap: 10px;
    min-height: 36px;
    padding: 0 16px;
    border-bottom: 1px solid var(--border);
    transition: background var(--ease);
}

.source-row:hover {
    background: var(--surface-2);
}

.source-row.is-off {
    opacity: 0.6;
}

.source-row.is-expanded {
    background: var(--surface-2);
}

.source-row:last-child {
    border-bottom: 0;
}

.source-row .source-logo {
    width: 22px;
    height: 22px;
    flex-basis: 22px;
}

.source-name {
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
    font-size: var(--fs-md);
    font-weight: 500;
    overflow: hidden;
}

.source-name > span:first-child {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.source-handle {
    font-size: var(--fs-xs);
    color: var(--text-faint);
    white-space: nowrap;
}

.source-more {
    font-size: var(--fs-xs);
    color: var(--text-muted);
    cursor: pointer;
    white-space: nowrap;
    padding: 2px 6px;
    border-radius: var(--radius-sm);
}

.source-more:hover {
    background: var(--surface-3);
    color: var(--text);
}

.source-controls {
    display: flex;
    align-items: center;
    gap: 4px;
}

.source-cell {
    width: 56px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 56px;
}

.source-cell.wide {
    width: 132px;
    flex-basis: 132px;
}

.source-cell.wide .select-wrap {
    width: 100%;
}

.source-cell.narrow {
    width: 40px;
    flex-basis: 40px;
}

.source-head .source-cell {
    text-align: center;
    font-size: var(--fs-xs);
}

.source-sub {
    grid-column: 1 / -1;
    padding: 8px 0 10px 38px;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    border-top: 1px dashed var(--border);
}

/* sound select small */
.sound-select {
    width: 132px;
}

/* ---------------------------------------------------------------------
   11. ACCOUNT / LEADERBOARD / CLAIM
   --------------------------------------------------------------------- */
.profile-header {
    display: flex;
    align-items: center;
    gap: var(--sp-4);
    padding: var(--sp-4);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    flex-wrap: wrap;
}

.profile-avatar {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    object-fit: cover;
    border: 2px solid var(--border-strong);
    background: var(--surface-3);
    flex: 0 0 56px;
}

.profile-info {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
    flex: 1 1 auto;
}

.profile-name {
    font-size: var(--fs-2xl);
    font-weight: 600;
    line-height: 1.1;
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.profile-sub {
    font-size: var(--fs-md);
    color: var(--text-muted);
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.profile-actions {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    flex-wrap: wrap;
}

.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: var(--sp-3);
}

.stat {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 12px 14px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    min-width: 0;
}

.stat.is-accent {
    border-color: rgba(76, 166, 76, 0.4);
    background: var(--accent-soft);
}

.stat-label {
    font-size: var(--fs-xs);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-muted);
    display: flex;
    align-items: center;
    gap: 6px;
}

.stat-value {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    font-size: 24px;
    font-weight: 500;
    line-height: 1.1;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.stat-value.is-accent { color: var(--accent-text); }
.stat-value.is-warn { color: var(--warn); }
.stat-value.is-up { color: var(--up); }
.stat-value.is-down { color: var(--down); }

.stat-sub {
    font-size: var(--fs-sm);
    color: var(--text-faint);
}

.stat-sm .stat-value {
    font-size: 18px;
}

.perks-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--fs-md);
}

.perks-table th,
.perks-table td {
    padding: 8px 12px;
    border-bottom: 1px solid var(--border);
    text-align: center;
    vertical-align: middle;
}

.perks-table th:first-child,
.perks-table td:first-child {
    text-align: left;
}

.perks-table thead th {
    font-size: var(--fs-xs);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    background: var(--surface-2);
}

.perks-table tbody tr:last-child td {
    border-bottom: 0;
}

.perks-table .is-current {
    background: var(--accent-soft);
}

.perks-table .yes { color: var(--up); }
.perks-table .no { color: var(--text-faint); }

.referral-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: var(--sp-3);
    align-items: center;
    padding: 10px 0;
    border-bottom: 1px solid var(--border);
    font-size: var(--fs-md);
}

.referral-row:last-child {
    border-bottom: 0;
}

.referral-code {
    font-family: var(--font-mono);
    font-weight: 600;
    color: var(--accent-text);
    letter-spacing: 0.04em;
}

/* account page: one linked wallet = address · copy · disconnect (red, asks first) */
.wallet-row {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-right: 8px;
}

.wallet-row .wallet-unlink {
    margin-left: 2px;
}

.wallet-confirm {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 2px 4px 2px 8px;
    border: 1px solid var(--danger);
    border-radius: var(--radius-md);
    background: var(--danger-soft);
    color: var(--text);
    font-size: var(--fs-sm);
    white-space: nowrap;
}

.wallet-addr {
    font-family: var(--font-mono);
    font-size: var(--fs-sm);
    color: var(--text-muted);
}

/* leaderboard */
.lb-podium {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--sp-3);
}

.lb-rank {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    color: var(--text-faint);
    width: 36px;
    text-align: right;
}

.lb-rank.r1 { color: var(--warn); font-weight: 600; }
.lb-rank.r2 { color: var(--text-muted); font-weight: 600; }
.lb-rank.r3 { color: #c98a5a; font-weight: 600; }

.lb-user {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

.lb-user .avatar {
    flex: 0 0 auto;
}

.lb-points {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    text-align: right;
    color: var(--text);
    font-weight: 500;
}

/* claim */
.claim-hero {
    text-align: center;
    padding: var(--sp-8) var(--sp-4);
}

.claim-amount {
    font-family: var(--font-mono);
    font-size: 40px;
    font-weight: 500;
    color: var(--accent-text);
    line-height: 1.1;
}

/* ---------------------------------------------------------------------
   12. PAGE MISC
   --------------------------------------------------------------------- */
.page-header {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--sp-4);
    margin-bottom: var(--sp-5);
    flex-wrap: wrap;
}

.page-title {
    font-size: var(--fs-2xl);
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: -0.01em;
    display: flex;
    align-items: center;
    gap: 10px;
}

.page-title i {
    color: var(--text-muted);
    font-size: 16px;
}

.page-subtitle {
    font-size: var(--fs-md);
    color: var(--text-muted);
    margin-top: 4px;
}

.page-actions {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    flex-wrap: wrap;
}

.page-stack {
    display: flex;
    flex-direction: column;
    gap: var(--sp-4);
}

.two-col {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--sp-4);
    align-items: start;
}

.two-col.is-sidebar {
    grid-template-columns: minmax(0, 1fr) 320px;
}

.three-col {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--sp-4);
}

/* prose (tos, docs) */
.prose {
    max-width: 820px;
    font-size: var(--fs-base);
    line-height: 1.6;
    color: var(--text);
}

.prose h1 {
    font-size: var(--fs-3xl);
    font-weight: 600;
    margin: 0 0 var(--sp-4);
    letter-spacing: -0.01em;
}

.prose h2 {
    font-size: var(--fs-xl);
    font-weight: 600;
    margin: var(--sp-6) 0 var(--sp-2);
    padding-top: var(--sp-3);
    border-top: 1px solid var(--border);
}

.prose h3 {
    font-size: var(--fs-lg);
    font-weight: 600;
    margin: var(--sp-4) 0 var(--sp-2);
}

.prose p {
    margin: 0 0 var(--sp-3);
    color: var(--text-muted);
}

.prose ul,
.prose ol {
    margin: 0 0 var(--sp-3) 20px;
    color: var(--text-muted);
}

.prose ul { list-style: disc; }
.prose ol { list-style: decimal; }
.prose li { margin: 4px 0; }
.prose li::marker { color: var(--text-faint); }

.prose a {
    color: var(--accent-text);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.prose strong {
    color: var(--text);
    font-weight: 600;
}

.prose-meta {
    font-size: var(--fs-sm);
    color: var(--text-faint);
    margin-bottom: var(--sp-4);
}

/* toast overrides (react-hot-toast renders inline styles; keep ours above) */
.tn-toast {
    font-family: var(--font-ui);
    font-size: var(--fs-md);
}

/* links list (rail extra / footers) */
.link-list {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.link-list a {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 10px;
    border-radius: var(--radius-md);
    color: var(--text-muted);
    font-size: var(--fs-md);
}

.link-list a i {
    width: 16px;
    text-align: center;
    color: var(--text-faint);
}

.link-list a:hover {
    background: var(--surface-2);
    color: var(--text);
}

/* delay / tier tags shown in topbar */

/* ---------------------------------------------------------------------
   13. RESPONSIVE
   --------------------------------------------------------------------- */
@media (min-width: 1101px) {
    .only-md { display: none; }
}

@media (min-width: 701px) {
    .only-sm { display: none; }
}

@media (max-width: 1100px) {
    .hide-md { display: none; }

    .feed,
    .feed.has-sidebar {
        grid-template-columns: minmax(0, 1fr);
    }

    .feed.is-tabbed .feed-col:not(.is-active) {
        display: none;
    }

    .feed-side {
        display: none;
    }

    .settings-layout {
        grid-template-columns: minmax(0, 1fr);
        gap: var(--sp-4);
    }

    .settings-nav {
        position: static;
        flex-direction: row;
        flex-wrap: nowrap;
        overflow-x: auto;
        scrollbar-width: none;
        padding: 4px;
    }

    .settings-nav::-webkit-scrollbar {
        display: none;
    }

    .settings-nav-item {
        flex: 0 0 auto;
        height: 30px;
    }

    .two-col,
    .two-col.is-sidebar {
        grid-template-columns: minmax(0, 1fr);
    }

    .three-col {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .topbar-center > * {
        max-width: 360px;
    }
}

@media (max-width: 900px) {
    /* rail → bottom tab bar */
    .rail,
    .rail:hover,
    .rail:focus-within {
        top: auto;
        bottom: 0;
        left: 0;
        right: 0;
        width: 100%;
        height: var(--bottombar-h);
        flex-direction: row;
        align-items: stretch;
        border-right: 0;
        border-top: 1px solid var(--border);
        box-shadow: none;
        padding-bottom: env(safe-area-inset-bottom);
        /* the top bar's glass: the page scrolls under it blurred, never through it (the rail's own background is
           transparent, for the desktop) */
        background: var(--surface-glass);
        -webkit-backdrop-filter: blur(18px) saturate(1.5);
        backdrop-filter: blur(18px) saturate(1.5);
    }

    .rail-nav,
    .rail-footer {
        flex-direction: row;
        padding: 0;
        gap: 0;
        flex: 1 1 auto;
        border-top: 0;
        margin: 0;
    }

    /* four equal slots: the three pages, then Plans (or, on a plan, the theme) */
    .rail-nav {
        flex: 3 1 0;
    }

    .rail-footer {
        flex: 1 1 0;
    }

    .rail-extra,
    .rail-group-title,
    .rail-footer .rail-item:not(.rail-theme),
    .rail-item-right {
        display: none;
    }

    .rail-item {
        flex: 1 1 0;
        flex-direction: column;
        justify-content: center;
        gap: 3px;
        height: auto;
        margin: 0;
        padding: 6px 4px;
        border-radius: 0;
        font-size: 10px;
        width: auto;
        min-width: 56px;
    }

    .rail-item.active {
        background: transparent;
    }

    .rail-item.active::before {
        left: 12px;
        right: 12px;
        top: 0;
        bottom: auto;
        width: auto;
        height: 2px;
        border-radius: 0 0 3px 3px;
    }

    .rail-icon {
        font-size: 17px;
        width: auto;
        flex-basis: auto;
    }

    .rail-label,
    .rail:hover .rail-label,
    .rail:focus-within .rail-label {
        opacity: 1;
        transform: none;
        transition: none;
    }

    .app-main {
        padding-left: 0;
        padding-bottom: var(--bottombar-h);
    }

    /* the padding above already keeps the feed clear of the fixed bottom bar */
    .app-main.is-full {
        height: 100vh;
        height: 100dvh;
    }

    .feed,
    .feed-wrap {
        height: calc(100vh - var(--topbar-h) - var(--bottombar-h));
        height: calc(100dvh - var(--topbar-h) - var(--bottombar-h));
    }

    .topbar {
        padding: 0 var(--sp-2);
    }

    .topbar-center {
        display: none;
    }

    .topbar {
        grid-template-columns: auto minmax(0, 1fr);
    }

    .user-pill-text {
        display: none;
    }

    .user-pill {
        padding-right: 4px;
        max-width: none;
    }

    .app-main.is-padded .page-container {
        padding: var(--sp-4) var(--sp-3) var(--sp-6);
    }

    .modal {
        max-height: calc(100vh - 16px);
    }

    .modal-overlay {
        padding: var(--sp-2);
        align-items: flex-end;
    }

    .drawer {
        width: 100vw;
    }

    .calendar-tab {
        top: auto;
        bottom: calc(var(--bottombar-h) + 16px);
    }
}

/* a phone's home page scrolls as one page (src/index.js pageScroll: the list follows the window): the toolbar, the
   welcome and Top stories scroll away above the feed, instead of the feed scrolling in a small box under them */
@media (max-width: 700px) {
    .app.is-page-scroll .app-main.is-full {
        height: auto;
        overflow: visible;
    }

    .app.is-page-scroll .app-main.is-full > .feed-wrap,
    .app.is-page-scroll .feed-wrap > .feed {
        height: auto;
    }

    .app.is-page-scroll .feed-wrap > .feed {
        flex: none;
    }

    .app.is-page-scroll .feed-col {
        overflow: visible;
        overflow: clip;
    }

    .app.is-page-scroll .feed-col-body {
        flex: none;
        overflow: visible;
    }

    .app.is-page-scroll .feed-col-body > div {
        height: auto;
    }

    .app.is-page-scroll .feed-wrap > .toolbar,
    .app.is-page-scroll .feed-col-header {
        position: static;
    }

    /* the window scrolls: the held day sits under the top bar while the column passes */
    .app.is-page-scroll .feed-col-body > .news-day-float {
        position: sticky;
        top: var(--topbar-h);
        height: 0;
    }

    .app.is-page-scroll .news-day-float > .news-day {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
    }

    .app.is-page-scroll .feed-new-pill {
        position: fixed;
        top: calc(var(--topbar-h) + 8px);
    }
}

@media (max-width: 700px) {
    .hide-sm { display: none; }

    .news-row {
        grid-template-columns: 22px auto minmax(0, 1fr);
        grid-template-areas:
            "logo time head"
            "logo body body";
        row-gap: 3px;
        column-gap: 10px;
        padding: 10px 12px 10px 13px;
    }

    /* the market reaction goes under the headline as one strip (before the other coins' chips) */
    .news-actions {
        grid-area: auto / 2 / auto / -1;
        order: 1;
        flex-direction: row;
        align-items: center;
        min-width: 0;
        min-height: 0;
        margin-top: 3px;
    }

    .cf-body {
        grid-template-columns: minmax(0, 1fr);
    }

    .cf-chart {
        height: 150px;
    }

    /* a phone keeps the chart (its dots open the stories) and gives the rest of the screen to the columns */
    .cf-side {
        display: none;
    }

    .cf-head {
        gap: 8px 12px;
        padding: 10px 10px 2px 12px;
    }

    .cf-price {
        font-size: 20px;
    }

    .cf-day {
        display: none;
    }

    .big-card {
        flex-basis: 84%;
        min-height: 0;
        gap: 5px;
        padding: 9px 11px 9px 13px;
    }

    .big-card-title {
        -webkit-line-clamp: 2;
    }

    .big-strip-cards {
        padding: 2px 12px 10px;
    }

    /* no coin: nothing to show there (the hover bar is off on phones) */
    .news-actions:not(.has-reaction) {
        display: none;
    }

    .news-meta {
        order: 2;
    }

    .rx {
        flex-direction: row;
        align-items: center;
        width: 100%;
        gap: 12px;
        padding: 6px 10px;
        border-color: var(--border);
        background: var(--tint-8);
    }

    .rx-top {
        flex: 1 1 auto;
        justify-content: flex-start;
        gap: 10px;
    }

    .rx-spark {
        flex: 0 0 auto;
    }

    .news-body {
        display: contents;
    }

    .news-head {
        grid-area: head;
        min-width: 0;
    }

    .news-body > :not(.news-head) {
        grid-column: 2 / -1;
    }

    .news-time {
        flex-direction: row;
        align-items: baseline;
        gap: 8px;
    }

    .news-title {
        font-size: var(--fs-base);
    }

    /* the hover bar (votes, open, copy link, copy timestamp) is dropped: a tap on the row opens the story panel */
    .news-actions-extra {
        display: none;
    }

    .market-strip {
        max-width: 100%;
    }

    .source-row,
    .source-head {
        padding: 0 12px;
        gap: 8px;
    }

    .source-cell {
        width: 44px;
        flex-basis: 44px;
    }

    .source-cell.wide {
        width: 100px;
        flex-basis: 100px;
    }

    .setting-row {
        flex-direction: column;
        align-items: flex-start;
        gap: var(--sp-2);
        padding: 10px 12px;
    }

    .setting-control {
        width: 100%;
        justify-content: flex-start;
        flex-wrap: wrap;
    }

    .setting-control .input,
    .setting-control .select-wrap {
        width: 100%;
    }

    .card-header,
    .card-body,
    .card-footer,
    .settings-section-header,
    .list-search {
        padding-left: 12px;
        padding-right: 12px;
    }

    .stat-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .stat-value {
        font-size: 20px;
    }

    .three-col {
        grid-template-columns: minmax(0, 1fr);
    }

    .profile-header {
        padding: var(--sp-3);
    }

    .profile-name {
        font-size: var(--fs-xl);
    }

    .page-title {
        font-size: var(--fs-xl);
    }

    .event-item {
        grid-template-columns: 44px minmax(0, 1fr);
    }

    .event-coin {
        grid-column: 2;
    }

    .event-name {
        grid-column: 2;
    }

    .table th,
    .table td {
        padding: 6px 8px;
    }

    .brand-sub {
        display: none;
    }
}

@media (hover: none) {
    /* fingers: every control a little bigger, chips in bars 28 */
    :root {
        --control-h-sm: 32px;
        --control-h-md: 36px;
        --chip-h-md: 28px;
    }

    .vote,
    .chip-remove {
        position: relative;
    }

    /* 32px / 24px tap areas around the small ones */
    .vote::after,
    .chip-remove::after {
        content: "";
        position: absolute;
        inset: -5px;
    }

    /* no hover on touch: a tap on the row opens its story panel, which has every action (the votes too) */
    .news-actions-extra {
        display: none;
    }
}

/* a tap leaves :hover on the rail: the side rail stays closed (on a phone the rail is the full-width bottom bar, and
   this width made it collapse to the left on every tap) */
@media (hover: none) and (min-width: 901px) {
    .rail:hover {
        width: var(--rail-w);
        box-shadow: none;
    }

    .rail:hover .rail-label,
    .rail:hover .rail-item-right,
    .rail:hover .rail-group-title {
        opacity: 0;
    }
}

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms;
        animation-iteration-count: 1;
        transition-duration: 0.01ms;
    }
}

@media print {
    .topbar,
    .rail,
    .calendar-tab,
    .toolbar {
        display: none;
    }

    .app-main {
        padding: 0;
    }
}

/* ---------------------------------------------------------------------
   14. MOTION
   --------------------------------------------------------------------- */
@keyframes tn-spin {
    to { transform: rotate(360deg); }
}

@keyframes tn-fade {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes tn-rise {
    from { opacity: 0; transform: translateY(6px); }
    to { opacity: 1; transform: none; }
}

@keyframes tn-slide-in-right {
    from { transform: translateX(24px); opacity: 0; }
    to { transform: none; opacity: 1; }
}

@keyframes tn-slide-in-left {
    from { transform: translateX(-24px); opacity: 0; }
    to { transform: none; opacity: 1; }
}

@keyframes tn-slide-up {
    from { transform: translateY(24px); opacity: 0; }
    to { transform: none; opacity: 1; }
}

@keyframes tn-flash {
    0% { background: var(--accent-soft); }
    100% { background: transparent; }
}

@keyframes tn-slide {
    0% { left: -40%; }
    100% { left: 100%; }
}

@keyframes tn-shimmer {
    100% { transform: translateX(100%); }
}

/* feed row enters the list */
@keyframes tn-row-in {
    from { opacity: 0; transform: translateY(-4px); }
    to { opacity: 1; transform: none; }
}

/* brief accent wash on items younger than 60s */
@keyframes tn-row-fresh {
    0% { opacity: 1; }
    60% { opacity: 0.8; }
    100% { opacity: 0; }
}

/* micro pill / badge pop-in */
@keyframes tn-pill-in {
    from { opacity: 0; transform: scale(0.85); }
    to { opacity: 1; transform: none; }
}

/* centered floating pill drops in (keeps the -50% centering) */
@keyframes tn-pill-drop {
    from { opacity: 0; transform: translate(-50%, -8px); }
    to { opacity: 1; transform: translate(-50%, 0); }
}

/* price tick flashes */
@keyframes tn-tick-up {
    0% { background-color: var(--up-soft); border-color: var(--up); }
    100% { background-color: transparent; }
}

@keyframes tn-tick-down {
    0% { background-color: var(--down-soft); border-color: var(--down); }
    100% { background-color: transparent; }
}

/* A post on its page, as its platform shows it (src/index.js PostCard): the author, the text as written, @ # $ and links in
   the platform's blue, the picture and the quoted post with rounded borders, the time under it */
.xp {
    --xp-blue: #1d9bf0;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.xp-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

.xp-author {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}

.xp-avatar {
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    overflow: hidden;
    border-radius: 50%;
    background: var(--surface-2);
    color: var(--text-muted);
    font-weight: 600;
}

.xp-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.xp-who {
    display: flex;
    flex-direction: column;
    min-width: 0;
    line-height: 1.25;
}

.xp-name {
    overflow: hidden;
    color: var(--text);
    font-size: 15px;
    font-weight: 700;
    text-overflow: ellipsis;
    white-space: nowrap;
}

a.xp-name:hover {
    text-decoration: underline;
}

.xp-handle {
    overflow: hidden;
    color: var(--text-faint);
    font-size: 15px;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.xp-brand {
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    color: var(--text);
}

.xp-brand:hover {
    background: var(--tint-8);
}

.xp-x {
    width: 20px;
    height: 20px;
    fill: currentColor;
}

.xp-truth {
    font-size: 12px;
    font-weight: 800;
    letter-spacing: -0.02em;
}

.xp-replying {
    margin-top: -6px;
    color: var(--text-faint);
    font-size: 15px;
}

.xp-text {
    margin: 0;
    color: var(--text);
    font-size: 17px;
    font-weight: 400;
    line-height: 1.5;
    letter-spacing: normal;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.xp-link,
.xp-text .xp-link {
    color: var(--xp-blue, #1d9bf0);   /* (feed rows too, outside .xp) */
}

a.xp-link:hover {
    text-decoration: underline;
}

.xp-media {
    display: block;
    overflow: hidden;
    border: 1px solid var(--border);
    border-radius: 16px;
}

.xp-media img {
    display: block;
    width: 100%;
    max-height: 560px;
    object-fit: cover;
}

.xp-quote {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 12px;
    border: 1px solid var(--border);
    border-radius: 16px;
}

/* the post a reply answers: above it, joined by the thread line */
.xp-quote.is-parent {
    position: relative;
    padding: 0 0 4px 0;
    border: 0;
    border-radius: 0;
}

.xp-quote.is-parent::before {
    position: absolute;
    top: 30px;
    bottom: -14px;
    left: 13px;
    width: 2px;
    background: var(--border-strong);
    content: "";
}

.xp-quote.is-parent .xp-quote-text {
    padding-left: 38px;
}

.xp-author.is-small .xp-avatar {
    width: 28px;
    height: 28px;
    font-size: 12px;
}

.xp-author.is-small .xp-who {
    flex-direction: row;
    gap: 6px;
}

.xp-author.is-small .xp-name,
.xp-author.is-small .xp-handle {
    font-size: 14px;
}

.xp-quote-text {
    color: var(--text);
    font-size: 15px;
    line-height: 1.45;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.xp-quote-media {
    display: block;
    width: 100%;
    max-height: 320px;
    border-radius: 12px;
    object-fit: cover;
}

.xp-time {
    display: flex;
    gap: 8px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--border);
    color: var(--text-faint);
    font-size: 15px;
}

.xp-ago {
    font-family: var(--font-mono);
    font-size: 13px;
}

/* the feed's markets: Crypto and Stocks, each on or off, side by side */
.feed-markets {
    display: inline-flex;
    gap: 2px;
    flex: 0 0 auto;
}

/* first visit, logged out: two lines above the stories (src/index.js welcomeNode), the buttons at the end, until it is closed */
.welcome-hero {
    position: relative;
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 24px;
    margin: var(--gutter) var(--gutter) 0;
    padding: 18px 52px 18px 22px;
    border-radius: var(--radius-panel);
    /* a slight green from the corner (2026-10-04: "slight green on the market moving header as well") */
    background: radial-gradient(120% 160% at 0% 0%, var(--accent-soft), transparent 55%), var(--surface);
    animation: wh-in 0.4s ease both;
}

.wh-copy {
    flex: 1 1 auto;
    min-width: 0;
}

.wh-live {
    color: var(--text-muted);
    font-size: var(--fs-sm);
}

.wh-live b {
    color: var(--text);
    font-weight: 600;
}

.wh-title {
    margin: 8px 0 6px;
    color: var(--text);
    font-size: 26px;
    font-weight: 650;
    line-height: 1.15;
    letter-spacing: -0.02em;
}

.wh-title span {
    color: var(--accent);
}

.wh-sub {
    max-width: 640px;
    margin: 0;
    color: var(--text-muted);
    font-size: var(--fs-md);
    line-height: 1.5;
}

.wh-actions {
    display: flex;
    flex: 0 0 auto;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: var(--sp-2);
}

@keyframes wh-in {
    from { opacity: 0; transform: translateY(6px); }
    to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    .welcome-hero {
        animation: none;
    }
}

@media (max-width: 900px) {
    .welcome-hero {
        flex-direction: column;
        align-items: stretch;
        gap: 12px;
        padding: 14px 44px 14px 14px;
    }

    .wh-title {
        font-size: 22px;
    }

    .wh-actions {
        justify-content: flex-start;
    }
}

.welcome-close {
    position: absolute;
    top: 8px;
    right: 8px;
}

/* "×N": the same post again within a day, merged into its newest row */
.news-repeat {
    background: var(--tint-8);
    border-color: var(--border);
    color: var(--text-muted);
}

/* end of a column: older items loading, or where "50 results" stops */
.feed-older {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 12px;
    color: var(--text-faint);
    font-size: var(--fs-sm);
}

/* the toolbar bell: one line on what alerts are, before the browser asks */
.alerts-ask {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
    width: 260px;
    max-width: calc(100vw - 32px);
    padding: 6px 8px;
}

.alerts-ask p {
    margin: 0;
    color: var(--text-muted);
    font-size: var(--fs-md);
    line-height: 1.4;
}

@media (max-width: 700px) {
    .welcome-hero {
        margin: 8px 8px 0;
        gap: 10px;
    }

    .wh-sub {
        font-size: var(--fs-sm);
    }

    /* the top bar's delay chip says what a plan adds: the opener leaves the stories most of the screen */
    .wh-sub-plan {
        display: none;
    }

    .wh-title {
        margin: 6px 0;
    }
}

/* account page: the account's logins, Discord and Telegram (src/account.js AccountLogins) */
.login-rows {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.login-row {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 32px;
}

.login-row-icon {
    flex: 0 0 auto;
    width: 18px;
    text-align: center;
    font-size: 16px;
    color: var(--text-muted);
}

.login-row-text {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-width: 0;
    line-height: 1.3;
}

.login-row-action {
    display: flex;
    flex: 0 0 auto;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: 6px;
}

/* the "5s delay" chip's explanation (src/components/ui.js DelayChip) */
.delay-explain {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
    width: 280px;
    max-width: calc(100vw - 32px);
    padding: 8px 10px;
    font-size: var(--fs-md);
    line-height: 1.4;
}

.delay-explain-title {
    font-weight: 600;
    color: var(--text);
}

.delay-explain p {
    margin: 0;
    color: var(--text-muted);
}

.delay-explain p b {
    color: var(--text);
    font-weight: 600;
}

.delay-explain .btn {
    margin-top: 4px;
}

/* "Plans" in the bottom bar on phones, for anyone not on a plan (ui.js Shell): never in the desktop rail */
.rail-plans {
    display: none;
}

@media (max-width: 900px) {
    .rail-footer .rail-item.rail-plans {
        display: flex;
    }

    .rail-footer.has-plans .rail-theme {
        display: none;
    }
}

/* "Big": the news desk's picks, the day's biggest stories (src/index.js, server.js POST /api/desk/big) */
.news-big {
    background: var(--big);
    color: var(--big-text);
    text-transform: uppercase;
}

/* a Big row: gold light from the left edge and a lit gold bar (the only gold in the feed) */
.news-row.is-big::before {
    background: var(--big);
    opacity: 1;
}

/* a row about something the reader follows (src/index.js follows) */
.news-follow {
    border-color: var(--info);
    color: var(--info);
}

/* the toolbar's Following panel */
.follow-panel {
    display: flex;
    flex-direction: column;
    gap: 8px;
    width: 300px;
    max-width: calc(100vw - 32px);
    padding: 8px 10px;
}

.follow-panel p {
    margin: 0;
    color: var(--text-muted);
    font-size: var(--fs-sm);
    line-height: 1.4;
}

.follow-add {
    display: flex;
    gap: 6px;
}

.follow-add .input {
    flex: 1 1 auto;
    min-width: 0;
}

.follow-list {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

/* ---- account + plans pages (2026-10-03) ---- */
/* account page: the plan summary under the profile header (plan, end date, auto-renew, Tree Credits, one action) */

/* account page: "Reset the key?" sits in the narrow side column, so it may wrap */
.wallet-confirm.api-key-confirm {
    white-space: normal;
    flex-wrap: wrap;
}

@media (max-width: 700px) {
    /* a wallet's "Remove this wallet?" prompt wraps instead of running off a phone screen */
    .profile-sub .wallet-row {
        flex-wrap: wrap;
        max-width: 100%;
    }

    .profile-sub .wallet-confirm,
    .login-row .wallet-confirm {
        white-space: normal;
        flex-wrap: wrap;
    }

    /* an exchange ID being edited (input, Save, Cancel) goes under the exchange's name */
    .referral-row {
        grid-template-columns: minmax(0, 1fr);
    }

    .referral-row .row {
        flex-wrap: wrap;
    }
}

/* ---- settings + leaderboard + terms pages (2026-10-03) ---- */
/* Settings: a section header's add box (Twitter, Telegram, Instagram), or the login / plan line standing in for it */
.settings-add {
    display: flex;
    align-items: center;
    gap: 6px;
}

@media (min-width: 701px) {
    .settings-add .input {
        width: 170px;
    }

    /* Leaderboard "Track an account": UID, then name or tag (phones: .setting-control's full-width inputs) */
    .setting-control .input.settings-uid {
        width: 220px;
    }

    .setting-control .input.settings-tag {
        width: 150px;
    }
}

/* Twitter list: a category header (its name, one menu) */
.twitter-cat {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-2);
    padding: 14px 16px 6px;
}

/* where a search typed far down the list brings the page back to (under the topbar) */
.twitter-list-top {
    scroll-margin-top: var(--topbar-h);
}

/* the Post types dialog */
.post-types-group + .post-types-group {
    margin-top: var(--sp-4);
}

.post-types-title {
    margin-bottom: 8px;
    font-size: var(--fs-xs);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-faint);
}

.post-types-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px 16px;
}

/* the Arkham webhook's red "Replace?" question may wrap */
.wallet-confirm.settings-confirm {
    white-space: normal;
    flex-wrap: wrap;
}

@media (max-width: 700px) {
    /* section and card headers: the actions go under the title instead of squeezing it to a sliver */
    .settings-section-header,
    .settings-section-actions,
    .card-header,
    .card-actions {
        flex-wrap: wrap;
    }

    .settings-section-actions {
        flex: 1 1 100%;
    }

    .settings-add {
        width: 100%;
        flex-wrap: wrap;
    }

    .settings-add .input {
        flex: 1 1 140px;
        width: auto;
        min-width: 0;
    }

    .twitter-cat {
        padding: 12px 12px 6px;
    }
}

/* Leaderboard: the trader cell (the name, and on phones the best pairs under it) */
.lb-user-text {
    display: flex;
    flex-direction: column;
    gap: 4px;
    flex: 1 1 auto;
    min-width: 0;
}

.lb-name {
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
}

.lb-pairs-under {
    display: none;
}

@media (max-width: 700px) {
    /* the table fits the screen: fixed columns, and no Best pairs column (the pairs are under the name) */
    .lb-table {
        table-layout: fixed;
    }

    .lb-table th.lb-pnl-col {
        width: 120px;
    }

    .lb-table .lb-pairs-col {
        display: none;
    }

    .lb-pairs-under {
        display: block;
    }
}

/* ---------------------------------------------------------------------
   ICONS: Lucide 1.51 (lucide.dev, ISC licence), as an icon font pinned to its version (code points move between
   versions). <i class="lc lc-<name>">: 1em, currentColor. Brand logos (Discord, Telegram, Twitter, Instagram,
   Ethereum) are Font Awesome 6.3 brands, those five only, from our own cut of its font (below): the pages no longer load
   Font Awesome itself (two stylesheets and 108 KB of font from cdnjs before the first paint).
   --------------------------------------------------------------------- */
/* Font Awesome 6.3.0 brands (fontawesome.com, Font Awesome Free licence: CC BY 4.0 icons, SIL OFL font): the five logos the
   pages use, from our own cut of fa-brands-400 */
@font-face {
    font-family: "Font Awesome 6 Brands";
    font-style: normal;
    font-weight: 400;
    font-display: block;
    src: url("/static/fonts/fa-brands-6.3.0-tree.woff2") format("woff2"),
         url("https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.3.0/webfonts/fa-brands-400.woff2") format("woff2");   /* only if ours is missing */
}
.fa-brands, .fab {
    display: var(--fa-display, inline-block);
    font-family: "Font Awesome 6 Brands";
    font-style: normal;
    font-weight: 400;
    font-variant: normal;
    line-height: 1;
    text-rendering: auto;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}
.fa-twitter::before { content: "\f099"; }
.fa-discord::before { content: "\f392"; }
.fa-telegram::before { content: "\f2c6"; }
.fa-instagram::before { content: "\f16d"; }
.fa-ethereum::before { content: "\f42e"; }

@font-face {
    font-family: "lucide";
    /* our own copy cut to the icons mapped below (2026-10-09: the whole font was 288 KB from jsdelivr, this is 22 KB):
       an icon added to this list needs the font cut again from lucide-static 1.51.0 with it */
    src: url("/static/fonts/lucide-1.51.0-tree.woff2") format("woff2"),
         url("https://cdn.jsdelivr.net/npm/lucide-static@1.51.0/font/lucide.woff2") format("woff2");   /* the whole font, only if ours is missing */
    font-display: block;
}

.lc {
    display: inline-block;
    font-family: "lucide" !important;
    font-style: normal;
    font-weight: normal;
    font-variant: normal;
    text-transform: none;
    line-height: 1;
    vertical-align: -0.125em;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    speak: never;
}

.lc-spin {
    animation: tn-spin 1s linear infinite;
}

.lc-activity::before { content: "\e038"; }
.lc-arrow-down::before { content: "\e042"; }
.lc-arrow-right::before { content: "\e049"; }
.lc-arrow-up::before { content: "\e04a"; }
.lc-arrow-up-right::before { content: "\e04d"; }
.lc-badge-check::before { content: "\e241"; }
.lc-badge-dollar-sign::before { content: "\e476"; }
.lc-ban::before { content: "\e051"; }
.lc-bell::before { content: "\e059"; }
.lc-bell-off::before { content: "\e05a"; }
.lc-book-open::before { content: "\e05f"; }
.lc-bookmark::before { content: "\e060"; }
.lc-calendar::before { content: "\e063"; }
.lc-calendar-days::before { content: "\e2b9"; }
.lc-chart-column::before { content: "\e2a3"; }
.lc-chart-line::before { content: "\e2a5"; }
.lc-check::before { content: "\e06c"; }
.lc-check-check::before { content: "\e38e"; }
.lc-chevron-down::before { content: "\e06d"; }
.lc-chevron-left::before { content: "\e06e"; }
.lc-chevron-right::before { content: "\e06f"; }
.lc-chevron-up::before { content: "\e070"; }
.lc-circle-check::before { content: "\e226"; }
.lc-circle-dot::before { content: "\e345"; }
.lc-circle-help::before { content: "\e082"; }
.lc-circle-user::before { content: "\e461"; }
.lc-circle-x::before { content: "\e084"; }
.lc-clock::before { content: "\e087"; }
.lc-clock-3::before { content: "\e250"; }
.lc-cloud-download::before { content: "\e089"; }
.lc-cloud-upload::before { content: "\e091"; }
.lc-coins::before { content: "\e097"; }
.lc-copy::before { content: "\e09e"; }
.lc-dollar-sign::before { content: "\e0b1"; }
.lc-download::before { content: "\e0b2"; }
.lc-ellipsis::before { content: "\e0b6"; }
.lc-external-link::before { content: "\e0b9"; }
.lc-eye::before { content: "\e0ba"; }
.lc-eye-off::before { content: "\e0bb"; }
.lc-file-audio::before { content: "\e31a"; }
.lc-file-text::before { content: "\e0cc"; }
.lc-flag::before { content: "\e0d1"; }
.lc-flame::before { content: "\e0d2"; }
.lc-funnel::before { content: "\e0dc"; }
.lc-funnel-x::before { content: "\e3b5"; }
.lc-gavel::before { content: "\e0e0"; }
.lc-gift::before { content: "\e0e1"; }
.lc-hand-coins::before { content: "\e5b8"; }
.lc-hand-heart::before { content: "\e5b9"; }
.lc-history::before { content: "\e1f5"; }
.lc-id-card::before { content: "\e617"; }
.lc-image::before { content: "\e0f6"; }
.lc-inbox::before { content: "\e0f7"; }
.lc-info::before { content: "\e0f9"; }
.lc-key-round::before { content: "\e4a3"; }
.lc-landmark::before { content: "\e23a"; }
.lc-layout-grid::before { content: "\e0ff"; }
.lc-leaf::before { content: "\e2de"; }
.lc-life-buoy::before { content: "\e101"; }
.lc-link::before { content: "\e102"; }
.lc-list::before { content: "\e106"; }
.lc-lock::before { content: "\e10b"; }
.lc-lock-open::before { content: "\e10c"; }
.lc-log-in::before { content: "\e10d"; }
.lc-log-out::before { content: "\e10e"; }
.lc-megaphone::before { content: "\e235"; }
.lc-menu::before { content: "\e115"; }
.lc-minus::before { content: "\e11c"; }
.lc-monitor::before { content: "\e11d"; }
.lc-moon::before { content: "\e11e"; }
.lc-music::before { content: "\e122"; }
.lc-network::before { content: "\e125"; }
.lc-newspaper::before { content: "\e348"; }
.lc-package::before { content: "\e129"; }
.lc-panel-right-open::before { content: "\e434"; }
.lc-pen::before { content: "\e12f"; }
.lc-pin::before { content: "\e259"; }
.lc-play::before { content: "\e13c"; }
.lc-plus::before { content: "\e13d"; }
.lc-qr-code::before { content: "\e1df"; }
.lc-quote::before { content: "\e239"; }
.lc-radio::before { content: "\e142"; }
.lc-refresh-cw::before { content: "\e145"; }
.lc-repeat-2::before { content: "\e411"; }
.lc-reply::before { content: "\e22a"; }
.lc-rotate-ccw::before { content: "\e148"; }
.lc-rss::before { content: "\e14a"; }
.lc-scale::before { content: "\e212"; }
.lc-search::before { content: "\e151"; }
.lc-send::before { content: "\e152"; }
.lc-settings::before { content: "\e154"; }
.lc-shield-check::before { content: "\e1ff"; }
.lc-shopping-cart::before { content: "\e15c"; }
.lc-signal::before { content: "\e25f"; }
.lc-sliders-horizontal::before { content: "\e29a"; }
.lc-sparkles::before { content: "\e412"; }
.lc-sprout::before { content: "\e1eb"; }
.lc-square::before { content: "\e167"; }
.lc-square-check::before { content: "\e559"; }
.lc-square-pen::before { content: "\e172"; }
.lc-star::before { content: "\e176"; }
.lc-sun::before { content: "\e178"; }
.lc-ticket::before { content: "\e20f"; }
.lc-trash-2::before { content: "\e18e"; }
.lc-tree-pine::before { content: "\e2f4"; }
.lc-trending-down::before { content: "\e190"; }
.lc-trending-up::before { content: "\e191"; }
.lc-triangle-alert::before { content: "\e193"; }
.lc-trophy::before { content: "\e373"; }
.lc-unlink::before { content: "\e19c"; }
.lc-user::before { content: "\e19f"; }
.lc-user-plus::before { content: "\e1a2"; }
.lc-volume-2::before { content: "\e1ab"; }
.lc-wallet::before { content: "\e204"; }
.lc-wand-sparkles::before { content: "\e357"; }
.lc-x::before { content: "\e1b2"; }
.lc-zap::before { content: "\e1b4"; }

/* ---- settings + leaderboard + terms, calm terminal (2026-10-03) ---- */
/* Settings, leaderboard and terms pages (src/settings.js, leaderboard.js, tos.js) on the calm terminal spec. Overrides
   sections 10-12 and the earlier "settings + leaderboard + terms pages" block; a rule here outranks the earlier @media
   ones of the same weight, so the phone rules are repeated in this block's own @media at its end. */

/* Settings: the section menu. Desktop: a plain list that stays in view; the active section looks like the app's rail
   (a neutral step up and a 3px accent edge, no green fill). Up to 1100px it is the scrolling strip of section 13, with
   the edge under the active item. */
.settings-nav-item {
    position: relative;
    height: var(--control-h-md);
    padding: 0 var(--sp-3);
    gap: var(--sp-2);
    border-radius: var(--radius-control);
    font-size: var(--fs-md);
    font-weight: 500;
    color: var(--text-muted);
}

.settings-nav-item i {
    width: 16px;
    flex: 0 0 16px;
    font-size: 14px;
    color: var(--text-muted);
}

.settings-nav-item:hover {
    background: var(--surface-2);
    color: var(--text);
}

.settings-nav-item:focus-visible {
    border-radius: var(--radius-control);
}

.settings-nav-item.active {
    background: var(--surface-3);
    color: var(--text);
}

.settings-nav-item.active i {
    color: var(--text);
}

.settings-nav-item.active::before {
    content: "";
    position: absolute;
    left: 0;
    top: var(--sp-2);
    bottom: var(--sp-2);
    width: 3px;
    border-radius: 0 3px 3px 0;
    background: var(--accent);
}

/* a section's count: a quiet number, not a pill */
.settings-nav-item .badge-count {
    margin-left: auto;
    min-width: 0;
    height: auto;
    padding: 0;
    background: transparent;
    color: var(--text-faint);
    font-size: var(--fs-sm);
}

.settings-nav-item.active .badge-count {
    color: var(--text-muted);
}

/* under the list: where the settings are saved (and, in the Terminal, Import / Save) */
.settings-nav-foot {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--sp-2);
    margin-top: var(--sp-3);
    padding-top: var(--sp-3);
    border-top: 1px solid var(--border);
}

.settings-nav-foot .btn {
    width: 100%;
}

/* the sync status is a sentence, not a number: the sans keeps "Saved in this browser only" whole in the 220px column */
.status-pill.settingsSyncStatus {
    font-family: var(--font-ui);
}

@media (min-width: 1101px) {
    .settings-nav {
        top: calc(var(--topbar-h) + var(--sp-4));
        gap: 2px;
        padding: 0;
        background: transparent;
        border: 0;
        border-radius: 0;
    }
}

/* Settings: section cards (15/600 title, 12px muted line, 16px padding) */
.settings-section {
    scroll-margin-top: calc(var(--topbar-h) + var(--sp-4));
}

.settings-section-header {
    align-items: center;
    gap: var(--sp-4);
    padding: var(--sp-4);
}

.settings-section-title {
    gap: var(--sp-2);
    font-size: var(--fs-lg);
    font-weight: 600;
    line-height: 1.3;
}

.settings-section-title i {
    font-size: 14px;
    color: var(--text-muted);
}

.settings-section-desc {
    margin-top: 2px;
    font-size: var(--fs-sm);
    line-height: 1.45;
    color: var(--text-muted);
}

/* Settings: one setting per row (13/500 label, 12px muted description, the control on the right, 44px or more) */
.setting-row {
    min-height: 44px;
    gap: var(--sp-4);
    padding: var(--sp-2) var(--sp-4);
}

.setting-label {
    flex: 1 1 auto;
    gap: 2px;
}

.setting-name {
    font-size: var(--fs-md);
    font-weight: 500;
    line-height: 1.35;
}

.setting-desc {
    font-size: var(--fs-sm);
    line-height: 1.4;
    color: var(--text-muted);
}

.setting-control {
    justify-content: flex-end;
}

/* Settings: source lists. The search bar and the column header stay under the top bar while their list scrolls by. */
.settings-section .list-search,
.settings-section .source-head {
    top: var(--topbar-h);
}

/* under the search bar: its field, its padding and its 1px line */
.settings-section .list-search + .source-head {
    top: calc(var(--topbar-h) + var(--control-h-md) + 2 * var(--sp-2) + 1px);
}

.list-search {
    gap: var(--sp-3);
    padding: var(--sp-2) var(--sp-4);
    background: var(--surface);
}

.list-search .search {
    flex: 1 1 auto;
    max-width: 440px;
}

.list-search-count {
    flex: 0 0 auto;
    margin-left: auto;
    font-size: var(--fs-sm);
    color: var(--text-muted);
    white-space: nowrap;
}

/* the header row and the rows share one grid: logo, name, then the fixed control columns */
.source-head,
.source-row {
    grid-template-columns: 24px minmax(0, 1fr) auto;
    gap: var(--sp-3);
    padding: 0 var(--sp-4);
}

.source-head {
    height: 32px;
    background: var(--surface-2);
    font-size: var(--fs-xs);
    font-weight: 600;
    letter-spacing: 0.05em;
    color: var(--text-muted);
}

.source-row {
    min-height: 40px;
}

.source-row:hover {
    background: var(--surface-hover);
}

/* an account or source that is off: its logo and name step back, the switches stay crisp */
.source-row.is-off {
    opacity: 1;
}

.source-row.is-off > .source-logo,
.source-row.is-off > .news-source-fallback,
.source-row.is-off > .source-name {
    opacity: 0.55;
}

.source-row .source-logo,
.source-row .news-source-fallback {
    width: 24px;
    height: 24px;
    flex: 0 0 24px;
}

.source-row .news-source-fallback {
    font-size: 12px;
}

.source-name {
    gap: var(--sp-2);
    font-size: var(--fs-md);
    font-weight: 500;
    color: var(--text);
}

/* a handle is a name: the sans, quieter (the mono cut is for numbers) */
.source-handle {
    font-family: var(--font-ui);
    font-size: var(--fs-sm);
    font-weight: 400;
    color: var(--text-faint);
}

/* Twitter list: a category header (small caps, its account count, one menu centred over the More column) */
.twitter-cat {
    min-height: 48px;
    gap: var(--sp-2);
    padding: var(--sp-4) 36px var(--sp-1) var(--sp-4);   /* 36px: the 28px button centred over the 68px More column */
}

.twitter-cat-title {
    display: flex;
    align-items: baseline;
    gap: var(--sp-2);
    min-width: 0;
    margin: 0;
    font-size: var(--fs-xs);
    font-weight: 600;
    line-height: 1.3;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted);
}

.twitter-cat-count {
    flex: 0 0 auto;
    font-family: var(--font-mono);
    font-weight: 500;
    letter-spacing: 0;
    color: var(--text-faint);
}

/* placeholder rows while a list loads */
.source-row.is-skeleton:hover {
    background: transparent;
}

.skeleton-logo {
    width: 24px;
    height: 24px;
    border-radius: 50%;
}

.skeleton-text {
    max-width: 100%;
    height: 12px;
    min-height: 0;
}

.skeleton-switch {
    width: 28px;
    height: 16px;
    min-height: 0;
    border-radius: var(--radius-pill);
}

/* Leaderboard: the stat cards (16px, kicker labels, hero numbers) */
.lb-stats {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--sp-4);
}

.lb-stats .stat {
    gap: var(--sp-2);
    padding: var(--sp-4);
}

.lb-stats .stat-label {
    font-weight: 600;
    letter-spacing: 0.05em;
}

.lb-stats .stat-label i {
    font-size: 12px;
}

.lb-stats .stat-value {
    font-size: var(--fs-3xl);
    font-weight: 600;
    line-height: 1.15;
    letter-spacing: -0.02em;
}

.lb-stats .stat-sub {
    color: var(--text-muted);
}

/* Leaderboard: the board. Rows 44px, the edge columns on the card's 16px, the header row under the top bar. */
.lb-table {
    border-collapse: separate;
    border-spacing: 0;
}

.lb-card .lb-table th {
    top: var(--topbar-h);
}

/* neighbouring cells can meet on half a pixel (Windows scaling): each paints 1px over the next one's edge, so no seam
   shows through the header row or a hovered row */
.lb-table th {
    box-shadow: 1px 0 0 var(--surface-2);
}

.lb-table th:last-child {
    box-shadow: none;
}

.lb-table td {
    height: 44px;
}

.lb-table th:first-child,
.lb-table td:first-child {
    padding-left: var(--sp-4);
}

.lb-table th:last-child,
.lb-table td:last-child {
    padding-right: var(--sp-4);
}

.lb-table th.lb-rank-col {
    width: 64px;
}

.lb-table .lb-rank-col {
    padding-right: var(--sp-2);
}

.lb-table th.lb-pnl-col {
    width: 168px;
}

/* the rank: the number for everyone, a quiet medal before it for the top three */
.lb-rank {
    display: inline-flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--sp-1);
    width: auto;
    font-weight: 500;
    color: var(--text-faint);
}

.lb-rank.is-top {
    font-weight: 600;
    color: var(--text);
}

.lb-rank i {
    font-size: 13px;
    color: var(--text-muted);
}

.lb-table .lb-user {
    gap: var(--sp-2);
}

.lb-user .avatar {
    width: 24px;
    height: 24px;
    font-size: var(--fs-xs);
}

.lb-name {
    font-weight: 500;
    color: var(--text);
}

.lb-name .truncate {
    max-width: 280px;
}

.lb-pnl {
    font-weight: 600;
}

/* a pair is a code: the mono cut, like the feed's ticker chips */
.lb-pairs-col .chip,
.lb-pairs-line {
    font-family: var(--font-mono);
}

/* a trader who hides their pairs */
.lb-hidden {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: var(--fs-sm);
    color: var(--text-faint);
}

.lb-hidden i {
    font-size: 12px;
}

/* phones: the pairs as one line under the name (nothing there for a trader without pairs) */
.lb-pairs-line {
    display: block;
    font-size: var(--fs-sm);
    color: var(--text-muted);
}

.lb-pairs-under:empty {
    display: none;
}

/* hover and "you" paint the cells, so the last row keeps the card's rounded corners */
.lb-table tbody tr:hover,
.lb-table tbody tr.is-me {
    background: transparent;
}

.lb-table tbody tr:hover td {
    background: var(--surface-hover);
}

.lb-table tbody tr:hover td:not(:last-child) {
    box-shadow: 1px 0 0 var(--surface-hover);
}

.lb-table tbody tr.is-skeleton:hover td {
    background: transparent;
    box-shadow: none;
}

.lb-table tbody tr.is-me td {
    background: var(--info-soft);
}

.lb-table tbody tr.is-me td:first-child {
    box-shadow: inset 2px 0 0 var(--info);
}

.lb-table tbody tr.is-me td:not(:first-child) {
    box-shadow: none;
}

.lb-table tbody tr:last-child td:first-child {
    border-bottom-left-radius: calc(var(--radius-lg) - 1px);
}

.lb-table tbody tr:last-child td:last-child {
    border-bottom-right-radius: calc(var(--radius-lg) - 1px);
}

/* placeholders until the first answer */
.lb-skel {
    display: inline-block;
    height: 12px;
    min-height: 0;
    vertical-align: middle;
}

.lb-skel-rank {
    width: 16px;
}

.lb-skel-avatar {
    width: 24px;
    height: 24px;
    border-radius: 50%;
}

.lb-skel-chip {
    width: 64px;
    height: var(--chip-h-sm);
    border-radius: var(--radius-pill);
}

.lb-skel-pnl {
    width: 72px;
}

.lb-skel-stat {
    width: 112px;
    height: 24px;
}

/* Terms: one reading column (~720px), 18/600 headings, 14/1.7 body in the main text colour, quiet lists */
.terms {
    max-width: 720px;
    margin: 0 auto;
}

.terms-card .card-body {
    padding: var(--sp-8);
}

.terms-prose {
    max-width: none;
    font-size: var(--fs-base);
    line-height: 1.7;
    color: var(--text);
}

.terms-prose p,
.terms-prose ul,
.terms-prose ol {
    color: var(--text);
}

.terms-prose p {
    margin: 0 0 var(--sp-4);
}

.terms-prose h2 {
    margin: var(--sp-8) 0 var(--sp-3);
    padding-top: 0;
    border-top: 0;
    font-size: var(--fs-xl);
    font-weight: 600;
    line-height: 1.35;
    letter-spacing: -0.01em;
    color: var(--text);
}

.terms-num {
    margin-right: 2px;
    font-weight: 500;
    color: var(--text-faint);
}

.terms-prose ul {
    margin: 0 0 var(--sp-4);
    padding-left: var(--sp-5);
    list-style: disc;
}

.terms-prose li {
    margin: 0;
    padding-left: var(--sp-1);
}

.terms-prose li + li {
    margin-top: var(--sp-2);
}

.terms-prose li::marker {
    color: var(--text-faint);
}

.terms-prose .prose-meta {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 0 0 var(--sp-5);
    font-family: var(--font-ui);
    font-size: var(--fs-sm);
    line-height: 1.4;
    color: var(--text-muted);
}

.terms-prose .prose-meta i {
    font-size: 12px;
}

.terms-prose .prose-meta time {
    font-family: var(--font-mono);
}

/* the closing acknowledgement: a quiet note */
.terms-prose .terms-ack {
    margin: var(--sp-8) 0 0;
    padding: var(--sp-3) var(--sp-4);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface-2);
}

.terms-ack strong {
    font-weight: 600;
}

/* tablets and phones: the section menu is the scrolling strip of section 13; the edge goes under the active item */
@media (max-width: 1100px) {
    .settings-nav-item {
        height: var(--control-h-sm);
        padding: 0 var(--sp-3);
    }

    .settings-nav-item.active::before {
        left: var(--sp-3);
        right: var(--sp-3);
        top: auto;
        bottom: 0;
        width: auto;
        height: 2px;
        border-radius: 2px 2px 0 0;
    }
}

/* phones: everything stacks, 12px insets, nothing wider than the screen */
@media (max-width: 700px) {
    .settings-section-header {
        padding: var(--sp-4) var(--sp-3);
    }

    .setting-row {
        flex-direction: column;
        align-items: flex-start;
        gap: var(--sp-2);
        padding: var(--sp-3);
    }

    .setting-control {
        justify-content: flex-start;
    }

    /* a lone switch stays beside its label */
    .setting-row.has-switch {
        flex-direction: row;
        align-items: center;
        gap: var(--sp-3);
    }

    .setting-row.has-switch .setting-control {
        width: auto;
        justify-content: flex-end;
    }

    .list-search {
        padding: var(--sp-2) var(--sp-3);
    }

    .source-head,
    .source-row {
        gap: 0 var(--sp-2);
        padding: 0 var(--sp-3);
    }

    /* a row: logo, name, More on one line; the switches (and the sound picker) on the row's full width under it, so a
       Twitter account's four fit on one line */
    .source-row {
        grid-template-rows: minmax(44px, auto) auto;
    }

    .source-end {
        grid-column: 3;
        display: flex;
        align-items: center;
        gap: var(--sp-1);
    }

    .source-sub {
        grid-column: 1 / -1;
        align-items: center;
        gap: var(--sp-2) var(--sp-4);
        padding: 0 0 var(--sp-3);
        border-top: 0;
    }

    .source-sub .switch {
        gap: 6px;
    }

    .source-sub .switch-label {
        font-size: var(--fs-sm);
        color: var(--text-muted);
    }

    .twitter-cat {
        padding: var(--sp-4) var(--sp-3) var(--sp-1);
    }

    .lb-header .page-actions {
        flex: 1 1 100%;
    }

    .lb-period {
        width: 100%;
    }

    .lb-period .segmented-item {
        flex: 1 1 0;
        padding: 0 var(--sp-1);
    }

    .lb-stats {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: var(--sp-3);
    }

    .lb-stats .stat:first-child {
        grid-column: 1 / -1;
    }

    .lb-stats .stat {
        padding: var(--sp-3);
    }

    .lb-stats .stat-value {
        font-size: var(--fs-2xl);
    }

    .lb-table th:first-child,
    .lb-table td:first-child {
        padding-left: var(--sp-3);
    }

    .lb-table th:last-child,
    .lb-table td:last-child {
        padding-right: var(--sp-3);
    }

    .lb-table th.lb-rank-col {
        width: 52px;
    }

    .lb-table th.lb-pnl-col {
        width: 112px;
    }

    .lb-name .truncate {
        max-width: none;
    }

    .terms-card .card-body {
        padding: var(--sp-5) var(--sp-4);
    }

    .terms-prose h2 {
        margin-top: var(--sp-6);
    }
}

/* the one icon these pages add to the ICONS block's set (Lucide 1.51 "medal") */
.lc-medal::before { content: "\e36f"; }
/* ---- end: settings + leaderboard + terms, calm terminal ---- */

/* ---- account + plans pages, calm terminal (2026-10-03) ---- */
/* The account page (src/account.js) and the plans page (views/access.html) on the calm terminal spec: the account hero,
   the plan cards both pages share (.price-card), the wallet lines, the invite numbers, the compact TreeNFT card and the
   skeletons. On the Tree terminal v2 tokens: Geist for words, Geist Mono only for numbers, prices and codes; panels on
   --radius-panel. Overrides section 11 and the earlier "account + plans pages" block; the phone rules are in this
   block's own @media at its end, so they outrank the base rules above them. */

/* account: main column + a 340px side column (Logins, API key, $TREE, TreeNFT); one column up to 1100px (section 13) */
@media (min-width: 1101px) {
    .two-col.is-sidebar.account-cols {
        grid-template-columns: minmax(0, 1fr) 340px;
    }
}

/* account: the hero. One card: who you are and your plan | your Tree Credits | the one next step, then your wallets */
.account-hero-top {
    display: flex;
    align-items: center;
    gap: var(--sp-6);
    padding: var(--sp-5) var(--sp-4);
}

.account-hero-id {
    display: flex;
    align-items: center;
    gap: var(--sp-4);
    flex: 1 1 auto;
    min-width: 0;
}

.avatar.account-hero-avatar {
    width: 48px;
    height: 48px;
    flex: 0 0 48px;
    font-size: var(--fs-xl);
}

.account-hero-text {
    display: flex;
    flex-direction: column;
    gap: var(--sp-1);
    min-width: 0;
}

.account-hero-name {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    min-width: 0;
}

.account-hero-name h1 {
    min-width: 0;
    font-size: var(--fs-2xl);
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: -0.01em;
    color: var(--text);
}

.account-hero-name .chip {
    flex: 0 0 auto;
}

.account-hero-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 2px var(--sp-4);
    font-size: var(--fs-md);
    color: var(--text-muted);
}

.account-hero-renew i {
    margin-right: 6px;
    font-size: 12px;
    color: var(--text-faint);
}

.account-hero-warn {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: var(--fs-sm);
    color: var(--warn);
}

.account-hero-credits {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 2px;
    flex: 0 0 auto;
    align-self: stretch;
    min-width: 168px;
    padding-left: var(--sp-6);
    border-left: 1px solid var(--border);
}

.account-hero-label,
.wallet-line-label,
.account-metric-label {
    font-size: var(--fs-xs);
    font-weight: 600;
    line-height: 1.3;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.account-hero-label {
    margin-bottom: 2px;
}

.account-hero-value {
    font-family: var(--font-mono);
    font-size: var(--fs-3xl);
    font-weight: 600;
    line-height: 1.15;
    letter-spacing: -0.03em;
    font-variant-numeric: tabular-nums;
    color: var(--text);
}

.account-hero-sub {
    font-size: var(--fs-sm);
    color: var(--text-muted);
}

.account-hero-action {
    flex: 0 0 auto;
}

/* the hero's wallets: one line per kind (label | linked addresses | its link button) */
.account-hero-wallets {
    padding: 0 var(--sp-4);
    border-top: 1px solid var(--border);
}

.wallet-line {
    display: grid;
    grid-template-columns: 112px minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--sp-3);
    min-height: 48px;
    padding: var(--sp-2) 0;
}

.wallet-line + .wallet-line {
    border-top: 1px solid var(--border);
}

.wallet-line-label {
    white-space: nowrap;
}

.wallet-line-items {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sp-1) var(--sp-4);
    min-width: 0;
    font-size: var(--fs-md);
}

.wallet-line-action {
    display: flex;
    justify-content: flex-end;
}

.wallet-line .wallet-row {
    gap: 2px;
    margin-right: 0;
}

.wallet-line .wallet-addr {
    margin-right: 4px;
    font-size: var(--fs-md);
    color: var(--text);
}

.wallet-choose {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sp-2);
}

.wallet-choose-icon {
    width: 16px;
    height: 16px;
    margin-right: 6px;
    border-radius: var(--radius-sm);
}

/* account, logged out: one card with both logins */
.card.account-login {
    align-items: center;
    gap: var(--sp-2);
    max-width: 420px;
    margin: var(--sp-8) auto 0;
    padding: var(--sp-8) var(--sp-6) var(--sp-6);
    text-align: center;
}

.account-login-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    margin-bottom: var(--sp-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--surface-2);
    font-size: 18px;
    color: var(--text-muted);
}

.account-login-title {
    font-size: var(--fs-2xl);
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: -0.01em;
}

.account-login-desc {
    max-width: 320px;
    font-size: var(--fs-md);
    color: var(--text-muted);
}

.account-login-actions {
    display: flex;
    flex-direction: column;
    gap: var(--sp-2);
    width: 100%;
    margin: var(--sp-4) 0 0;
}

/* "Compare every plan", "See what each plan includes" */
.account-more-link {
    display: inline-flex;
    align-items: center;
    align-self: center;
    gap: 6px;
    margin-top: var(--sp-3);
    font-size: var(--fs-md);
    color: var(--text-muted);
}

.account-more-link i {
    font-size: 12px;
}

.card-body > .account-more-link {
    align-self: auto;
}

/* a line of context at the top of a card (the NFT holder's note in Plans) */
.account-note {
    display: flex;
    align-items: flex-start;
    gap: var(--sp-2);
    margin-bottom: var(--sp-3);
    font-size: var(--fs-md);
    color: var(--text-muted);
}

.account-note i {
    flex: 0 0 auto;
    margin-top: 3px;
    font-size: 13px;
    color: var(--text-faint);
}

.account-inline-error {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-bottom: var(--sp-3);
    font-size: var(--fs-sm);
    color: var(--danger);
}

/* plan cards (account Plans card, plans page): the name, a big price, what it gives, then the button, level with the
   next card's (the grid makes the cards one height and the foot sits at the bottom) */
.price-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--sp-3);
}

.price-grid.is-4 {
    grid-template-columns: repeat(4, minmax(0, 1fr));
}

.price-card {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--sp-4);
    min-width: 0;
    padding: var(--sp-4);
    border: 1px solid var(--border);
    border-radius: var(--radius-panel);
    background: var(--surface);
    transition: border-color var(--ease), background var(--ease), box-shadow var(--ease);
}

/* the plans page's cards sit on the page like every panel */
.price-grid.is-4 .price-card {
    box-shadow: var(--shadow-panel);
}

.price-card.is-current,
.price-card.is-selected,
.price-grid.is-4 .price-card.is-selected {
    border-color: var(--accent);
    box-shadow: inset 0 0 0 1px var(--accent);
}

/* a narrow card (phones) puts its badge under the name */
.price-card-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-1) var(--sp-2);
    min-height: var(--chip-h-sm);
}

.price-card-name {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    min-width: 0;
    font-size: var(--fs-lg);
    font-weight: 600;
    color: var(--text);
}

.price-card-name i {
    font-size: 14px;
    color: var(--text-muted);
}

.price-card-badges {
    display: inline-flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 4px;
}

.price-card-pricing {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.price-card-price {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0 6px;
}

.price-card-amount {
    font-family: var(--font-mono);
    font-size: var(--fs-3xl);
    font-weight: 600;
    line-height: 1.15;
    letter-spacing: -0.03em;
    font-variant-numeric: tabular-nums;
    color: var(--text);
    white-space: nowrap;
}

/* a price that is not a number ("Tree NFT") stays in the words font */
.price-card-amount.is-text {
    font-family: var(--font-ui);
    letter-spacing: -0.02em;
}

.price-card-unit {
    font-size: var(--fs-md);
    color: var(--text-muted);
}

.price-card-per {
    font-size: var(--fs-sm);
    color: var(--text-faint);
}

/* a dollar line under a number ("≈ $500") is a price too: the mono cut */
.price-card-per.is-num,
.account-hero-usd {
    font-family: var(--font-mono);
    letter-spacing: -0.01em;
}

.price-card-blurb {
    font-size: var(--fs-md);
    line-height: var(--lh);
    color: var(--text-muted);
}

.price-card-features {
    display: flex;
    flex-direction: column;
    gap: var(--sp-2);
    padding-top: var(--sp-4);
    border-top: 1px solid var(--border);
    font-size: var(--fs-md);
    line-height: 1.4;
    color: var(--text);
}

.price-card-features li {
    display: flex;
    align-items: flex-start;
    gap: var(--sp-2);
}

.price-card-features li i {
    flex: 0 0 auto;
    margin-top: 2px;
    font-size: 13px;
    color: var(--text-muted);
}

.price-card-foot {
    display: flex;
    flex-direction: column;
    gap: var(--sp-3);
    margin-top: auto;
}

/* where a card has no button: what covers that plan already */
.price-card-included {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    min-height: var(--control-h-md);
    padding: 0 var(--sp-3);
    border-radius: var(--radius-control);
    background: var(--surface-2);
    font-size: var(--fs-md);
    color: var(--text-muted);
    text-align: center;
}

.price-card-included i {
    flex: 0 0 auto;
    font-size: 13px;
    color: var(--text-faint);
}

/* the plan's auto-renew switch and its status lines, above the button */
.auto-renew {
    display: flex;
    flex-direction: column;
    gap: var(--sp-1);
    padding-top: var(--sp-3);
    border-top: 1px solid var(--border);
}

.auto-renew i {
    margin-right: 4px;
}

.auto-renew-failed {
    color: var(--danger);
}

/* plans page: a card is also the tab that shows its plan below; its own button stays clickable on top */
.price-card.is-selectable:hover {
    border-color: var(--border-strong);
}

.price-card.is-selectable.is-selected:hover {
    border-color: var(--accent);
}

.price-card-select {
    display: flex;
    flex-direction: column;
    gap: var(--sp-4);
    width: 100%;
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.price-card-select::after {
    content: "";
    position: absolute;
    inset: -1px;
    border-radius: var(--radius-panel);
}

.price-card-select:focus-visible {
    box-shadow: none;
}

.price-card-select:focus-visible::after {
    box-shadow: var(--focus);
}

.price-card.is-selectable .price-card-foot > * {
    position: relative;
    z-index: 1;
}

/* account: the invite link and its code on one line, then three numbers */
.invite-link {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
}

.invite-link .referral-code {
    flex: 0 0 auto;
}

.account-metrics {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    margin-top: var(--sp-4);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
}

.account-metric {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    padding: var(--sp-3) var(--sp-4);
}

.account-metric + .account-metric {
    border-left: 1px solid var(--border);
}

.account-metric-value {
    font-family: var(--font-mono);
    font-size: var(--fs-2xl);
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: -0.01em;
    font-variant-numeric: tabular-nums;
    color: var(--text);
}

.account-metric-sub {
    overflow: hidden;
    font-size: var(--fs-sm);
    color: var(--text-muted);
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* account: the exchange rows sit flush with the card's padding */
.card-body > .referral-row:first-child {
    padding-top: 0;
}

.card-body > .referral-row:last-of-type {
    padding-bottom: 0;
    border-bottom: 0;
}

/* account: the TreeNFT card, a thumbnail beside its button */
.nft-row {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
}

.nft-thumb {
    width: 64px;
    height: 64px;
    flex: 0 0 64px;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface-2);
    object-fit: cover;
}

.nft-row-text {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--sp-2);
    min-width: 0;
}

/* skeletons while the account, the logins, the price and the deposit addresses load */
.skeleton.account-skel-line {
    display: block;
    width: 100%;
    height: 12px;
    min-height: 0;
}

.skeleton.account-skel-value {
    width: 140px;
    height: 28px;
    margin: 2px 0;
}

.skeleton.account-skel-inline {
    display: inline-block;
    width: 90px;
    vertical-align: middle;
}

.skeleton.account-skel-avatar {
    display: block;
    width: 48px;
    height: 48px;
    flex: 0 0 48px;
    border-radius: 50%;
}

.skeleton.account-skel-icon {
    display: block;
    width: 18px;
    height: 18px;
    flex: 0 0 18px;
    border-radius: 50%;
}

.skeleton.account-skel-qr {
    display: block;
    width: 160px;
    height: 160px;
    flex: 0 0 160px;
    border-radius: var(--radius-md);
}

.card.account-skel-card {
    gap: var(--sp-3);
    padding: var(--sp-4);
}

.skeleton.account-skel-block {
    display: block;
    height: 220px;
    border-radius: var(--radius-md);
}

@media (max-width: 700px) {
    .account-hero-top {
        flex-wrap: wrap;
        gap: var(--sp-4);
        padding: var(--sp-4) var(--sp-3);
    }

    .account-hero-id {
        flex: 1 1 100%;
        gap: var(--sp-3);
    }

    /* the credits and the button share a line: the credits start narrow and grow, so the button fits beside them */
    .account-hero-credits {
        flex: 1 1 140px;
        min-width: 0;
        padding-left: 0;
        border-left: 0;
    }

    .account-hero-action {
        align-self: flex-end;
    }

    .account-hero-wallets {
        padding: 0 var(--sp-3);
    }

    /* the label and its button on one line, the addresses under them */
    .wallet-line {
        grid-template-columns: minmax(0, 1fr) auto;
        row-gap: var(--sp-1);
    }

    .wallet-line-items {
        grid-column: 1 / -1;
        grid-row: 2;
    }

    .wallet-line .wallet-row {
        flex-wrap: wrap;
        max-width: 100%;
    }

    .wallet-line .wallet-confirm {
        flex-wrap: wrap;
        white-space: normal;
    }

    .price-grid {
        grid-template-columns: minmax(0, 1fr);
    }

    .price-grid.is-4 {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .invite-link {
        flex-wrap: wrap;
    }

    .account-metric {
        padding: var(--sp-2) var(--sp-3);
    }

    .account-metric-value {
        font-size: var(--fs-xl);
    }

    .account-metric-sub {
        white-space: normal;
    }

    .card.account-login {
        margin-top: var(--sp-4);
        padding: var(--sp-6) var(--sp-4) var(--sp-4);
    }
}
/* ---- end: account + plans pages, calm terminal ---- */


/* the Important switch, on and locked below Seed (src/index.js importantLocked): still green, a little greyed */
.btn.is-locked {
    opacity: 0.6;
    cursor: not-allowed;
}
.btn.is-locked:hover {
    opacity: 0.7;
}

/* a stock's reaction while its market has been closed since the news (ticker.js closedSinceNews) */
.rx-closed {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: var(--fs-xs);
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-faint);
    white-space: nowrap;
}
