@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600;700&display=swap');

/* ---- static/cf-theme.css ---- */
/* Cartel Family — theme tokens: SYNDICATE NOIR (decided 2026-10-12).
 *
 * THE palette. Every colour, type face, space, radius, shadow, glass recipe
 * and motion value in the product resolves from this file: the web pages,
 * the Telegram Mini App, the admin console, the landing, the share-card PNGs
 * (pnl_share_cards.py parses it) and every canvas (cf-charts.js reads the
 * computed values off <body>). Nothing else defines a colour.
 *
 * The values ARE the Noir design system. The prototype they were taken from
 * (/design/a/*, its tokens.css and COMPONENTS.md) was deleted on 2026-10-15
 * once every surface wore Noir; this file and cf-noir.css are the system now,
 * with the AA corrections the product's contrast test computes
 * (tests/test_accent_contrast.py) — see "AA" below.
 *
 * Three layers:
 *   1. NOIR TOKENS — the design system's own names (--ink-0..5 grounds,
 *      --text-1..4, --gold-50..900 + --molten, the ONE electric accent --ion,
 *      --up/--dn, rank metals, glass, elevation, type, space, radii, motion,
 *      chart series). New work uses these.
 *   2. PRODUCT TOKENS — the short names every existing stylesheet already
 *      reads (--bg --s1 --s2 --line --ink --ink2 --ink3 --acc --accT --onAcc
 *      --up --dn --pro --nav-* --rank-* --series-* --dur-* ...), each pointed
 *      at its Noir value, so every page is Noir without touching its markup.
 *   3. ALIASES — the ~60 older names (--bg2, --text, --accent-cta, --m3-*).
 *
 * NAME TRAP: in Noir `--ink-1` (with a hyphen and a digit) is a GROUND
 * colour; the product's `--ink` / `--ink2` / `--ink3` are TEXT colours. They
 * are different tokens and both exist here on purpose.
 *
 * Themes (owner decision 2026-09-25, kept by the Noir decision): dark is the
 * default; [data-theme="light"] is an explicit choice; absent means dark
 * whatever the OS prefers. The light palette is scoped to body.cf-themable so
 * a legacy template with hardcoded dark surfaces is not handed light chrome
 * over dark content. Light is ice white, the same blue (deeper), navy type.
 *
 * BRAND COLOUR: BLUE (owner's decision, 2026-10-16: "change the gold colour
 * scheme to match the blue"). The ramp was sampled from the new brand art
 * (the Boss Bull icon on royal blue, and the CARTEL banner): electric
 * #1687FF, royal #0659B7, deep navy #0F264F / #061735. The --gold-* names
 * stay as ALIASES of --blue-* so every stylesheet keeps working; --molten is
 * the blue molten (ice -> electric -> royal -> deep). Rank metals keep their
 * metal tones (they are ranks, not brand). The ONE live accent --ion moved
 * from cyan to aqua-teal so it never reads as the primary blue.
 *
 * AA (tests/test_accent_contrast.py computes these from this file):
 *   dark  --acc #3d97ff under --on-molten #04122a      6.28:1
 *   dark  --accent-text #7cb8ff on --ink-4 #122036     7.90:1 (worst ground)
 *   dark  --text-3 #8b9ab0 on --ink-4                  5.71:1
 *   light --acc #1f6fe0 under #ffffff                  4.76:1
 *   light --accent-text #1652b8 on --ink-4 #eaf1fb     6.30:1
 *   light --text-3 #56647c on --ink-4                  5.26:1
 *   light --up #0e6947 / --dn #c22e40 keep their earlier AA corrections.
 */


/* ── 1+2. DARK (the default): Noir tokens and the product names ────────── */
:root, [data-theme="dark"] {
  color-scheme: dark;

  /* product names, first so every parser (pnl_share_cards.py, the contrast
     test) reads the dark value; each resolves to a Noir token below */
  --bg: var(--ink-1); --s1: var(--ink-3); --s2: var(--ink-4);
  --ink: var(--text-1); --ink2: var(--text-2); --ink3: var(--text-3); --body: #d5deea;
  --acc: #3d97ff; --accT: var(--accent-text); --onAcc: var(--on-molten);
  --up: #4fe0a2; --dn: #ff5f6d;
  --upBg: rgba(79,224,162,.14); --dnBg: rgba(255,95,109,.14);
  --pro: #f2b84b; --proBg: #120d06; --proLine: #4a3a1c;
  --onPro: #1c1209;   /* label on an amber FILL */

  /* ground and surfaces */
  --ink-0: #03070f;                 /* deepest: bezel inner, dial */
  --ink-1: #050b17;                 /* page: deep navy ink */
  --ink-2: #081120;                 /* sunken: inputs, segmented track */
  --ink-3: #0c1729;                 /* card */
  --ink-4: #122036;                 /* raised control */
  --ink-5: #1c2d48;                 /* hairline on raised, sheet grabber */
  --ground-rgb: 5 11 23;
  --ground-hi: #0b1a33;
  --raise: 17 29 49;
  --card-hi: #122036; --card-lo: #09121f;
  --sheet-hi: #101c30; --sheet-lo: #081120;
  --well-hi: #0d1626; --well-lo: #060c17;
  --badge-hi: #11213b; --badge-lo: #08101e;
  --surface-hover: #0b1424;
  --well: rgb(0 0 0 / .26);         /* figure wells inside cards */
  --tint: 214 232 255;              /* light-on-dark channel: rgb(var(--tint) / .04) */
  --shade: 0 0 0;
  --scrim-rgb: 2 5 12;
  --ion-ground: 4 28 28;

  /* text: ice white, never pure white */
  --text-1: #eef3fb;
  --text-2: #a7b4c8;
  --text-3: #8b9ab0;
  --text-4: #4a566a;
  --accent-text: #7cb8ff;           /* blue as TEXT (= --blue-300) */
  --accent-text-strong: #b0d4ff;    /* blue figures (= --blue-200) */
  --on-molten: #04122a;
  --on-ion: #032622;

  /* molten blue: brand electric #1687FF / royal #0659B7 / navy #0F264F ramped */
  --blue-50: #eef6ff; --blue-100: #d6e9ff; --blue-200: #b0d4ff; --blue-300: #7cb8ff;
  --blue-400: #3d97ff; --blue-500: #1687ff; --blue-600: #0f6ad8; --blue-700: #0b4fa8;
  --blue-800: #0b3570; --blue-900: #071a38;
  --gold-50: var(--blue-50); --gold-100: var(--blue-100); --gold-200: var(--blue-200); --gold-300: var(--blue-300);
  --gold-400: var(--blue-400); --gold-500: var(--blue-500); --gold-600: var(--blue-600); --gold-700: var(--blue-700);
  --gold-800: var(--blue-800); --gold-900: var(--blue-900);
  --glow: 61 151 255;
  --molten: linear-gradient(118deg, #d4e9ff 0%, #8cc4ff 22%, #4aa0ff 46%, #2f86ff 64%, #1a5fd0 100%);
  --molten-text: linear-gradient(100deg, #eef6ff 0%, #b0d4ff 30%, #6aaeff 62%, #3d97ff 100%);
  --molten-edge: linear-gradient(180deg, rgba(214,233,255,.42), rgba(22,135,255,.08) 40%, rgba(22,135,255,0) 70%);
  --molten-hi: rgba(214,233,255,.55);    /* the molten fill's own rim */
  --molten-lo: rgba(6,40,110,.35);       /* its inset royal base */
  --sheen-rgb: 236 245 255;              /* the light sweep, the ripple, a top highlight */

  /* the ONE electric accent: ion = live / active only (aqua-teal, so it never
     reads as the primary blue) */
  --ion: #40ead2; --ion-rgb: 64 234 210;

  /* direction, as channels */
  --up-rgb: 79 224 162; --dn-rgb: 255 95 109;

  /* ember: the celebration palette (sparks, embers), as HSL parts */
  --ember-h: 208; --ember-h-span: 22; --ember-s: 100%; --ember-l: 70%;

  /* rank metals, Associate -> Boss: base / highlight / shadow */
  --metal-associate: #8d939c; --metal-associate-hi: #d7dce3; --metal-associate-lo: #3a3e45;
  --metal-soldier: #c07a45;   --metal-soldier-hi: #f3c194;   --metal-soldier-lo: #5a3016;
  --metal-capo: #c6ccd6;      --metal-capo-hi: #ffffff;      --metal-capo-lo: #5d6470;
  --metal-underboss: #e0b464; --metal-underboss-hi: #fff0c4; --metal-underboss-lo: #7a5420;
  --metal-boss: #f4d79a;      --metal-boss-hi: #fffaf0;      --metal-boss-lo: #2a1c0e;

  /* chart series: brand blue, ion, jade, amethyst, ember, gold, brass, rose */
  --series-1: #7cb8ff; --series-2: #40ead2; --series-3: #4fe0a2; --series-4: #c08cff;
  --series-5: #ff9b5c; --series-6: #ecc286; --series-7: #f2e58a; --series-8: #ff6fa8;

  /* chains (one dot colour per chain; NA.chainChip in the reference) */
  --chain-solana: #b98cff; --chain-base: #5b8cff; --chain-bsc: #f3c74f;
  --chain-arbitrum: #62b5ff; --chain-polygon: #a77bff; --chain-robinhood: #c6f25b;
  --chain-ethereum: #9aa9ff; --chain-monad: #a98bff; --chain-hyperevm: #5fe3c4;

  /* navigation hues (navigation.HUES): drawn from the Noir series */
  --nav-feed: #5fd0ff; --nav-discover: #c08cff; --nav-market: #4fe0a2; --nav-bot: #40ead2;
  --nav-traders: #ff9b5c; --nav-calls: #f2e58a; --nav-leaderboard: #7cb8ff; --nav-groups: #8fb4ff;
  --nav-promote: #ff6fa8; --nav-launch: #4fe0a2; --nav-share: #9aa7ba; --nav-admin: #7cb8ff;
  --nav-portfolio: #4fe0a2; --nav-profile: #7cb8ff; --nav-trade: #3d97ff; --nav-history: #8fb4ff;
  --nav-referrals: #f2e58a; --nav-settings: #9aa7ba; --nav-about: #9aa7ba;

  /* family ranks (gamification.RANKS): each rank's metal */
  --rank-associate: #8d939c; --rank-soldier: #d08a55; --rank-capo: #c6ccd6;
  --rank-underboss: #e0b464; --rank-boss: #f4d79a;
}

/* ── 1. NOIR: theme-independent tokens ──────────────────────────────────── */
:root {
  /* type: Space Grotesk for words, JetBrains Mono for every figure */
  --font-display: 'Space Grotesk', ui-sans-serif, system-ui, sans-serif;
  --font-body: 'Space Grotesk', ui-sans-serif, system-ui, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, 'SFMono-Regular', Menlo, monospace;
  --font-ui: var(--font-body);
  --font-num: var(--font-mono);
  --fs-hero: clamp(40px, 7.4vw, 104px); --lh-hero: .94; --fw-hero: 700; --tr-hero: -.05em;
  --fs-h1: clamp(30px, 4.4vw, 56px);    --lh-h1: 1.02;  --fw-h1: 700;   --tr-h1: -.035em;
  --fs-page-title: 26px;                --lh-page-title: 1.1; --fw-page-title: 700; --tr-page-title: -.03em;
  --fs-h2: clamp(22px, 2.6vw, 34px);    --lh-h2: 1.1;   --fw-h2: 700;   --tr-h2: -.03em;
  --fs-h3: 18px; --lh-h3: 1.2; --fw-h3: 600; --tr-h3: -.01em;
  --fs-body: 15px; --lh-body: 1.55; --fw-body: 400;
  --fs-small: 13px; --lh-small: 1.45;
  --fs-micro: 11px; --lh-micro: 1.2; --fw-micro: 600;
  --fs-figure-xl: clamp(26px, 3.2vw, 42px);
  --fs-figure: 20px;
  --tr-caps: .16em; --track-caps: var(--tr-caps);

  /* space: a 4px grid */
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 20px;
  --sp-6: 24px; --sp-8: 32px; --sp-10: 40px; --sp-12: 48px; --sp-16: 64px; --sp-24: 96px;
  --gutter: clamp(16px, 4vw, 48px);
  --maxw: 1320px;
  --rail-w: 232px; --rail-w-collapsed: 72px;
  --bar-h: 64px;
  --tap: 44px;                       /* minimum touch target */
  --pad-compact: 12px; --pad-comfortable: 16px;

  /* radii: badge 6 · control 10 · card 14 · sheet 20 · hero 28 · pill */
  --r-badge: 6px; --r-control: 10px; --r-card: 14px; --r-sheet: 20px; --r-full: 999px;
  --r-xs: 6px; --r-sm: 10px; --r-md: 14px; --r-lg: 20px; --r-xl: 28px; --r-pill: 999px;

  /* glass */
  --blur: 16px; --glass-saturate: 1.2;

  /* motion (COMPONENTS.md "Motion & toasts"). The --t-* names are Noir's; the
     --dur-* names are the product's, at the same values. */
  --ease-out: cubic-bezier(.2,.8,.2,1);
  --ease-in: cubic-bezier(.55,0,1,.45);
  --ease-in-out: cubic-bezier(.65,0,.35,1);
  --ease-spring: cubic-bezier(.34,1.56,.64,1);
  --ease-draw: cubic-bezier(.3,.7,.2,1);
  --t-fast: 160ms; --t-med: 280ms; --t-slow: 520ms; --t-enter: 600ms;
  --t-count: 900ms; --t-draw: 700ms; --t-sweep: 760ms; --t-ripple: 620ms; --t-press: 90ms;
  --toast-life: 5200ms;
  --dur-fast: .16s; --dur: .28s; --dur-draw: .7s;

  /* z-index, on the product's scale (its modals sit at 1500, its tips at 9800) */
  --z-base: 0; --z-sticky: 30; --z-bar: 40; --z-popover: 900; --z-sheet: 1500;
  --z-toast: 9700; --z-overlay: 9750;

  /* breakpoints (documentation: media queries use the literals) */
  --bp-phone: 390px; --bp-phone-max: 767px; --bp-tablet: 768px; --bp-laptop: 1024px; --bp-desktop: 1280px; --bp-wide: 1440px;

  --chart-fill-top: .22; --chart-glow: 4px;

  /* Card padding follows density; compact is the default. */
  --pad: var(--pad-compact);

  /* ── density: the compact pass (owner, 2026-10-11: "more minimal and
     compact"). One dial per kind of space, so every page tightens together.
     Touch targets stay 44px: --h-btn only drops on a fine pointer at laptop
     width. */
  --wrap-pad: 16px 24px;
  --wrap-pad-phone: 10px 12px 20px;
  --gap-cols: 16px;
  --gap-section: 12px;
  --gap-stack: 10px;
  --pad-card: var(--pad) 16px;
  --pad-card-head: 12px 16px 6px;
  --row-min: 48px;
  --h-btn: 44px;
}
@media (hover:hover) and (pointer:fine) and (min-width:1025px){
  :root{ --h-btn: 36px; }
}

/* ── derived tokens + aliases ───────────────────────────────────────────── */
/* Declared on body.cf-themable as well as :root. A custom property that
   references another is resolved where it is DECLARED, so a recipe declared
   only on :root resolves against the root's (dark) values and stays dark
   under the light palette, which lives on body.cf-themable. Re-declared on
   the body, every recipe follows the theme. */
:root, body.cf-themable {
  /* Noir recipes */
  --ion-dim: rgb(var(--ion-rgb) / .14);
  --ion-glow: 0 0 12px rgb(var(--ion-rgb) / .55), 0 0 2px rgb(var(--ion-rgb) / .9);
  --up-dim: rgb(var(--up-rgb) / .14);
  --dn-dim: rgb(var(--dn-rgb) / .14);
  --danger: var(--dn);
  --rank-ink: var(--text-1);
  --glass: rgb(var(--raise) / .62);
  --glass-edge: rgb(var(--tint) / .09);
  --glass-edge-hi: rgb(var(--tint) / .18);
  --glass-fill: linear-gradient(180deg, rgb(var(--raise) / .7), rgb(var(--raise) / .6) 38%, var(--glass));
  --glow-gold: 0 0 0 1px rgb(var(--glow) / .35), 0 8px 30px rgb(var(--glow) / .28);
  --focus-ring: 0 0 0 2px var(--ink-1), 0 0 0 4px var(--gold-300);
  --focus: var(--focus-ring);
  --chart-up: var(--up); --chart-down: var(--dn);
  --chart-grid: rgb(var(--tint) / .06);
  --chart-crosshair: rgb(var(--glow) / .55);
  /* the ground: navy ink, a blue light from above, a hint of ion top-right,
     royal blue bottom-left, and a 7% film grain drawn by an SVG turbulence filter */
  --ground:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 .85  0 0 0 0 .92  0 0 0 0 1  0 0 0 .055 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>"),
    radial-gradient(1200px 600px at 50% -10%, rgb(var(--glow) / .16), transparent 60%),
    radial-gradient(900px 500px at 100% 0%, rgb(var(--ion-rgb) / .05), transparent 60%),
    radial-gradient(800px 800px at 0% 100%, rgb(var(--glow) / .14), transparent 60%);

  /* product names that are recipes */
  --line: rgb(var(--tint) / .1);
  --grid: var(--chart-grid);
  --accBg: rgb(var(--glow) / .16);
  --scrim: rgb(var(--scrim-rgb) / .66);
  --e1: var(--shadow-2);
  --e2: var(--shadow-3);

  /* older names */
  --bg2: var(--s1);
  --bg3: var(--s2);
  --bg4: var(--s2);
  --text: var(--ink);
  --muted: var(--ink2);
  --dim: var(--ink3);
  --border: var(--line);
  --border2: var(--glass-edge-hi);
  --glass-border: var(--glass-edge);

  --accent: var(--acc);
  --accent-rgb: 61,151,255;
  --accent-cta: var(--acc);        /* a FILL: its label is --onAcc */
  --accent-ink: var(--accT);       /* accent as TEXT */
  --accent-fill: var(--molten);    /* the molten FILL, where a gradient is allowed */
  --gold: var(--acc);
  --gold2: var(--accT);
  --gold-rgb: 61,151,255;
  --on-gold: var(--onAcc);

  --green: var(--up);
  --green2: var(--up);
  --green-glow: var(--upBg);
  --red: var(--dn);
  --yellow: var(--pro);
  --blue: var(--series-6);
  --purple: var(--series-4);

  --m3-background: var(--bg);
  --m3-surface-lowest: var(--bg);
  --m3-surface-low: var(--s1);
  --m3-surface: var(--s1);
  --m3-surface-high: var(--s2);
  --m3-surface-highest: var(--s2);
  --m3-surface-bright: var(--s2);
  --m3-on-surface: var(--ink);
  --m3-on-surface-variant: var(--ink2);
  --m3-outline: var(--ink3);
  --m3-outline-variant: var(--line);
  --m3-primary: var(--accT);
  --m3-primary-container: var(--acc);
  --m3-on-primary: var(--onAcc);
  --m3-on-primary-container: var(--onAcc);
  --m3-primary-fixed: var(--gold-300);  /* brand fill, hovered */
  --m3-primary-fixed-dim: var(--acc);
  --m3-secondary: var(--series-2);
  --m3-secondary-container: var(--series-2);
  --m3-tertiary-fixed: var(--series-5);
  --m3-tertiary-fixed-dim: var(--series-5);
  --m3-error: var(--dn);
  --m3-error-container: var(--dnBg);

  --card-radius: var(--r-card);

  --space-xs: var(--sp-1);
  --space-sm: var(--sp-2);
  --gutter-compact: var(--sp-3);
  --space-md: var(--sp-4);
  --space-lg: var(--sp-6);
  --space-xl: var(--sp-8);

  --shadow-card: var(--shadow-2);
  --cf-scrim: var(--scrim);
  --cf-scrim-strong: rgb(var(--scrim-rgb) / .88);
  --cf-modal-shadow: var(--shadow-3);

  --font-sans: var(--font-body);
}

/* elevation + glass fill, per theme (the light values are warm and low) */
:root, [data-theme="dark"] {
  --glass-strong: rgba(10,19,34,.88);
  --shadow-1: 0 1px 0 rgb(var(--tint) / .05) inset, 0 1px 2px rgb(var(--shade) / .5), 0 4px 12px rgb(var(--shade) / .35);
  --shadow-2: 0 1px 0 rgb(var(--tint) / .07) inset, 0 2px 4px rgb(var(--shade) / .45), 0 12px 32px rgb(var(--shade) / .45);
  --shadow-3: 0 1px 0 rgb(var(--tint) / .09) inset, 0 4px 10px rgb(var(--shade) / .5), 0 28px 64px rgb(var(--shade) / .6);
}

html{min-height:100%;background:var(--bg)}

/* ── LIGHT: ice white, the brand blue (deeper), navy type ───────────────── */
:root[data-theme="light"]:has(body.cf-themable),
html:has(body.cf-themable.cf-light){
  --bg: #f3f7fd;
  color-scheme: light;
}
:root[data-theme="light"] body.cf-themable,
body.cf-themable.cf-light{
  --bg: #f3f7fd; --s1: #ffffff; --s2: #eaf1fb;
  --ink: #0a1628; --ink2: #45536a; --ink3: #56647c; --body: #1a2638;
  --acc: #1f6fe0; --accT: #1652b8; --onAcc: #ffffff;
  --up: #0e6947; --upBg: rgba(14,105,71,.10);
  --dn: #c22e40; --dnBg: rgba(194,46,64,.10);
  --pro: #936100; --proBg: #fbf3e2; --proLine: #ebd6a8;
  --onPro: #ffffff;

  --ink-0: #0a1426; --ink-1: #f3f7fd; --ink-2: #e8eff9; --ink-3: #ffffff; --ink-4: #eaf1fb; --ink-5: #cfdbec;
  --ground-rgb: 243 247 253; --ground-hi: #f8fbff; --raise: 255 255 255;
  --card-hi: #ffffff; --card-lo: #f6f9fe; --sheet-hi: #ffffff; --sheet-lo: #f1f6fd;
  --well-hi: #e8eff9; --well-lo: #dde7f4; --badge-hi: #eef5ff; --badge-lo: #dce9fb; --surface-hover: #e8f0fb;
  --well: rgb(30 70 140 / .07);
  --glass: rgb(var(--raise) / .74); --glass-edge: rgb(var(--tint) / .11); --glass-edge-hi: rgb(var(--tint) / .2);
  --tint: 20 40 80; --shade: 30 50 90; --scrim-rgb: 8 18 38; --ion-ground: 226 250 246;
  --text-1: #0a1628; --text-2: #45536a; --text-3: #56647c; --text-4: #9eabbf;
  --accent-text: #1652b8; --accent-text-strong: #0f3f8f;
  --on-molten: #ffffff; --on-ion: #ffffff;
  --molten: linear-gradient(118deg, #4a9dff 0%, #2a7ff0 22%, #1f6fe0 46%, #1a5fc8 64%, #0f3f8f 100%);
  --molten-text: linear-gradient(100deg, #2a7ff0 0%, #1f6fe0 35%, #1652b8 70%, #0f3f8f 100%);
  --molten-hi: rgba(255,255,255,.45);
  --molten-lo: rgba(6,30,80,.35);
  --sheen-rgb: 255 255 255;
  --glow: 31 111 224;
  --ion: #0b7d70; --ion-rgb: 11 125 112;
  --up-rgb: 14 105 71; --dn-rgb: 194 46 64;
  --ember-l: 45%;
  --glass-strong: rgba(255,252,247,.94);
  --molten-edge: linear-gradient(180deg, rgba(255,255,255,.9), rgba(31,111,224,.18) 40%, rgba(31,111,224,0) 70%);
  --shadow-1: 0 1px 0 rgba(255,255,255,.8) inset, 0 1px 2px rgb(var(--shade) / .08), 0 4px 12px rgb(var(--shade) / .07);
  --shadow-2: 0 1px 0 rgba(255,255,255,.9) inset, 0 2px 4px rgb(var(--shade) / .07), 0 12px 32px rgb(var(--shade) / .1);
  --shadow-3: 0 1px 0 rgba(255,255,255,.9) inset, 0 4px 10px rgb(var(--shade) / .08), 0 28px 64px rgb(var(--shade) / .16);
  --focus-ring: 0 0 0 2px var(--ink-1), 0 0 0 4px var(--gold-600);
  --series-1: #1f6fe0; --series-2: #0b7d70; --series-3: #12895c; --series-4: #7d4fd0;
  --series-5: #d2622a; --series-6: #a8743c; --series-7: #9a8320; --series-8: #c23c78;
  --metal-boss-lo: #4a3218;
  --chain-solana: #7d4fd0; --chain-base: #2f5fd6; --chain-bsc: #a8840f;
  --chain-arbitrum: #2a7cc4; --chain-polygon: #6e44c4; --chain-robinhood: #5f7d12; --chain-ethereum: #4b5bc4; --chain-monad: #6a48c8; --chain-hyperevm: #11806a;
  --nav-feed: #0a76b8; --nav-discover: #7d4fd0; --nav-market: #12895c; --nav-bot: #0b7d70;
  --nav-traders: #c4581f; --nav-calls: #8a7314; --nav-leaderboard: #1652b8; --nav-groups: #4a68c8;
  --nav-promote: #c23c78; --nav-launch: #12895c; --nav-share: #56647c; --nav-admin: #1652b8;
  --nav-portfolio: #12895c; --nav-profile: #1652b8; --nav-trade: #1652b8; --nav-history: #4a68c8;
  --nav-referrals: #8a7314; --nav-settings: #56647c; --nav-about: #56647c;
  --rank-associate: #5d6470; --rank-soldier: #8a4f22; --rank-capo: #4f5866;
  --rank-underboss: #7a5420; --rank-boss: #6b4a14;
  --chart-crosshair: rgb(var(--glow) / .7);
}

/* Comfortable density: set on <body data-density="comfortable">. */
body[data-density="comfortable"]{ --pad: var(--pad-comfortable); }

body{
  background-color:var(--bg);
  background-image:var(--ground);
  background-repeat:repeat,no-repeat,no-repeat,no-repeat;
  background-attachment:fixed;
  color:var(--ink);
  font-family:var(--font-body);
  font-weight:500;
  -webkit-font-smoothing:antialiased;
  /* Without this the ground stops where the content does, and a short page
     shows the browser's own canvas below the fold. */
  min-height:100vh;
}
::selection{background:rgb(var(--glow) / .35);color:var(--ink)}

/* ── type ramp (DESIGN_PROMPT §2) ─────────────────────────────────────────── */
.cf-display{font:var(--fw-h1) var(--fs-h1)/var(--lh-h1) var(--font-display);letter-spacing:var(--tr-h1)}
.cf-page-title{font-family:var(--font-display);font-size:var(--fs-page-title);line-height:var(--lh-page-title);font-weight:var(--fw-page-title);letter-spacing:var(--tr-page-title)}
.cf-card-title{font-size:16px;line-height:1.3;font-weight:700}
.cf-handle{font-size:15px;font-weight:700}
.cf-body{font-size:14px;line-height:1.45;font-weight:500;color:var(--body)}
.cf-label{font-size:12px;font-weight:600}
.cf-mono-label{font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:500}
/* Noir caps: 11px mono, wide tracking (section labels, table heads, chips) */
.cf-caps{font:600 var(--fs-micro)/var(--lh-micro) var(--font-mono);letter-spacing:var(--tr-caps);text-transform:uppercase;color:var(--ink3)}
.cf-molten-text{background:var(--molten-text);-webkit-background-clip:text;background-clip:text;color:transparent}
.cf-hero-price{font-family:var(--font-mono);font-size:var(--fs-figure-xl);font-weight:600;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.cf-row-figure{font-family:var(--font-num);font-size:13px;font-weight:500;font-variant-numeric:tabular-nums}
/* Earlier names, kept so pages that opted in keep their sizes. */
.cf-headline-lg{font-size:26px;line-height:1.2;font-weight:700}
.cf-headline-md{font-size:22px;line-height:1.25;font-weight:700}
.cf-headline-sm{font-size:18px;line-height:1.3;font-weight:700}
.cf-title-md{font-size:16px;line-height:1.3;font-weight:700}
.cf-body-lg{font-size:16px;line-height:1.45}
.cf-body-md{font-size:14px;line-height:1.45}
.cf-body-sm{font-size:12px;line-height:1.4}
.cf-label-md{font-size:12px;letter-spacing:.04em;font-weight:600;text-transform:uppercase}
.cf-label-sm{font-size:11px;letter-spacing:.08em;font-weight:700;text-transform:uppercase}

/* Figures: JetBrains Mono, tabular, so columns of prices align. */
.cf-num,.cf-data{font-family:var(--font-num);font-variant-numeric:tabular-nums}

.cf-pill,.cf-avatar{border-radius:var(--r-full)}

/* Focus ring (Noir --focus-ring: a 2px ground gap, then 2px gold), drawn as
   an outline so it never replaces an element's own shadow. */
:focus-visible{outline:2px solid var(--focus-c,var(--gold-300));outline-offset:2px}
:root[data-theme="light"] body.cf-themable{--focus-c:var(--gold-600)}

/* ── theme toggle ─────────────────────────────────────────────────────────── */
.cf-theme-toggle{
  width:40px;height:40px;flex:0 0 40px;
  display:inline-flex;align-items:center;justify-content:center;
  border-radius:var(--r-pill);border:1px solid var(--glass-edge-hi);
  background:var(--s2);color:var(--ink2);cursor:pointer;padding:0;box-shadow:var(--shadow-1);
  transition:color var(--dur-fast),background var(--dur-fast),border-color var(--dur-fast);
}
.cf-theme-toggle:hover{color:var(--accent-text-strong);border-color:rgb(var(--glow) / .45)}
.cf-theme-toggle svg{transition:transform var(--t-med) var(--ease-spring)}
.cf-theme-toggle:hover svg{transform:rotate(-18deg)}
.cf-theme-toggle svg{width:16px;height:16px;display:block}
.cf-theme-toggle .cf-ico-sun{display:none}
:root[data-theme="light"] .cf-theme-toggle .cf-ico-sun{display:block}
:root[data-theme="light"] .cf-theme-toggle .cf-ico-moon{display:none}

@media (prefers-reduced-motion:reduce){
  .cf-theme-toggle{transition:none}
}

/* ── brand marks (DESIGN_PROMPT §1) ───────────────────────────────────────
   The wordmark is set in TYPE: the display face, white on dark and ink on light
   -- "never set the wordmark in gold". New markup uses .cf-wordmark-text.

   .cf-wordmark is the older EMPTY element drawn through a mask image, still
   used in six places. It keeps working, recoloured to --ink (it was gold, which
   the brand rules now forbid) until each place moves to the text mark. */
.cf-wordmark-text{
  font-family:var(--font-display);font-weight:700;letter-spacing:.14em;
  color:var(--ink);text-transform:uppercase;white-space:nowrap;
}
.cf-wordmark{
  display:block;
  background-color:var(--ink);
  -webkit-mask-image:url('/static/img/cartel-family-wordmark-mask.png');
          mask-image:url('/static/img/cartel-family-wordmark-mask.png');
  -webkit-mask-size:contain;   mask-size:contain;
  -webkit-mask-repeat:no-repeat; mask-repeat:no-repeat;
  -webkit-mask-position:center;  mask-position:center;
}
.cf-tagline{
  font-family:var(--font-display);font-weight:700;letter-spacing:.26em;
  color:var(--accT);text-transform:uppercase;
}
.cf-icon-tile{
  display:block;border-radius:22%;object-fit:cover;
  background:url('/static/brand/icon-tile-128.png') center/cover no-repeat;
}

/* A member who predates handles (users.username empty) reads "unnamed" on
   every list -- never their wallet (handles.UNNAMED, decided 2026-10-09).
   Lower-case, muted, no '@': it is the absence of a name, not a name. */
.cf-unnamed{
  color:var(--ink3);font-weight:500;font-style:normal;text-transform:none;letter-spacing:0;
}

/* Native controls follow the theme. Without color-scheme the browser drew
   every <select>'s open list (Bridge's From/To, Convert's network, settings)
   in light-mode colours on the dark app -- white text on white, unreadable
   (owner's report, 2026-10-11). The open list is painted by the OS, so the
   options get the theme's own surface and ink as well. */
:root{color-scheme:dark}
:root[data-theme="light"]{color-scheme:light}
select option,select optgroup{background-color:var(--s1);color:var(--ink)}

/* ── shared primitives: icons and tooltips ────────────────────────────────
   CFIcon (static/cf-icons.js, Lucide subset) draws in currentColor at
   Lucide's own 2px stroke, 1em square unless a size is given. */
.cf-i{
  width:1em;height:1em;flex:none;display:inline-block;vertical-align:-.125em;
  fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;
}
/* The glyph beside a menu label (navigation.icon_svg / {{ nav_icon() }}):
   a fixed box that never shrinks or shifts, currentColor so it follows the
   row lit, dim, dark or light. The label stays; this only sits beside it. */
.cf-nav-i{flex:none;display:inline-block;vertical-align:-3px;width:16px;height:16px}
.cf-nav-i[width="18"]{width:18px;height:18px}
.cf-nav-i[width="14"]{width:14px;height:14px}
.cf-nav-i[width="12"]{width:12px;height:12px}
/* CFFloat tooltips ([data-cf-tip]). One shared node, positioned by
   Floating UI; never parked invisible -- it is display:none until shown. */
.cf-tip{
  display:none;z-index:9800;pointer-events:none;max-width:240px;
  padding:7px 10px;border-radius:var(--r-sm);
  background:var(--glass-strong);color:var(--ink);border:1px solid rgb(var(--glow) / .3);
  font:500 12px/1.35 var(--font-body);box-shadow:var(--shadow-3);
  -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
}
.cf-tip.on{display:block}
/* One dropdown menu (CFFloat.menu positions it): the profile and DM "more"
   menus, a message's own menu, the admin role picker. Each used to carry its
   own copy of these rules, at three slightly different paddings. */
.cf-menu{
  display:none;position:absolute;z-index:900;min-width:150px;padding:4px;
  background:var(--glass-strong);border:1px solid var(--glass-edge-hi);border-radius:var(--r-md);box-shadow:var(--shadow-3);
  -webkit-backdrop-filter:blur(var(--blur)) saturate(var(--glass-saturate));backdrop-filter:blur(var(--blur)) saturate(var(--glass-saturate));
}
.cf-menu.open{display:block;animation:cf-pop-in var(--dur-pop) var(--ease-spring)}
@keyframes cf-pop-in{from{transform:translateY(-4px) scale(.97)}to{transform:none}}
.cf-menu>a,.cf-menu>button{
  display:flex;align-items:center;gap:8px;width:100%;min-height:36px;box-sizing:border-box;
  text-align:left;background:none;border:0;cursor:pointer;text-decoration:none;
  padding:0 10px;border-radius:var(--r-sm);font:500 13.5px var(--font-body);color:var(--ink);transition:background var(--dur-fast);
}
.cf-menu>a:hover,.cf-menu>button:hover,.cf-menu>a:focus-visible,.cf-menu>button:focus-visible{background:rgb(var(--tint) / .06)}
.cf-menu>.danger{color:var(--dn)}
@media (pointer:coarse){.cf-menu>a,.cf-menu>button{min-height:44px}}

/* ── motion system (2026-10-11: "looks plain, no animations") ─────────────
   One set of durations, easings and a stagger step, read by every surface
   (CSS here, JS through CFMotion, the Mini App through the same file) instead
   of the scattered .3s / .25s / cubic-bezier literals each stylesheet used to
   guess. Values are Syndicate Noir's (COMPONENTS.md "Motion & toasts"); the
   easings and --dur-fast/--dur/--dur-draw sit with the Noir tokens above.

   Two rules every class below obeys:
     - The RESTING state is the visible one. An entrance is a class script
       adds and removes on animationend (CFMotion.enter); nothing is parked
       at opacity 0 waiting for it, so a paused, hidden or printed page still
       shows its content.
     - prefers-reduced-motion shows the finished state: the classes stop
       animating and the content is simply there. */
:root{
  --dur-flash: .9s;            /* a price tick's glow, in and out            */
  --dur-enter: .6s;            /* a card, a row, a sheet arriving (--t-enter) */
  --dur-exit: .26s;            /* the same leaving -- always faster           */
  --dur-count: .9s;            /* a figure counting to its value (--t-count) */
  --dur-pop: .32s;             /* a like / follow / copy acknowledgement     */
  --stagger: 60ms;             /* between siblings entering together         */
  --stagger-max: 8;            /* siblings past this arrive with the 8th     */
}

/* enter: rise + fade, from script only (CFMotion.enter adds, then removes) */
@keyframes cf-enter-rise{from{opacity:0;transform:translateY(16px) scale(.985);filter:blur(4px)}to{opacity:1;transform:none;filter:none}}
@keyframes cf-enter-fade{from{opacity:0}to{opacity:1}}
@keyframes cf-enter-down{from{opacity:0;transform:translateY(-14px)}to{opacity:1;transform:none}}
@keyframes cf-enter-left{from{opacity:0;transform:translateX(28px)}to{opacity:1;transform:none}}
@keyframes cf-enter-right{from{opacity:0;transform:translateX(-28px)}to{opacity:1;transform:none}}
@keyframes cf-exit-left{from{opacity:1;transform:none}to{opacity:0;transform:translateX(-36px) rotate(-1.5deg)}}
@keyframes cf-exit-right{from{opacity:1;transform:none}to{opacity:0;transform:translateX(36px) rotate(1.5deg)}}
.cf-enter{animation:cf-enter-rise var(--dur-enter) var(--ease-out) var(--cf-delay,0s) both}
.cf-enter-fade{animation:cf-enter-fade var(--dur-enter) var(--ease-out) var(--cf-delay,0s) both}
.cf-enter-down{animation:cf-enter-down var(--dur-enter) var(--ease-out) var(--cf-delay,0s) both}
.cf-enter-left{animation:cf-enter-left var(--dur-enter) var(--ease-out) var(--cf-delay,0s) both}
.cf-enter-right{animation:cf-enter-right var(--dur-enter) var(--ease-out) var(--cf-delay,0s) both}
.cf-exit-left{animation:cf-exit-left var(--dur-exit) var(--ease-in) both}
.cf-exit-right{animation:cf-exit-right var(--dur-exit) var(--ease-in) both}

/* flash: a value that just moved tints up / down and settles back */
@keyframes cf-flash-up{0%{background-color:var(--upBg);color:var(--up);text-shadow:0 0 14px rgb(var(--up-rgb) / .8)}100%{background-color:transparent}}
@keyframes cf-flash-dn{0%{background-color:var(--dnBg);color:var(--dn);text-shadow:0 0 14px rgb(var(--dn-rgb) / .8)}100%{background-color:transparent}}
.cf-flash-up,.cf-flash-dn{border-radius:var(--r-badge)}
.cf-flash-up{animation:cf-flash-up var(--dur-flash) var(--ease-out)}
.cf-flash-dn{animation:cf-flash-dn var(--dur-flash) var(--ease-out)}

/* pop: an action acknowledged (like, follow, copy) */
@keyframes cf-pop{0%{transform:scale(1)}40%{transform:scale(1.18)}100%{transform:scale(1)}}
.cf-pop{animation:cf-pop var(--dur-pop) var(--ease-spring)}
/* a count that changed ticks up into place */
@keyframes cf-tick-up{from{transform:translateY(60%);opacity:.2}to{transform:none;opacity:1}}
@keyframes cf-tick-dn{from{transform:translateY(-60%);opacity:.2}to{transform:none;opacity:1}}
.cf-tick-up,.cf-tick-dn{display:inline-block}
.cf-tick-up{animation:cf-tick-up var(--dur-fast) var(--ease-out)}
.cf-tick-dn{animation:cf-tick-dn var(--dur-fast) var(--ease-out)}

/* a live dot: one soft pulse per new value (never an infinite loop) */
@keyframes cf-pulse{0%{box-shadow:0 0 0 0 var(--cf-pulse,rgb(var(--glow) / .55))}100%{box-shadow:0 0 0 12px transparent}}
.cf-pulse{animation:cf-pulse .7s var(--ease-out)}

/* the success mark: a ring and a tick that draw, used by the trade sheet */
.cf-mark{display:inline-block;width:44px;height:44px;color:var(--up)}
.cf-mark circle{stroke-dasharray:132;stroke-dashoffset:0}
.cf-mark path{stroke-dasharray:30;stroke-dashoffset:0}
.cf-mark.is-drawing circle{animation:cf-mark-ring .45s var(--ease-out) both}
.cf-mark.is-drawing path{animation:cf-mark-tick .3s var(--ease-out) .32s both}
@keyframes cf-mark-ring{from{stroke-dashoffset:132}to{stroke-dashoffset:0}}
@keyframes cf-mark-tick{from{stroke-dashoffset:30}to{stroke-dashoffset:0}}

/* "N new" pill: new items wait above the list instead of shoving it */
.cf-newpill{
  position:sticky;top:calc(var(--cf-sticky-top,72px) + 8px);z-index:30;
  display:flex;justify-content:center;height:0;overflow:visible;pointer-events:none;
}
.cf-newpill[hidden]{display:none}
.cf-newpill button{
  pointer-events:auto;display:inline-flex;align-items:center;gap:6px;
  height:36px;padding:0 16px;border-radius:var(--r-pill);cursor:pointer;
  border:1px solid rgb(var(--ion-rgb) / .45);background:var(--glass-strong);color:var(--ion);
  font:600 12.5px var(--font-mono);letter-spacing:.04em;
  box-shadow:var(--ion-glow),var(--shadow-3);animation:cf-enter-down var(--dur-enter) var(--ease-spring);
  -webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);
}
.cf-newpill button:focus-visible{outline:2px solid var(--ion);outline-offset:2px}

/* skeleton shimmer: a loading block that says "loading", not "empty" */
@keyframes cf-shimmer{from{background-position:150% 0}to{background-position:-50% 0}}
.cf-skel{
  background:linear-gradient(90deg,rgb(var(--tint) / .04) 0%,rgb(var(--tint) / .1) 45%,rgb(var(--tint) / .04) 90%);
  background-size:200% 100%;animation:cf-shimmer 1.4s linear infinite;border-radius:var(--r-md);
}

@media (prefers-reduced-motion:reduce){
  .cf-enter,.cf-enter-fade,.cf-enter-down,.cf-enter-left,.cf-enter-right,
  .cf-flash-up,.cf-flash-dn,.cf-pop,.cf-tick-up,.cf-tick-dn,.cf-pulse,.cf-skel,
  .cf-newpill button{animation:none!important}
  .cf-exit-left,.cf-exit-right{animation:none!important;opacity:0}
  .cf-mark.is-drawing circle,.cf-mark.is-drawing path{animation:none!important}
}

/* Reduced motion: every Noir timing token is 0 -- no entrances, sweeps,
   ripples, magnet, shimmer or ring spin; the finished state shows. */
@media (prefers-reduced-motion:reduce){
  :root{--t-fast:0ms;--t-med:0ms;--t-slow:0ms;--t-enter:0ms;--t-count:0ms;--t-draw:0ms;--t-sweep:0ms;--t-ripple:0ms;--t-press:0ms}
  .cf-theme-toggle svg,.cf-menu.open{transition:none;animation:none}
}


/* ---- static/cf-noir.css ---- */
/* Cartel Family — SYNDICATE NOIR shared components (decided 2026-10-12).
 *
 * THE Noir component library. It began as the port of the prototype's
 * noir.css (spec COMPONENTS.md, both under /design/a/*, deleted 2026-10-15
 * once every surface wore it): the reference's `na-X` became the product's
 * `cf-X` (na-btn -> cf-btn, na-chip -> cf-chip, na-glass -> cf-glass,
 * na-tabs -> cf-tabs, na-sheet -> cf-sheet ...). Comments elsewhere that
 * name /design/a/* or static/design/a/* describe where a layout came from;
 * the classes and tokens they refer to live here and in cf-theme.css.
 *
 * Every value is a token from static/cf-theme.css; this file declares no
 * colour of its own. Loaded right after cf-theme.css on every surface
 * (noir_inject.py puts the <link> there), so any page, the Mini App, the admin
 * console and the landing can use these classes.
 *
 * Two rules every rule here keeps:
 *   - The RESTING state is the visible one. Entrances are classes script adds
 *     and removes (CFMotion.enter); nothing is parked at opacity 0.
 *   - Reduced motion is the finished state: no sweep, ripple, magnet,
 *     shimmer, pulse or spin; transitions off.
 */

/* ── glass panel: real depth, a 1px light edge on top ───────────────────── */
.cf-glass{
  position:relative;border-radius:var(--r-lg);
  background:linear-gradient(180deg,rgb(var(--raise) / .66),rgb(var(--raise) / .72) 38%,var(--glass));
  border:1px solid var(--glass-edge);box-shadow:var(--shadow-2);
  -webkit-backdrop-filter:blur(var(--blur)) saturate(var(--glass-saturate));
  backdrop-filter:blur(var(--blur)) saturate(var(--glass-saturate));
}
.cf-glass::before{
  content:'';position:absolute;inset:-1px;border-radius:inherit;padding:1px;pointer-events:none;
  background:var(--molten-edge);opacity:.9;
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude;
}
.cf-panel{padding:var(--sp-5)}
.cf-panel-h{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);margin-bottom:var(--sp-4);flex-wrap:wrap}
.cf-panel-h h2,.cf-panel-h h3{margin:0;font:var(--fw-h3) var(--fs-h3)/var(--lh-h3) var(--font-display);letter-spacing:var(--tr-h3)}

/* ── live marker: the ion accent's one job ──────────────────────────────── */
.cf-live{display:inline-flex;align-items:center;gap:7px;font:600 var(--fs-micro)/1 var(--font-mono);letter-spacing:var(--tr-caps);color:var(--ion);text-transform:uppercase}
.cf-live::before{content:'';width:7px;height:7px;border-radius:50%;background:var(--ion);box-shadow:var(--ion-glow);animation:cf-beat 1.6s var(--ease-in-out) infinite}
.cf-live.is-off{color:var(--ink3)}
.cf-live.is-off::before{background:var(--text-4);box-shadow:none;animation:none}
@keyframes cf-beat{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.45;transform:scale(.7)}}

/* ── buttons: magnetic, light sweep, press, ripple ──────────────────────── */
.cf-btn{
  --mx:0px;--my:0px;
  position:relative;display:inline-flex;align-items:center;justify-content:center;gap:8px;
  min-height:var(--tap);padding:0 20px;border-radius:var(--r-pill);border:1px solid var(--glass-edge-hi);
  background:var(--ink-4);color:var(--ink);cursor:pointer;overflow:hidden;isolation:isolate;
  font:600 14px/1 var(--font-display);letter-spacing:.01em;white-space:nowrap;text-decoration:none;
  transform:translate(var(--mx),var(--my)) scale(var(--press,1));
  transition:transform var(--t-med) var(--ease-spring),box-shadow var(--t-med) var(--ease-out),background var(--t-med),border-color var(--t-med);
  box-shadow:var(--shadow-1);-webkit-tap-highlight-color:transparent;user-select:none;
}
.cf-btn svg{width:18px;height:18px;flex:none}
.cf-btn::after{ /* the light sweep */
  content:'';position:absolute;inset:-2px;z-index:-1;pointer-events:none;
  background:linear-gradient(105deg,transparent 30%,rgb(var(--sheen-rgb) / .38) 46%,rgb(var(--sheen-rgb) / .06) 54%,transparent 64%);
  transform:translateX(-120%);transition:transform 0s;
}
@media (hover:hover){
  .cf-btn:hover{border-color:rgb(var(--glow) / .45);box-shadow:var(--shadow-2),0 0 0 1px rgb(var(--glow) / .18)}
  .cf-btn:hover::after{transform:translateX(120%);transition:transform var(--t-sweep) var(--ease-out)}
}
.cf-btn:active{--press:.95;transition-duration:var(--t-press)}
.cf-btn[disabled],.cf-btn[aria-disabled="true"]{opacity:.45;cursor:not-allowed}
.cf-btn--primary{
  background:var(--molten);color:var(--on-molten);border-color:var(--molten-hi);
  box-shadow:0 1px 0 rgb(var(--sheen-rgb) / .5) inset,0 -2px 0 var(--molten-lo) inset,0 6px 22px rgb(var(--glow) / .32),0 2px 4px rgb(var(--shade) / .4);
  text-shadow:0 1px 0 rgb(var(--sheen-rgb) / .45);
}
@media (hover:hover){
  .cf-btn--primary:hover{box-shadow:0 1px 0 rgb(var(--sheen-rgb) / .55) inset,0 -2px 0 var(--molten-lo) inset,0 10px 34px rgb(var(--glow) / .45),0 2px 4px rgb(var(--shade) / .4);border-color:rgb(var(--sheen-rgb) / .8)}
}
/* The sweep (::after, z-index -1 inside the button's own stacking context)
   always paints UNDER the label; what can still wash the label out is its
   colour. A page's scoped `.page a{color}` (0,1,1) outranks `.cf-btn--primary`
   (0,1,0), so a molten link button took the gold link colour -- gold on gold,
   which read as "washed out" the moment the sheen passed (the docs hero).
   :link/:visited lift the molten label above any such rule. */
a.cf-btn--primary:link,a.cf-btn--primary:visited{color:var(--on-molten)}
.cf-btn--ghost{background:transparent;box-shadow:none}
.cf-btn--ion{background:rgb(var(--ion-rgb) / .08);border-color:rgb(var(--ion-rgb) / .35);color:var(--ion)}
.cf-btn--danger{background:var(--dn-dim);color:var(--dn);border-color:rgb(var(--dn-rgb) / .45)}
@media (hover:hover){.cf-btn--danger:hover{border-color:var(--dn);box-shadow:var(--shadow-2),0 0 0 1px rgb(var(--dn-rgb) / .3)}}
.cf-btn--sm{min-height:36px;padding:0 14px;font-size:13px}
.cf-btn--sm::before{content:'';position:absolute;inset:-4px}   /* 36px pill, 44px to a finger */
.cf-btn--block{width:100%}
.cf-btn--icon{width:var(--tap);padding:0}
.cf-btn--xl{min-height:54px;padding:0 28px;font-size:16px}

/* The ripple CFMotion spawns at the pointer. On a .cf-btn it lives inside
   the button; on any other control it is a fixed overlay clipped to the
   control's own box and radius, so the control itself is never restyled. */
.cf-ripple{
  position:absolute;border-radius:50%;pointer-events:none;z-index:-1;transform:translate(-50%,-50%) scale(0);
  background:radial-gradient(circle,rgb(var(--sheen-rgb) / .55),rgb(var(--sheen-rgb) / 0) 70%);
  animation:cf-ripple var(--t-ripple) var(--ease-out) forwards;
}
.cf-ripple-host{position:fixed;overflow:hidden;pointer-events:none;z-index:var(--z-popover)}
.cf-ripple-host .cf-ripple{z-index:0;background:radial-gradient(circle,rgb(var(--sheen-rgb) / .32),rgb(var(--sheen-rgb) / 0) 70%)}
@keyframes cf-ripple{to{transform:translate(-50%,-50%) scale(1);opacity:0}}

/* Product controls that were drawn as a flat gold fill before Noir: CFMotion
   marks each one whose computed fill IS the theme's --acc with .cf-molten,
   and it takes the molten fill and the sweep. Nothing is restyled by a
   colour literal, and a control the page later repaints keeps its own look. */
.cf-molten{
  background-image:linear-gradient(105deg,transparent 30%,rgb(var(--sheen-rgb) / .38) 46%,rgb(var(--sheen-rgb) / .06) 54%,transparent 64%),var(--molten)!important;
  background-size:300% 100%,100% 100%!important;
  background-position:100% 0,0 0!important;
  background-repeat:no-repeat!important;
  color:var(--on-molten)!important;
  border-color:var(--molten-hi)!important;
  text-shadow:0 1px 0 rgb(var(--sheen-rgb) / .45);
  box-shadow:0 1px 0 rgb(var(--sheen-rgb) / .5) inset,0 -2px 0 var(--molten-lo) inset,0 6px 22px rgb(var(--glow) / .28);
  transition:background-position var(--t-sweep) var(--ease-out),box-shadow var(--t-med) var(--ease-out),scale var(--t-press);
}
@media (hover:hover){
  .cf-molten:hover{background-position:0 0,0 0!important;box-shadow:0 1px 0 rgb(var(--sheen-rgb) / .55) inset,0 -2px 0 var(--molten-lo) inset,0 10px 34px rgb(var(--glow) / .45)}
}
.cf-molten:disabled,.cf-molten[aria-disabled="true"]{box-shadow:none}
/* press: the individual `scale` property, so it composes with whatever
   transform the control already has (a centred FAB keeps its translate) */
.cf-pressing{scale:.95;transition:scale var(--t-press) var(--ease-out)}

/* ── chips ──────────────────────────────────────────────────────────────── */
.cf-chip{
  display:inline-flex;align-items:center;gap:6px;height:24px;padding:0 9px;border-radius:var(--r-pill);
  background:rgb(var(--tint) / .05);border:1px solid var(--glass-edge);color:var(--ink2);
  font:600 10.5px/1 var(--font-mono);letter-spacing:.08em;text-transform:uppercase;white-space:nowrap;
}
.cf-chip i{width:6px;height:6px;border-radius:50%;background:var(--chain,var(--gold-400));box-shadow:0 0 8px var(--chain,transparent)}
.cf-chip--gold{color:var(--accent-text-strong);border-color:rgb(var(--glow) / .35);background:rgb(var(--glow) / .12)}
.cf-chip--ion{color:var(--ion);border-color:rgb(var(--ion-rgb) / .35);background:var(--ion-dim)}
.cf-chip--up{color:var(--up);border-color:rgb(var(--up-rgb) / .3);background:var(--up-dim)}
.cf-chip--dn{color:var(--dn);border-color:rgb(var(--dn-rgb) / .3);background:var(--dn-dim)}
button.cf-chip{cursor:pointer;min-height:32px;height:auto;padding:6px 12px;position:relative;transition:background var(--t-fast),color var(--t-fast),border-color var(--t-fast)}
button.cf-chip::before{content:'';position:absolute;inset:-6px -2px}
button.cf-chip[aria-pressed="true"]{color:var(--accent-text-strong);border-color:rgb(var(--glow) / .55);background:rgb(var(--glow) / .2)}
@media (hover:hover){button.cf-chip:hover{color:var(--ink);border-color:var(--glass-edge-hi)}}
.cf-chip[data-chain="solana"]{--chain:var(--chain-solana)}
.cf-chip[data-chain="base"]{--chain:var(--chain-base)}
.cf-chip[data-chain="bsc"]{--chain:var(--chain-bsc)}
.cf-chip[data-chain="arbitrum"]{--chain:var(--chain-arbitrum)}
.cf-chip[data-chain="polygon"]{--chain:var(--chain-polygon)}
.cf-chip[data-chain="robinhood"]{--chain:var(--chain-robinhood)}
.cf-chip[data-chain="ethereum"]{--chain:var(--chain-ethereum)}
.cf-chip[data-chain="monad"]{--chain:var(--chain-monad)}
.cf-chip[data-chain="hyperevm"]{--chain:var(--chain-hyperevm)}

/* ── avatars + token marks: API image over a designed fallback ──────────── */
.cf-ava{
  --s:40px;position:relative;flex:none;width:var(--s);height:var(--s);border-radius:50%;
  display:grid;place-items:center;overflow:hidden;color:var(--on-molten);
  font:700 calc(var(--s) * .4)/1 var(--font-display);background:var(--monogram,var(--molten));
  box-shadow:0 0 0 1px rgb(var(--tint) / .16),0 3px 10px rgb(var(--shade) / .45);
}
.cf-ava img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.cf-ava-wrap{position:relative;flex:none}
.cf-ava-wrap .cf-medal,.cf-medal-slot{position:absolute;right:-6px;bottom:-6px;line-height:0}
.cf-medal-slot:empty{display:none}
.cf-tok{
  --s:36px;position:relative;flex:none;width:var(--s);height:var(--s);border-radius:calc(var(--s) * .3);overflow:hidden;
  display:grid;place-items:center;background:var(--ink-4);box-shadow:0 0 0 1px var(--glass-edge-hi),var(--shadow-1);
}
.cf-tok svg{width:100%;height:100%}
.cf-tok img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.cf-faces{display:inline-flex}
.cf-faces .cf-ava{--s:22px;margin-left:-7px;box-shadow:0 0 0 2px var(--ink-3)}
.cf-faces .cf-ava:first-child{margin-left:0}

/* ── rank medallion (CFGame.medal draws the SVG) ────────────────────────── */
.cf-medal{display:inline-block;flex:none;line-height:0;filter:drop-shadow(0 3px 6px rgb(var(--shade) / .55))}
.cf-medal svg{display:block;overflow:visible}
.cf-medal .cf-sheen{transform:translateX(-140%) skewX(-18deg);transform-box:fill-box}
@media (hover:hover){
  .cf-medal:hover .cf-sheen,.cf-medal-host:hover .cf-sheen{transform:translateX(260%) skewX(-18deg);transition:transform 900ms var(--ease-out)}
}
.cf-medal.is-shining .cf-sheen{transform:translateX(260%) skewX(-18deg);transition:transform 900ms var(--ease-out)}

/* ── segmented tabs with a sliding molten indicator ─────────────────────── */
.cf-tabs{position:relative;display:inline-flex;gap:2px;padding:4px;border-radius:var(--r-pill);background:var(--ink-2);border:1px solid var(--glass-edge);max-width:100%;overflow-x:auto;scrollbar-width:none}
.cf-tabs::-webkit-scrollbar{display:none}
.cf-tab{position:relative;z-index:1;min-height:36px;padding:0 14px;border:0;border-radius:var(--r-pill);background:transparent;color:var(--ink2);cursor:pointer;font:600 13px/1 var(--font-display);white-space:nowrap;transition:color var(--t-med)}
.cf-tab::before{content:'';position:absolute;inset:-4px 0}
.cf-tab[aria-selected="true"]{color:var(--on-molten)}
@media (hover:hover){.cf-tab:not([aria-selected="true"]):hover{color:var(--ink)}}
.cf-tabs-ind{position:absolute;z-index:0;top:4px;bottom:4px;left:0;width:0;border-radius:var(--r-pill);background:var(--molten);box-shadow:0 4px 14px rgb(var(--glow) / .35);transition:transform var(--t-med) var(--ease-spring),width var(--t-med) var(--ease-out)}

/* ── card ───────────────────────────────────────────────────────────────── */
.cf-card{
  position:relative;padding:var(--sp-4);border-radius:var(--r-lg);
  background:linear-gradient(180deg,rgb(var(--raise) / .9),rgb(var(--raise) / .92));
  border:1px solid var(--glass-edge);box-shadow:var(--shadow-2);
  transition:transform var(--t-med) var(--ease-out),border-color var(--t-med),box-shadow var(--t-med);
}
@media (hover:hover){.cf-card.is-lift:hover,a.cf-card:hover{transform:translateY(-2px);border-color:rgb(var(--glow) / .22);box-shadow:var(--shadow-3)}}
.cf-card.is-new{animation:cf-arrive 700ms var(--ease-out)}
@keyframes cf-arrive{0%{box-shadow:0 0 0 1px var(--ion),0 0 30px rgb(var(--ion-rgb) / .35)}100%{box-shadow:var(--shadow-2)}}
.cf-well{padding:12px;border-radius:var(--r-md);background:var(--well);border:1px solid rgb(var(--tint) / .04)}

/* ── empty state: an engraved vault door, gently turning ────────────────── */
.cf-noir-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:28px 16px;text-align:center;color:var(--ink3);font-size:13.5px}
.cf-noir-empty svg{width:54px;height:54px;opacity:.9}
.cf-noir-empty b{color:var(--ink2);font-weight:600}
.cf-empty-dial{transform-origin:32px 32px;animation:cf-dial 9s var(--ease-in-out) infinite alternate}
@keyframes cf-dial{from{transform:rotate(-30deg)}to{transform:rotate(60deg)}}

/* ── skeleton: shaped like what replaces it ─────────────────────────────── */
.cf-skel-noir,.cf-shimmer{position:relative;overflow:hidden;border-radius:var(--r-md);background:rgb(var(--tint) / .04);min-height:18px}
.cf-skel-noir::after,.cf-shimmer::after{content:'';position:absolute;inset:0;transform:translateX(-100%);background:linear-gradient(90deg,transparent,rgb(var(--tint) / .06),transparent);animation:cf-sweep 1.4s infinite}
@keyframes cf-sweep{to{transform:translateX(100%)}}

/* ── sheet: bottom sheet on a phone, drawer from 900px ──────────────────── */
.cf-scrim{position:fixed;inset:0;z-index:var(--z-sheet);background:rgb(var(--scrim-rgb) / .66);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);animation:cf-enter-fade var(--t-med) var(--ease-out)}
.cf-sheet{
  position:fixed;z-index:calc(var(--z-sheet) + 1);left:0;right:0;bottom:0;max-height:88vh;overflow:auto;overscroll-behavior:contain;
  padding:10px var(--sp-5) calc(var(--sp-6) + env(safe-area-inset-bottom,0px));border-radius:var(--r-xl) var(--r-xl) 0 0;
  background:linear-gradient(180deg,var(--sheet-hi),var(--sheet-lo));border:1px solid var(--glass-edge-hi);border-bottom:0;box-shadow:var(--shadow-3);
  color:var(--ink);animation:cf-sheet-up var(--t-slow) var(--ease-spring);touch-action:pan-y;
}
.cf-sheet.is-closing{animation:cf-sheet-down 240ms var(--ease-in-out) forwards}
@keyframes cf-sheet-up{from{transform:translateY(100%)}to{transform:none}}
@keyframes cf-sheet-down{to{transform:translateY(105%)}}
.cf-sheet-grab{width:44px;height:5px;margin:0 auto 14px;border-radius:3px;background:var(--ink-5)}
.cf-sheet h2{margin:0 0 4px;font:700 22px/1.2 var(--font-display);letter-spacing:-.02em}
.cf-sheet-sub{margin:0 0 var(--sp-4);color:var(--ink2);font-size:14px}
.cf-sheet-actions{display:flex;gap:10px;flex-wrap:wrap;margin-top:var(--sp-4)}
.cf-sheet-actions .cf-btn{flex:1 1 160px}
@media (min-width:900px){
  .cf-sheet{left:auto;top:0;width:440px;max-height:none;border-radius:var(--r-xl) 0 0 var(--r-xl);border-bottom:1px solid var(--glass-edge-hi);border-right:0;padding-top:var(--sp-6);animation-name:cf-drawer-in}
  .cf-sheet.is-closing{animation-name:cf-drawer-out}
  .cf-sheet-grab{display:none}
}
@keyframes cf-drawer-in{from{transform:translateX(100%)}to{transform:none}}
@keyframes cf-drawer-out{to{transform:translateX(105%)}}

/* ── overlay: a centred moment (rank-up) ────────────────────────────────── */
.cf-overlay{
  position:fixed;inset:0;z-index:var(--z-overlay);display:grid;place-items:center;padding:20px;
  background:radial-gradient(circle at 50% 45%,rgb(var(--glow) / .22),rgb(var(--scrim-rgb) / .82) 60%);
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);animation:cf-enter-fade 320ms var(--ease-out);
}
.cf-overlay.is-out{opacity:0;transition:opacity 240ms}
@keyframes cf-noir-pop{from{transform:scale(.7);opacity:0}to{transform:none;opacity:1}}

/* ── fields, inputs, presets, switch ────────────────────────────────────── */
.cf-field{display:grid;gap:6px;margin:12px 0}
.cf-field label,.cf-field>span{font:600 var(--fs-micro)/1 var(--font-mono);letter-spacing:var(--tr-caps);text-transform:uppercase;color:var(--ink3)}
.cf-presets{display:flex;gap:8px;flex-wrap:wrap}
.cf-input{
  min-height:var(--tap);padding:0 14px;border-radius:var(--r-md);background:var(--ink-2);border:1px solid var(--glass-edge-hi);
  color:var(--ink);font:500 16px/1 var(--font-mono);width:100%;box-sizing:border-box;
  transition:border-color var(--t-fast),box-shadow var(--t-fast);
}
.cf-input:focus-visible{outline:none;border-color:var(--gold-400);box-shadow:0 0 0 3px rgb(var(--glow) / .2)}
.cf-switch{position:relative;flex:none;width:52px;height:30px;padding:0;border-radius:15px;border:1px solid var(--glass-edge-hi);background:var(--ink-2);cursor:pointer;transition:background var(--t-med),border-color var(--t-med)}
.cf-switch::before{content:'';position:absolute;inset:-8px -4px}
.cf-switch i{position:absolute;top:3px;left:3px;width:22px;height:22px;border-radius:50%;background:var(--ink3);box-shadow:var(--shadow-1);transition:transform var(--t-med) var(--ease-spring),background var(--t-med)}
.cf-switch[aria-checked="true"]{background:rgb(var(--glow) / .25);border-color:rgb(var(--glow) / .6)}
.cf-switch[aria-checked="true"] i{transform:translateX(22px);background:var(--molten);box-shadow:0 0 12px rgb(var(--glow) / .6)}

/* ── table ──────────────────────────────────────────────────────────────── */
.cf-table-wrap{overflow-x:auto;max-width:100%}
.cf-table{width:100%;border-collapse:separate;border-spacing:0;font-size:13.5px}
.cf-table th{text-align:left;padding:0 10px 10px;font:600 10px/1 var(--font-mono);letter-spacing:.14em;text-transform:uppercase;color:var(--ink3);border-bottom:1px solid var(--glass-edge);white-space:nowrap}
.cf-table td{padding:12px 10px;border-bottom:1px solid rgb(var(--tint) / .05);vertical-align:middle}
.cf-table tbody tr{transition:background var(--t-fast)}
.cf-table tbody tr:hover{background:rgb(var(--tint) / .03)}
.cf-table .r{text-align:right;font-family:var(--font-mono);font-variant-numeric:tabular-nums}
.cf-cell-p{display:inline-flex;align-items:center;gap:8px;font-weight:600}

/* ── progress bar (curve, season, XP) ───────────────────────────────────── */
.cf-bar{position:relative;display:block;height:6px;border-radius:3px;background:rgb(var(--tint) / .06);overflow:hidden}
.cf-bar i{position:absolute;inset:0 auto 0 0;width:0;border-radius:inherit;background:var(--molten);box-shadow:0 0 10px rgb(var(--glow) / .5);transition:width 900ms var(--ease-out)}
.cf-bar.is-ion i{background:linear-gradient(90deg,rgb(var(--ion-rgb) / .3),var(--ion));box-shadow:var(--ion-glow)}

/* ── headings ───────────────────────────────────────────────────────────── */
.cf-eyebrow{display:inline-flex;align-items:center;gap:10px;font:600 var(--fs-micro)/1 var(--font-mono);letter-spacing:.22em;text-transform:uppercase;color:var(--accT)}
.cf-eyebrow::before{content:'';width:26px;height:1px;background:linear-gradient(90deg,transparent,var(--gold-400))}
.cf-h1{margin:0;font:var(--fw-h1) var(--fs-h1)/var(--lh-h1) var(--font-display);letter-spacing:var(--tr-h1)}
.cf-h2{margin:10px 0 8px;font:var(--fw-h2) var(--fs-h2)/var(--lh-h2) var(--font-display);letter-spacing:var(--tr-h2)}
.cf-lede{margin:0;max-width:60ch;color:var(--ink2);font-size:16px}

/* ── house-account badge (house_accounts.py): "House bot" / "Official" beside
   the name of a platform account, on every surface that shows a person. The
   payload decides (account_kind); static/cf-house.js draws it. ─────────── */
.cf-house{display:inline-flex;align-items:center;gap:4px;height:18px;max-width:max-content;padding:0 7px;border-radius:var(--r-full);
  font:700 9.5px/1 var(--font-mono);letter-spacing:.08em;text-transform:uppercase;white-space:nowrap;vertical-align:middle;
  color:var(--accent-text-strong);border:1px solid rgb(var(--glow) / .38);background:rgb(var(--glow) / .13);flex:none}
.cf-house svg{width:10px;height:10px;flex:none}
.cf-house--official{color:var(--on-molten);border-color:transparent;background:var(--molten)}
[data-theme="light"] .cf-house{color:var(--accT)}
.cf-house-note{margin:6px 0 0;font:500 13px/1.5 var(--font-ui);color:var(--ink2)}
.cf-house-note b{color:var(--ink);font-weight:700}
.cf-house-group{margin-top:14px;padding-top:10px;border-top:1px solid var(--glass-edge)}
.cf-house-group-h{display:flex;align-items:center;gap:8px;margin:0 0 6px;font:600 var(--fs-micro)/1 var(--font-mono);letter-spacing:.14em;text-transform:uppercase;color:var(--ink3)}

/* ── reduced motion: the finished state ─────────────────────────────────── */
@media (prefers-reduced-motion:reduce){
  .cf-live::before,.cf-skel-noir::after,.cf-shimmer::after,.cf-empty-dial{animation:none}
  .cf-btn,.cf-card,.cf-tabs-ind,.cf-bar i,.cf-switch,.cf-switch i,.cf-molten,.cf-pressing{transition:none}
  .cf-btn::after{display:none}
  .cf-ripple{display:none}
  .cf-btn{transform:none}
  .cf-sheet,.cf-scrim,.cf-overlay,.cf-card.is-new{animation:none}
  .cf-molten:hover{background-position:100% 0,0 0!important}
}

/* ── brand marks: a chain's or launchpad's real logo BESIDE its name ─────── */
/* (owner, 2026-10-13; brand_logos.py + cf-brand.js). Fixed box, so nothing
   shifts while it loads; the dot above stays only where no mark exists. A
   project that publishes its mark only as mono white / mono black ships both
   files: --dark is drawn on the dark theme, --light on the light one. */
.cf-logo{flex:none;display:inline-block;width:14px;height:14px;object-fit:contain;vertical-align:-2px;border-radius:3px;background:transparent}
.cf-chip .cf-logo{width:12px;height:12px;margin-left:-2px;vertical-align:-1px}
.cf-logo--lg{width:20px;height:20px;border-radius:5px}
.cf-logo--light{display:none}
.cf-logo-slot{display:none}   /* a dot-less placeholder cf-brand.js fills once the registry answers */
[data-theme="light"] .cf-logo--dark{display:none}
[data-theme="light"] .cf-logo--light{display:inline-block}
/* The Mini App outside Telegram follows a light OS theme with body.cf-light and no
   data-theme attribute: the light-theme mark must follow it there too. */
.cf-light .cf-logo--dark{display:none}
.cf-light .cf-logo--light{display:inline-block}
/* A pale mark (HyperEVM mint) vanishes on the light ground: it sits on a neutral dark plate from the tokens. */
[data-theme="light"] .cf-logo[src*="/chains/hyperevm"]{background:var(--ink-0);padding:1px;border-radius:50%}
[aria-disabled="true"] .cf-logo,[disabled] .cf-logo{opacity:.7}

/* ── Alive: XP chip, streak flame, season strip, success check (2026-10-14) ─
 * Fed by cf-toast.js's pulse. The resting state is the finished one; every
 * motion runs on a CHANGE only and not under prefers-reduced-motion. */
.cf-xpchip-wrap{position:relative;flex:none;margin-left:8px}
.cf-xpchip{position:relative;display:inline-flex;align-items:center;gap:6px;min-height:36px;padding:0 12px;border-radius:var(--r-pill,999px);
  border:1px solid var(--glass-edge-hi);background:var(--glass-bg,rgb(var(--sheen-rgb) / .06));color:var(--ink);font:600 12px/1 var(--font-mono);cursor:pointer}
.cf-xpchip b{font-weight:700}
.cf-xpchip small{color:var(--ink3);font-size:10px;letter-spacing:.08em}
.cf-xpchip:hover{border-color:var(--gold-300)}
.cf-xpchip:focus-visible{outline:2px solid var(--gold-300);outline-offset:2px}
.cf-xpchip-sep{width:1px;height:14px;background:var(--glass-edge-hi)}
.cf-flame{display:inline-grid;place-items:center;width:16px;height:16px;color:var(--ink3)}
.cf-flame svg{width:16px;height:16px}
.cf-flame.on{color:var(--gold-300);filter:drop-shadow(0 0 6px rgb(var(--glow) / .6))}
.cf-flame.risk{color:var(--ember,var(--gold-300))}
.cf-xpchip-pop{position:absolute;right:6px;top:-4px;pointer-events:none;color:var(--gold-200,var(--gold-300));font:700 12px/1 var(--font-mono)}
.cf-xpchip-pop.go{animation:cf-xp-pop .9s var(--ease-out) forwards}
.cf-xpchip.bump{animation:cf-xp-bump .5s var(--ease-spring)}
@keyframes cf-xp-pop{0%{opacity:0;transform:translateY(6px) scale(.8)}20%{opacity:1}100%{opacity:0;transform:translateY(-20px) scale(1.1)}}
@keyframes cf-xp-bump{0%{transform:scale(1)}40%{transform:scale(1.08)}100%{transform:scale(1)}}
.cf-xpp{position:absolute;right:0;top:calc(100% + 8px);z-index:var(--z-pop,9400);width:min(300px,calc(100vw - 32px));padding:14px;border-radius:var(--r-lg,16px);
  border:1px solid var(--glass-edge-hi);background:linear-gradient(180deg,var(--sheet-hi),var(--sheet-lo));box-shadow:var(--shadow-3);color:var(--ink)}
.cf-xpp[hidden]{display:none}
.cf-xpp-rank{display:flex;align-items:center;gap:10px}
.cf-xpp-rank b{display:block;font:700 16px/1.1 var(--font-display)}
.cf-xpp-rank small{color:var(--ink3);font:600 11px var(--font-mono)}
.cf-xpbar{height:8px;border-radius:99px;background:rgb(var(--sheen-rgb) / .1);overflow:hidden;margin:12px 0 6px}
.cf-xpbar i{display:block;height:100%;border-radius:99px;background:var(--molten-text,var(--gold-300));transition:width .7s var(--ease-out)}
.cf-xpbar i.glint{animation:cf-xp-glint .9s var(--ease-out)}
@keyframes cf-xp-glint{0%{filter:brightness(1.9)}100%{filter:none}}
.cf-xpp-next,.cf-xpp-season{margin:0 0 10px;font:500 12px/1.4 var(--font-body);color:var(--ink2)}
.cf-xpp-season{margin:8px 0 0}
.cf-xpp-streak{display:flex;align-items:center;gap:10px;padding-top:10px;border-top:1px solid var(--glass-edge-hi)}
.cf-xpp-streak b{display:block;font:700 13px var(--font-display)}
.cf-xpp-streak small{display:block;color:var(--ink3);font:500 11px/1.3 var(--font-body)}
.cf-xpp-streak .cf-flame{width:22px;height:22px}.cf-xpp-streak .cf-flame svg{width:22px;height:22px}
.cf-xpp-week{margin-left:auto;display:flex;gap:3px}
.cf-xpp-week i{width:7px;height:7px;border-radius:50%;background:rgb(var(--sheen-rgb) / .16)}
.cf-xpp-week i.on{background:var(--gold-300)}
.cf-xpp-week i.today{outline:1px solid var(--gold-300);outline-offset:1px}
@media (max-width:1024px){.cf-xpchip{min-height:44px}}
@media (max-width:640px){.cf-xpchip{padding:0 9px}.cf-xpchip small{display:none}}
/* the season strip on the feed */
.cf-race{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:10px 14px;border-radius:var(--r-lg,16px);border:1px solid var(--glass-edge-hi);
  background:var(--glass-bg,rgb(var(--sheen-rgb) / .05));font:500 13px var(--font-body);color:var(--ink2)}
.cf-race[hidden]{display:none}
.cf-race-k{font:600 var(--fs-micro,10px) var(--font-mono);letter-spacing:var(--tr-caps,.1em);text-transform:uppercase;color:var(--ink3)}
.cf-race-pos{font:700 20px/1 var(--font-display);color:var(--ink)}
.cf-race-track{flex:1 1 80px;min-width:80px;height:6px;border-radius:99px;background:rgb(var(--sheen-rgb) / .1);overflow:hidden}
.cf-race-track i{display:block;height:100%;background:var(--molten-text,var(--gold-300));border-radius:99px;transition:width .8s var(--ease-out)}
.cf-race-pts{font:600 12px var(--font-mono);color:var(--ink)}
.cf-race-link{color:var(--gold-300);font:600 12px var(--font-mono);text-decoration:none}
.cf-race.moved .cf-race-pos{animation:cf-xp-bump .7s var(--ease-spring);color:var(--gold-200,var(--gold-300))}
/* success check drawn on a confirmed trade / copy (sheets add .cf-check) */
.cf-check{display:inline-block;width:56px;height:56px;color:var(--ok,var(--gold-300))}
.cf-check circle,.cf-check path{fill:none;stroke:currentColor;stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}
.cf-check circle{stroke-dasharray:151;stroke-dashoffset:0}
.cf-check path{stroke-dasharray:40;stroke-dashoffset:0}
.cf-check.draw circle{animation:cf-draw .55s var(--ease-out) both}
.cf-check.draw path{animation:cf-draw .4s var(--ease-out) .35s both}
@keyframes cf-draw{from{stroke-dashoffset:151}to{stroke-dashoffset:0}}
/* staggered arrival: the class is added from script and removed on end */
.cf-arrive{animation:cf-arrive .5s var(--ease-out) both;animation-delay:calc(var(--i,0) * 55ms)}
@keyframes cf-arrive{from{transform:translateY(10px)}to{transform:none}}
@media (prefers-reduced-motion:reduce){
  .cf-xpchip-pop.go,.cf-xpchip.bump,.cf-xpbar i.glint,.cf-race.moved .cf-race-pos,.cf-check.draw circle,.cf-check.draw path,.cf-arrive{animation:none}
  .cf-xpbar i,.cf-race-track i{transition:none}
}


/* ---- static/cf-charts.css ---- */
/* Cartel Family — shared chart primitives (see cf-charts.js), dressed in
   Syndicate Noir (COMPONENTS.md §16): every line carries a two-step glow
   trail in its own colour, the end point is a 9px dot ringed in the ground
   with the shared pulse, the readouts are glass with a gold edge. Tokens
   only; the line colour itself comes from cf-charts.js (read off <body>). */

/* the glow trail: the path's `color` is its stroke (set by cf-charts.js) */
.cf-line{filter:drop-shadow(0 0 4px color-mix(in srgb,currentColor 55%,transparent)) drop-shadow(0 0 12px color-mix(in srgb,currentColor 35%,transparent))}
.cf-line--spark{filter:drop-shadow(0 0 3px color-mix(in srgb,currentColor 50%,transparent))}

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

/* The tooltip is an HTML element rather than SVG text: it needs to stay
   upright and legibly sized while the SVG itself is stretched by
   preserveAspectRatio:none, which would distort any text drawn inside it. */
.cf-chart-tip{
  /* The design's readout: 132px wide, value over clock time, centred. */
  position:absolute;top:-6px;transform:translateX(-50%);box-sizing:border-box;
  width:132px;text-align:center;
  pointer-events:none;opacity:0;transition:opacity var(--t-fast,.13s);
  background:var(--glass-strong);border:1px solid rgb(var(--glow) / .3);border-radius:var(--r-sm);
  padding:6px 9px;white-space:nowrap;z-index:5;
  box-shadow:var(--shadow-3);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
}
.cf-chart-tip.on{opacity:1}
.cf-chart-tip b{
  display:block;color:var(--ink);font:500 12px/1.3 var(--font-num);
  font-variant-numeric:tabular-nums;overflow:hidden;text-overflow:ellipsis;
}
.cf-chart-tip i{display:block;color:var(--ink2);font:500 10px/1.3 var(--font-num);font-style:normal;margin-top:1px}

.cf-chart-end{position:absolute;width:7px;height:7px;border-radius:50%;
  transform:translate(-50%,-50%);pointer-events:none;z-index:2;
  box-shadow:0 0 0 3px rgb(var(--ground-rgb) / .85),0 0 14px currentColor;width:9px;height:9px}
/* The live pulse (cf-charts.js addPulse): a ring the size of the dot, grown
   and faded by ONE requestAnimationFrame loop for the page -- transform and
   opacity only. At rest it is invisible decoration; the dot is the mark. */
.cf-pulse-ring{position:absolute;inset:0;border-radius:50%;opacity:0;
  pointer-events:none;will-change:transform,opacity;transform-origin:50% 50%}
.cf-spark-end{position:absolute;width:5px;height:5px;border-radius:50%;
  transform:translate(-50%,-50%);pointer-events:none;z-index:2}
/* The latest value on the right edge (opts.lastLabel); slides with the line. */
.cf-chart-last{position:absolute;right:0;transform:translateY(-50%);z-index:3;
  font:600 11px/1.3 var(--font-num);color:var(--onAcc);
  padding:2px 6px;border-radius:6px;white-space:nowrap;pointer-events:none;
  font-variant-numeric:tabular-nums}
/* A redraw with a new series cross-fades: the old drawing on top, fading. */
.cf-chart-ghost{position:absolute;inset:0;pointer-events:none;z-index:1}

/* Label of the dashed gold entry line (CFCharts.area opts entry + entryLabel). */
.cf-chart-entry{
  position:absolute;left:8px;transform:translateY(-100%);margin-top:-4px;
  font:600 11px/1.3 var(--font-num);color:var(--onAcc);background:var(--acc);
  padding:2px 6px;border-radius:6px;white-space:nowrap;pointer-events:none;
}

/* Candles: OHLC readout top-left; the price under the pointer shown as
   gold pill on the right edge. */
.cf-ohlc{
  position:absolute;left:8px;top:8px;display:flex;gap:12px;flex-wrap:wrap;
  font:500 12px/1.3 var(--font-num);color:var(--ink2);background:var(--glass-strong);
  border:1px solid rgb(var(--glow) / .3);border-radius:var(--r-sm);padding:6px 10px;
  -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
  pointer-events:none;opacity:0;transition:opacity .13s;z-index:4;max-width:calc(100% - 16px);
}
.cf-ohlc.on{opacity:1}
.cf-ohlc b{font-weight:500}
.cf-ohlc b.up{color:var(--up)}
.cf-ohlc b.down{color:var(--dn)}
.cf-chart-pricepill{
  position:absolute;right:0;transform:translateY(-50%);
  font:600 11px/1.3 var(--font-num);color:var(--onAcc);background:var(--acc);
  padding:3px 6px;border-radius:6px;pointer-events:none;opacity:0;z-index:4;
}
.cf-chart-pricepill.on{opacity:1}
.cf-candles{cursor:crosshair;touch-action:pan-y;user-select:none}

.cf-chart-empty{
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:7px;min-height:120px;height:100%;color:var(--muted);
  font-size:12px;text-align:center;padding:18px 12px;
}
.cf-chart-empty svg{opacity:.5}

.cf-spark{display:block;width:100%;line-height:0}
/* The spark readout sits above the line so a finger does not cover it. */
.cf-spark{position:relative}
.cf-spark-tip{top:auto;bottom:calc(100% + 4px);padding:3px 7px;width:auto;min-width:0}
.cf-spark-tip b{font-size:11.5px}
.cf-spark-svg{display:block;width:100%;height:100%}

/* donut */
.cf-donut{display:flex;flex-direction:column;align-items:center;gap:12px}
.cf-donut-svg{display:block;width:168px;height:168px;max-width:100%}
.cf-donut-center{
  position:absolute;top:0;left:50%;transform:translateX(-50%);
  width:168px;height:168px;display:flex;flex-direction:column;
  align-items:center;justify-content:center;pointer-events:none;
}
.cf-donut-center b{
  color:var(--text);font-size:17px;font-weight:600;letter-spacing:-.02em;
  font-family:var(--font-mono);
}
.cf-donut-center i{color:var(--muted);font-size:10px;font-style:normal;
  text-transform:uppercase;letter-spacing:.12em;margin-top:2px}
.cf-donut-legend{display:flex;flex-wrap:wrap;gap:8px 14px;justify-content:center;width:100%}
.cf-dl-item{display:inline-flex;align-items:center;gap:6px;font-size:11px;color:var(--muted)}
.cf-dl-item i{width:8px;height:8px;border-radius:2px;flex:0 0 8px}
.cf-dl-item b{color:var(--text);font-weight:700;
  font-family:var(--font-mono)}

/* A card wrapper pages can reuse so charts sit consistently. */
.cf-chart-card{
  position:relative;border-radius:var(--r-lg);padding:16px 18px 14px;
  background:linear-gradient(180deg,rgb(var(--raise) / .66),rgb(var(--raise) / .72) 38%,var(--glass));
  border:1px solid var(--glass-edge);box-shadow:var(--shadow-2);
}
.cf-chart-head{display:flex;align-items:baseline;justify-content:space-between;
  gap:10px;margin-bottom:12px;flex-wrap:wrap}
.cf-chart-title{font:600 var(--fs-micro,11px)/1.2 var(--font-mono);letter-spacing:var(--tr-caps,.16em);
  text-transform:uppercase;color:var(--muted)}
.cf-chart-value{font-size:20px;font-weight:600;color:var(--text);letter-spacing:-.02em;
  font-family:var(--font-mono);font-variant-numeric:tabular-nums}
.cf-chart-delta{font-size:11.5px;font-weight:600;font-family:var(--font-mono)}
.cf-chart-delta.up{color:var(--green)}
.cf-chart-delta.down{color:var(--red)}
.cf-chart-delta.flat{color:var(--muted)}

@media (prefers-reduced-motion:reduce){
  .cf-chart-tip,.cf-ohlc{transition:none}
  .cf-pulse-ring,.cf-chart-ghost{display:none}
  .cf-line,.cf-line--spark{filter:none}
}
/* bars(): the optional label row under the slots (opts.ticks). */
.cf-chart-axis{position:relative;height:16px;margin-top:2px}
.cf-chart-axis span{position:absolute;top:0;transform:translateX(-50%);font:500 10px var(--font-num);color:var(--ink3);white-space:nowrap}

/* Keyboard readout (opts.keyboard; always on for heatmap and histogram):
   the chart is focusable and shows a visible focus ring. */
.cf-chart-kb{outline:none;border-radius:8px}
.cf-chart-kb:focus-visible{box-shadow:var(--focus-ring,0 0 0 2px var(--bg),0 0 0 4px var(--accT))}

/* donut(): a hovered / focused legend row (opts.hover). */
.cf-dl-item[tabindex]{cursor:pointer;border-radius:6px;padding:2px 4px;margin:-2px -4px}
.cf-dl-item.on{color:var(--text)}
.cf-dl-item[tabindex]:focus-visible{outline:2px solid var(--accT);outline-offset:1px}

/* heatmap(): squares keep their shape; a long range scrolls in its own box. */
.cf-heat{display:flex;flex-direction:column;gap:8px}
.cf-heat-scroll{overflow-x:auto;overflow-y:hidden;scrollbar-width:thin;padding-top:2px}
.cf-heat-svg{display:block;height:auto}
/* SVG text never wraps; it only must not inherit a nowrap meant for HTML text. */
.cf-heat-svg text{white-space:normal;user-select:none}
.cf-heat-legend{display:flex;align-items:center;gap:3px;justify-content:flex-end;
  font:500 10px var(--font-num);color:var(--ink3)}
.cf-heat-legend span{margin:0 4px}
.cf-heat-legend i{width:10px;height:10px;border-radius:2px;display:inline-block}
.cf-heat-tip{transform:translate(-50%,calc(-100% - 8px));width:auto;min-width:132px;max-width:220px}

/* histogram(): the marker's label rides above the plot. */
.cf-hist{height:100%}
.cf-hist-marker{position:absolute;top:0;transform:translateX(-50%);pointer-events:none;
  font:600 10px/1.3 var(--font-num);color:var(--onAcc);background:var(--acc);
  padding:1px 6px;border-radius:5px;white-space:nowrap}
.cf-hist-axis{height:18px;margin-top:0}


/* ── CFPriceChart (cf-price-chart.js): price pane, volume pane, readout ── */
.cf-pc{position:relative}
.cf-pc-wrap{position:relative;border-radius:12px;overflow:hidden;background:var(--s1)}
.cf-pc{outline:none;border-radius:12px}
.cf-pc:focus-visible{box-shadow:0 0 0 2px var(--bg),0 0 0 4px var(--accT)}
/* Candle mode's live dot: placed by transform on the library's coordinates. */
.cf-pc-dot{position:absolute;left:0;top:0;width:9px;height:9px;border-radius:50%;
  pointer-events:none;z-index:3;box-shadow:0 0 0 3px rgb(var(--ground-rgb) / .85),0 0 14px rgb(var(--glow) / .6)}
.cf-pc-price,.cf-pc-vol{position:relative;width:100%}
.cf-pc-vol{border-top:1px solid var(--line)}
.cf-pc-empty{display:flex;align-items:center;justify-content:center;height:100%;min-height:220px;
  color:var(--ink3);font:500 13px/1.4 var(--font-body);text-align:center;padding:0 16px}
.cf-pc-tip{position:absolute;top:10px;left:12px;z-index:4;pointer-events:none;opacity:0;transform:translateY(-4px);
  transition:opacity var(--t-fast,.14s),transform var(--t-fast,.14s);background:var(--glass-strong);border:1px solid rgb(var(--glow) / .3);border-radius:var(--r-sm);
  padding:7px 10px;box-shadow:var(--shadow-3);max-width:min(92%,420px);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px)}
.cf-pc-tip.on{opacity:1;transform:none}
.cf-pc-tip.right{left:auto;right:64px}
.cf-pc-tip i{display:block;font:500 10px/1.3 var(--font-num);color:var(--ink3);font-style:normal;letter-spacing:.02em}
.cf-pc-tip b{display:flex;flex-wrap:wrap;gap:4px 10px;font:600 12px/1.4 var(--font-num);color:var(--ink);
  font-variant-numeric:tabular-nums;margin-top:2px}
.cf-pc-tip em{display:inline-block;margin-top:2px;font:600 11px/1.3 var(--font-num);font-style:normal}
.cf-pc-tip em.up{color:var(--up)} .cf-pc-tip em.dn{color:var(--dn)}
.cf-pc-tip small{display:block;margin-top:2px;font:500 10px/1.3 var(--font-num);color:var(--ink2)}
/* Entrance: a left-to-right reveal on first paint, a crossfade on a rebuild.
   Both are added from script and removed on animationend; the resting state
   is fully visible, so a paused tab never leaves a chart hidden. */
.cf-pc-reveal{animation:cfPcReveal var(--t-draw,.7s) var(--ease-out) both}
@keyframes cfPcReveal{from{clip-path:inset(0 100% 0 0);opacity:.6}to{clip-path:inset(0 0 0 0);opacity:1}}
.cf-pc-swap{animation:cfPcSwap var(--t-med,.28s) var(--ease-out) both}
@keyframes cfPcSwap{from{opacity:.25;transform:translateY(4px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){.cf-pc-reveal,.cf-pc-swap{animation:none}.cf-pc-tip{transition:none}}


/* ---- static/dev-portal.css ---- */
/* Developer portal -- Syndicate Noir. Every colour is a cf-theme.css token;
 * components are cf-noir.css's (cf-glass, cf-btn, cf-chip, cf-table, cf-tabs,
 * cf-input, cf-noir-empty); this file lays the portal out: a glass top bar,
 * a docs rail from 1024px, one column below, 320-2560, both themes.
 * Reduced motion: no entrances, no count-ups, everything at its final state. */
.dvp *, .dvp *::before, .dvp *::after { box-sizing: border-box; }
.dvp { margin: 0; overflow-x: hidden; background: var(--ink-1); color: var(--text-1); font: 400 var(--fs-body)/1.55 var(--font-body); -webkit-font-smoothing: antialiased; }
.dvp a { color: var(--accent-text); text-decoration: none; }
.dvp a:hover { text-decoration: underline; }
.dvp code, .dvp pre, .dvp kbd { font-family: var(--font-mono); }
.dvp code { font-size: .9em; overflow-wrap: anywhere; background: rgb(var(--tint) / .07); border: 1px solid var(--glass-edge); border-radius: var(--r-xs); padding: 1px 6px; color: var(--text-1); }
.dvp pre code { background: none; border: 0; padding: 0; font-size: 12.5px; }
.dvp-skip { position: absolute; left: -9999px; top: 8px; z-index: 100; display: inline-flex; align-items: center; min-height: 44px; padding: 0 16px; background: var(--molten); color: var(--on-molten); border-radius: var(--r-sm); font: 600 14px var(--font-display); box-shadow: var(--glow-gold); }
.dvp-skip:focus { left: 8px; text-decoration: none; outline: 2px solid var(--ion); outline-offset: 2px; }
/* `.dvp a` (0,1,1) outranks `.cf-btn` (0,1,0) and `.cf-btn--primary`: without
   these, a link drawn as a button took the gold link colour, and on the molten
   fill a gold label is gold on gold -- it read as "washed out" the moment the
   light sweep passed under it. The label is the component's own: ink on a
   plain button, --on-molten on the molten one, never underlined. */
.dvp a.cf-btn { color: var(--ink); }
.dvp a.cf-btn--primary { color: var(--on-molten); }
.dvp a.cf-btn:hover { text-decoration: none; }

/* ── top bar ── */
.dvp-top { position: sticky; top: 0; z-index: var(--z-bar); display: flex; align-items: center; gap: var(--sp-4); height: 64px; padding: 0 var(--gutter, 16px); border-radius: 0; border-left: 0; border-right: 0; border-top: 0; }
/* The glass panel's molten edge is drawn 1px outside its box; on a full-width
   header that 1px was a sideways scroll on every page. */
.dvp-top::before { left: 0; right: 0; }
.dvp-brand { display: inline-flex; align-items: center; gap: 10px; color: var(--text-1); flex: 0 0 auto; }
.dvp-brand:hover { text-decoration: none; }
.dvp-tile { width: 36px; height: 36px; border-radius: 10px; overflow: hidden; background: var(--ink-3); box-shadow: var(--shadow-1); display: grid; place-items: center; }
.dvp-tile img { width: 36px; height: 36px; display: block; transform: scale(1.18); }
.dvp-word { display: flex; flex-direction: column; line-height: 1; font-family: var(--font-display); }
.dvp-word b { font-size: 13px; letter-spacing: .08em; }
.dvp-word i { font-style: normal; font-size: 10px; letter-spacing: .14em; color: var(--accent-text); font-weight: 700; margin-top: 3px; }
.dvp-search { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 8px; max-width: 520px; height: 40px; padding: 0 12px; border-radius: var(--r-pill); background: rgb(var(--tint) / .06); border: 1px solid var(--glass-edge); color: var(--text-3); }
.dvp-search:focus-within { border-color: rgb(var(--glow) / .5); box-shadow: 0 0 0 3px rgb(var(--glow) / .14); }
.dvp-search input { flex: 1; min-width: 0; background: none; border: 0; outline: 0; color: var(--text-1); font: 500 14px var(--font-body); }
.dvp-search kbd { font-size: 11px; border: 1px solid var(--glass-edge-hi); border-radius: 5px; padding: 1px 6px; color: var(--text-3); }
.dvp-top-acts { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.cf-theme-toggle .dvp-sun, .cf-theme-toggle .dvp-moon { display: none; }
:root:not([data-theme="light"]) .cf-theme-toggle .dvp-sun { display: block; }
:root[data-theme="light"] .cf-theme-toggle .dvp-moon { display: block; }
.dvp-icon { width: 40px; height: 40px; border-radius: 50%; border: 1px solid var(--glass-edge); background: rgb(var(--tint) / .05); color: var(--text-1); display: inline-grid; place-items: center; cursor: pointer; }

/* ── shell ── */
.dvp-shell { display: grid; grid-template-columns: minmax(0, 1fr); max-width: var(--maxw); margin: 0 auto; width: 100%; }
.dvp-nav { position: sticky; top: 64px; z-index: 5; min-width: 0; max-width: 100%; background: rgb(var(--ground-rgb) / .92); backdrop-filter: blur(10px); border-bottom: 1px solid var(--glass-edge); }
.dvp-nav-in { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; padding: 10px var(--gutter, 16px); }
.dvp-nav-in::-webkit-scrollbar { display: none; }
.dvp-nav-h { display: none; }
.dvp-nav-a { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 9px; min-height: 36px; padding: 0 12px; border-radius: var(--r-pill); color: var(--text-2); font: 600 13px var(--font-display); border: 1px solid transparent; white-space: nowrap; }
.dvp-nav-a:hover { text-decoration: none; background: rgb(var(--tint) / .05); }
.dvp-nav-a.is-active { color: var(--on-molten); background: var(--molten); box-shadow: var(--glow-gold); }
.dvp-nav-a[hidden] { display: none; }
.dvp-nav-i { flex: none; opacity: .78; }
.dvp-nav-a:hover .dvp-nav-i, .dvp-nav-a.is-active .dvp-nav-i { opacity: 1; }
.dvp-main { min-width: 0; padding: var(--sp-6) var(--gutter, 16px) var(--sp-12); }
.dvp-article { display: grid; gap: var(--sp-5); }
.dvp-article > * { min-width: 0; }
.dvp-foot { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-top: var(--sp-10); padding-top: var(--sp-5); border-top: 1px solid var(--glass-edge); color: var(--text-3); font-size: var(--fs-small); }

@media (min-width: 1024px) {
  .dvp-shell { grid-template-columns: 240px minmax(0, 1fr); gap: var(--sp-8); padding: 0 var(--gutter, 24px); }
  .dvp-nav { position: sticky; top: 64px; align-self: start; height: calc(100vh - 64px); overflow: auto; background: none; backdrop-filter: none; border-bottom: 0; border-right: 1px solid var(--glass-edge); }
  .dvp-nav-in { flex-direction: column; gap: 2px; overflow: visible; padding: var(--sp-6) var(--sp-4) var(--sp-6) 0; }
  .dvp-nav-h { display: block; margin: var(--sp-4) 0 var(--sp-2) 12px; }
  .dvp-nav-h:first-child { margin-top: 0; }
  .dvp-nav-a { min-height: 40px; border-radius: var(--r-sm); white-space: normal; }
  .dvp-nav-a.is-active { background: linear-gradient(90deg, rgb(var(--glow) / .18), transparent); color: var(--accent-text-strong); box-shadow: inset 3px 0 0 var(--molten); }
  .dvp-main { padding: var(--sp-8) 0 var(--sp-12); }
}

/* ── type blocks ── */
.dvp-head, .dvp-hero { display: grid; gap: var(--sp-3); }
.dvp-hero { padding: var(--sp-6) 0 var(--sp-2); }
.dvp .cf-h1 { margin: 0; font: var(--fw-h1, 700) clamp(28px, 4.5vw, var(--fs-h1, 40px)) / 1.1 var(--font-display); letter-spacing: var(--tr-h1, -.02em); }
.dvp .cf-h2 { margin: 0 0 var(--sp-3); font: 600 var(--fs-h2, 22px) / 1.2 var(--font-display); letter-spacing: var(--tr-h2, -.01em); }
.dvp .cf-lede { margin: 0; color: var(--text-2); font-size: clamp(15px, 1.6vw, 17px); max-width: 68ch; }
.dvp-p { margin: 0 0 var(--sp-3); color: var(--text-2); max-width: 78ch; }
.dvp-p:last-child { margin-bottom: 0; }
.dvp-muted { color: var(--text-3); font-size: var(--fs-small); }
.dvp-sub { color: var(--text-3); font-size: var(--fs-small); }
.dvp-ul, .dvp-ol { margin: 0; padding-left: 1.2em; color: var(--text-2); display: grid; gap: 8px; }
.dvp-ol li b, .dvp-ul li b { color: var(--text-1); }
.dvp-hero-cta { display: flex; gap: 10px; flex-wrap: wrap; margin-top: var(--sp-2); }
.dvp-pre { margin: 0; padding: 14px 16px; border-radius: var(--r-md); background: var(--ink-2); border: 1px solid var(--glass-edge); overflow-x: auto; color: var(--text-1); font-size: 12.5px; line-height: 1.6; }
.dvp-wrap { word-break: break-all; }
.dvp-num { display: inline-grid; place-items: center; width: 28px; height: 28px; border-radius: 50%; background: var(--molten); color: var(--on-molten); font: 700 13px var(--font-mono); margin-right: 10px; vertical-align: middle; }
.dvp-step { display: grid; gap: var(--sp-3); }

/* ── grids and cards ── */
.dvp-grid3 { display: grid; gap: var(--sp-4); grid-template-columns: 1fr; }
.dvp-grid2 { display: grid; gap: var(--sp-4); grid-template-columns: 1fr; }
@media (min-width: 640px) { .dvp-grid3, .dvp-grid2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1200px) { .dvp-grid3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } .dvp-grid2 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.dvp-stat { display: grid; gap: 6px; align-content: start; }
.dvp-fig { font: 600 var(--fs-figure-xl, 30px) / 1 var(--font-mono); color: var(--accent-text-strong); letter-spacing: -.02em; }
.dvp-card { display: grid; gap: 6px; color: var(--text-1); transition: transform var(--t-fast) var(--ease-out), border-color var(--t-fast); }
.dvp-card:hover { text-decoration: none; transform: translateY(-2px); border-color: rgb(var(--glow) / .45); }
.dvp-card b { font-family: var(--font-display); font-size: 16px; }
.dvp .cf-panel-h h2 { margin: 0; }
.dvp-fee-grid { display: grid; gap: var(--sp-4); grid-template-columns: 1fr; margin-bottom: var(--sp-4); }
@media (min-width: 640px) { .dvp-fee-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

/* ── live panel ── */
.dvp-live-grid { display: grid; gap: var(--sp-4); grid-template-columns: 1fr; }
@media (min-width: 900px) { .dvp-live-grid { grid-template-columns: 300px minmax(0, 1fr); } }
.dvp-live-kpis { display: grid; gap: 10px; grid-template-columns: repeat(2, minmax(0, 1fr)); align-content: start; }
.dvp-kpi { padding: 12px; border-radius: var(--r-md); background: rgb(var(--tint) / .04); border: 1px solid var(--glass-edge); display: grid; gap: 4px; }
.dvp-kpi .cf-eyebrow { font-size: 10px; }
.dvp-kpi b { font: 600 20px / 1 var(--font-mono); color: var(--text-1); }
.dvp-chart { position: relative; height: var(--ch, 160px); }
.dvp-empty-sm { padding: var(--sp-4); color: var(--text-3); font-size: var(--fs-small); text-align: center; border: 1px dashed var(--glass-edge); border-radius: var(--r-md); }

/* ── tables ── */
.dvp-table { width: 100%; border-collapse: collapse; }
.dvp-table th { text-align: left; font: 600 10px / 1 var(--font-mono); letter-spacing: var(--tr-caps); text-transform: uppercase; color: var(--text-3); padding: 8px 10px; border-bottom: 1px solid var(--glass-edge); }
.dvp-table td { padding: 10px; border-bottom: 1px solid rgb(var(--tint) / .05); vertical-align: top; color: var(--text-2); }
.dvp-table tr:last-child td { border-bottom: 0; }
.dvp-table-wrap { overflow-x: auto; max-width: 100%; }
.dvp-ep > *, .dvp-try-form > *, .cf-panel > * { min-width: 0; max-width: 100%; }
.dvp-swatch { display: inline-block; width: 14px; height: 14px; border-radius: 4px; vertical-align: -2px; margin-left: 6px; border: 1px solid var(--glass-edge-hi); }
.dvp-copy-inline { background: none; border: 0; color: var(--accent-text); font: 600 11px var(--font-mono); cursor: pointer; padding: 2px 4px; }

/* ── API reference ── */
.dvp-api-tools-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: var(--sp-3); }
.dvp-section-chips { display: flex; gap: 8px; flex-wrap: wrap; }
.dvp-section-chips .cf-chip { min-height: 32px; gap: 6px; }
.dvp-section-chips .cf-chip .cf-nav-i { opacity: .8; }
.dvp-section-chips .cf-chip i { display: none; }
.dvp-api-section { display: grid; gap: var(--sp-4); }
.dvp-ep { padding: var(--sp-5); display: grid; gap: var(--sp-3); scroll-margin-top: 130px; }
.dvp-ep[hidden] { display: none; }
.dvp-ep-h { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.dvp-method { font: 700 11px / 1 var(--font-mono); letter-spacing: .08em; color: var(--up); background: var(--up-dim); border: 1px solid rgb(var(--up-rgb) / .3); border-radius: var(--r-xs); padding: 5px 7px; }
.dvp-path { font-size: 14px; background: none; border: 0; padding: 0; color: var(--text-1); word-break: break-all; }
.dvp-anchor { margin-left: auto; color: var(--text-4); font-family: var(--font-mono); }
.dvp-ep-meta { display: flex; gap: 8px; flex-wrap: wrap; }
.dvp-params { font-size: 13px; }
.dvp-params td:last-child { min-width: 140px; }
.dvp-params .cf-input, .dvp-param { width: 100%; min-width: 120px; height: 36px; border-radius: var(--r-sm); border: 1px solid var(--glass-edge-hi); background: var(--ink-2); color: var(--text-1); padding: 0 10px; font: 500 13px var(--font-mono); }
.dvp-param:focus { outline: 0; border-color: rgb(var(--glow) / .6); box-shadow: 0 0 0 3px rgb(var(--glow) / .14); }
.dvp-req { color: var(--dn); margin-left: 2px; }
.dvp-try-form { display: grid; gap: var(--sp-3); }
.dvp-try { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.dvp-try-url { font-size: 12px; color: var(--text-3); background: none; border: 0; padding: 0; word-break: break-all; }
.dvp-try-meta { font: 500 12px var(--font-mono); color: var(--text-3); }
.dvp-try-meta.ok { color: var(--up); }
.dvp-try-meta.bad { color: var(--dn); }
.dvp-try-out { margin: 0; max-height: 360px; overflow: auto; padding: 12px 14px; border-radius: var(--r-md); background: var(--ink-2); border: 1px solid var(--glass-edge); font-size: 12px; line-height: 1.55; color: var(--text-1); white-space: pre; }
.dvp-try-out .k { color: var(--accent-text); }
.dvp-try-out .s { color: var(--up); }
.dvp-try-out .n { color: var(--ion); }
.dvp-try-out .b { color: var(--series-4, var(--text-2)); }
.dvp-try-img img { max-width: 100%; height: auto; border-radius: var(--r-md); border: 1px solid var(--glass-edge); display: block; }
.dvp-cache[hidden] { display: none; }

/* ── code tabs ── */
.dvp-code { position: relative; display: grid; gap: 8px; }
.dvp-code-tabs { display: inline-flex; gap: 4px; padding: 4px; border-radius: var(--r-pill); background: var(--ink-2); width: max-content; max-width: 100%; }
.dvp-code .cf-tab { min-height: 32px; padding: 0 12px; border: 0; border-radius: var(--r-pill); background: none; color: var(--text-2); font: 600 13px var(--font-display); cursor: pointer; }
.dvp-code .cf-tab[aria-selected="true"] { background: var(--molten); color: var(--on-molten); }
.dvp-code pre { margin: 0; padding: 14px 16px; border-radius: var(--r-md); background: var(--ink-2); border: 1px solid var(--glass-edge); overflow-x: auto; }
.dvp-code .dvp-copy { position: absolute; right: 0; top: 4px; }   /* in the tab row, beside the tabs: never over the code, whatever its length */

/* ── builder dashboard ── */
.dvp-program-state { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; color: var(--text-2); }
.dvp-dash { display: grid; gap: var(--sp-4); }
.dvp-dash-kpis { display: grid; gap: 10px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 900px) { .dvp-dash-kpis { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.dvp-dash-charts { display: grid; gap: var(--sp-4); grid-template-columns: 1fr; }
@media (min-width: 900px) { .dvp-dash-charts { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.dvp-dash-card { padding: var(--sp-4); border-radius: var(--r-md); background: rgb(var(--tint) / .04); border: 1px solid var(--glass-edge); display: grid; gap: 10px; }
.dvp-dash-card h3 { margin: 0; font: 600 15px var(--font-display); }
.dvp-range { display: inline-flex; gap: 4px; padding: 4px; border-radius: var(--r-pill); background: var(--ink-2); }
.dvp-range button { min-height: 30px; padding: 0 10px; border: 0; border-radius: var(--r-pill); background: none; color: var(--text-2); font: 600 12px var(--font-display); cursor: pointer; }
.dvp-range button[aria-pressed="true"] { background: var(--molten); color: var(--on-molten); }
.dvp-keyrow { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 10px 0; border-bottom: 1px solid rgb(var(--tint) / .06); }
.dvp-keyrow:last-child { border-bottom: 0; }
.dvp-keyrow code { font-size: 13px; word-break: break-all; min-width: 0; }
.dvp-keyrow .grow { flex: 1 1 auto; min-width: 0; color: var(--text-3); font-size: var(--fs-small); }
.dvp-newkey { padding: 14px; border-radius: var(--r-md); background: rgb(var(--glow) / .08); border: 1px solid rgb(var(--glow) / .4); display: grid; gap: 8px; }
.dvp-newkey code { font-size: 14px; word-break: break-all; background: var(--ink-2); display: block; padding: 10px; }
.dvp-form { display: grid; gap: 10px; max-width: 520px; }
.dvp-form label { display: grid; gap: 4px; font-size: var(--fs-small); color: var(--text-3); }
.dvp-form input { height: 42px; border-radius: var(--r-sm); border: 1px solid var(--glass-edge-hi); background: var(--ink-2); color: var(--text-1); padding: 0 12px; font: 500 14px var(--font-body); }
.dvp-form input:focus { outline: 0; border-color: rgb(var(--glow) / .6); box-shadow: 0 0 0 3px rgb(var(--glow) / .14); }
.dvp-form .row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.dvp-err { color: var(--dn); font-size: var(--fs-small); }
.dvp-ok { color: var(--up); font-size: var(--fs-small); }

/* ── changelog ── */
.dvp-log { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-4); }
.dvp-log-h { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin-bottom: 10px; }
.dvp-log-h time { font: 600 12px var(--font-mono); color: var(--accent-text); letter-spacing: .04em; }
.dvp-log-h h2 { margin: 0; font: 600 18px var(--font-display); }

/* ── brand ── */
.dvp-brand-grid { display: grid; gap: 12px; grid-template-columns: repeat(2, minmax(0, 1fr)); margin-bottom: var(--sp-4); }
@media (min-width: 720px) { .dvp-brand-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.dvp-brand-item { display: grid; gap: 8px; justify-items: center; padding: 14px; border-radius: var(--r-md); background: var(--ink-2); border: 1px solid var(--glass-edge); color: var(--text-2); font-size: var(--fs-small); text-align: center; }
.dvp-brand-item img { max-width: 100%; height: auto; border-radius: 8px; }
.dvp-brand-item:hover { text-decoration: none; border-color: rgb(var(--glow) / .45); }

/* ── search results, toast ── */
.dvp-search-results { margin-bottom: var(--sp-4); }
.dvp-search-results[hidden] { display: none; }
.dvp-sr { display: grid; gap: 4px; padding: 12px 14px; border-radius: var(--r-md); color: var(--text-1); border: 1px solid var(--glass-edge); background: rgb(var(--tint) / .04); margin-bottom: 8px; }
.dvp-sr:hover { text-decoration: none; border-color: rgb(var(--glow) / .45); }
.dvp-sr code { font-size: 12px; }
.dvp-toast { position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%); z-index: var(--z-toast); padding: 10px 16px; border-radius: var(--r-pill); background: var(--ink-3); color: var(--text-1); border: 1px solid var(--glass-edge-hi); box-shadow: var(--shadow-3); font: 600 13px var(--font-display); }
.dvp-toast[hidden] { display: none; }

/* ── entrances (added by script, removed on end) ── */
.dvp-in { animation: dvp-in var(--t-enter, .6s) var(--ease-out) both; }
@keyframes dvp-in { from { opacity: 0; transform: translateY(14px) scale(.99); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .dvp-in { animation: none; }
  .dvp-card, .dvp-card:hover { transition: none; transform: none; }
}
@media (max-width: 600px) {
  .dvp-top-acts .cf-btn { display: none; }
}
@media (max-width: 480px) {
  .dvp-search kbd, .dvp-word { display: none; }
  .dvp-top { gap: 10px; }
  .dvp-ep { padding: var(--sp-4); }
  .dvp-anchor { display: none; }
}

/* ── the parameter table stacks on a phone: one block per parameter ── */
@media (max-width: 720px) {
  .dvp-params thead { display: none; }
  .dvp-params, .dvp-params tbody, .dvp-params tr, .dvp-params td { display: block; width: 100%; }
  .dvp-params tr { padding: 10px 0; border-bottom: 1px solid rgb(var(--tint) / .06); }
  .dvp-params tr:last-child { border-bottom: 0; }
  .dvp-params td { padding: 2px 0; border: 0; }
  .dvp-params td:nth-child(2), .dvp-params td:nth-child(3) { display: inline-block; width: auto; margin-right: 10px; color: var(--text-3); font: 500 11px var(--font-mono); text-transform: uppercase; letter-spacing: .06em; }
  .dvp-params td:last-child { padding-top: 6px; }
}

/* ── compact docs (owner 2026-10-14): disclosures, builder, on-this-page, search popover ── */
.dvp-hide-sm { }
@media (max-width: 760px) { .dvp-hide-sm { display: none; } }
.dvp-fig--sm { font-size: 20px; }
.dvp-more > summary { cursor: pointer; list-style: none; display: inline-flex; align-items: center; gap: 8px; min-height: 36px; color: var(--accent-text); font: 600 13px var(--font-display); }
.dvp-more > summary::-webkit-details-marker { display: none; }
.dvp-more > summary::before { content: ""; width: 7px; height: 7px; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(-45deg); transition: transform var(--t-fast) var(--ease-out); }
.dvp-more[open] > summary::before { transform: rotate(45deg); }
.dvp-more--panel { padding: var(--sp-3) var(--sp-5); }
.dvp-more .dvp-ul { margin-top: 8px; }
.dvp-hero-code { max-width: 640px; margin-top: var(--sp-3); }
.dvp-try-snip { margin-top: 6px; }
.dvp-pre-in { opacity: .0001; transform: translateY(14px); }
.dvp-ep, .dvp-api-section > .cf-h2 { transition: opacity var(--t-slow) var(--ease-out), transform var(--t-slow) var(--ease-out); }
@media (prefers-reduced-motion: reduce) { .dvp-pre-in { opacity: 1; transform: none; } .dvp-ep, .dvp-api-section > .cf-h2 { transition: none; } }
.dvp-api-tools-row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-top: 10px; }
.dvp-ep { padding: var(--sp-4); display: grid; gap: 8px; }
.dvp-ep .dvp-p { margin: 0; }

/* search popover */
.dvp-search-results { position: fixed; top: 70px; left: max(12px, calc(50% - 310px)); width: min(620px, calc(100vw - 24px)); max-height: min(60vh, 520px); overflow: auto; z-index: var(--z-popover); margin: 0; padding: 8px; border-radius: var(--r-lg); background: var(--ink-3); border: 1px solid var(--glass-edge-hi); box-shadow: var(--shadow-1), 0 24px 60px rgb(var(--shade) / .5); }
.dvp-sr { grid-template-columns: 48px minmax(0, 1fr); align-items: start; margin: 0; border-color: transparent; background: none; }
.dvp-sr.is-sel, .dvp-sr:hover { background: rgb(var(--glow) / .12); border-color: rgb(var(--glow) / .35); }
.dvp-sr-k { font: 700 10px var(--font-mono); letter-spacing: .08em; color: var(--text-3); padding-top: 3px; }
.dvp-sr > span:last-child { display: grid; gap: 2px; min-width: 0; }

/* builder */
.dvp-b-grid { display: grid; gap: var(--sp-5); grid-template-columns: minmax(0, 1fr); }
@media (min-width: 900px) { .dvp-b-grid { grid-template-columns: minmax(0, 1fr) 320px; } }
.dvp-b-form { display: grid; gap: var(--sp-3); align-content: start; }
.dvp-b-row { display: grid; gap: var(--sp-3); grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }
.dvp-field { display: grid; gap: 6px; font: 500 var(--fs-small) var(--font-body); color: var(--text-3); }
.dvp-field .cf-input, .dvp-b-form .cf-input { width: 100%; height: 44px; border-radius: var(--r-sm); border: 1px solid var(--glass-edge-hi); background: var(--ink-2); color: var(--text-1); padding: 0 12px; font: 500 14px var(--font-mono); }
.dvp-field .cf-input:focus { outline: 0; border-color: rgb(var(--glow) / .6); box-shadow: 0 0 0 3px rgb(var(--glow) / .14); }
.dvp-seg { display: inline-flex; flex-wrap: wrap; gap: 4px; padding: 4px; border-radius: var(--r-pill); background: var(--ink-2); width: max-content; max-width: 100%; }
.dvp-seg button { min-height: 40px; padding: 0 14px; border: 0; border-radius: var(--r-pill); background: none; color: var(--text-2); font: 600 13px var(--font-display); cursor: pointer; }
.dvp-seg button[aria-pressed="true"] { background: var(--molten); color: var(--on-molten); }
.dvp-b-out { display: grid; gap: var(--sp-3); align-content: start; }
.dvp-b-prev { display: grid; gap: 6px; min-height: 120px; align-content: center; }
.dvp-b-prev img { width: 100%; height: auto; border-radius: var(--r-md); border: 1px solid var(--glass-edge); display: block; animation: dvp-fade .4s var(--ease-out) both; }
.dvp-b-qr { width: 132px; }
.dvp-b-qr svg { width: 100%; height: auto; border-radius: 8px; display: block; }
.dvp-b-links { display: grid; gap: 8px; margin-top: var(--sp-4); }
.dvp-b-link { display: grid; grid-template-columns: 96px minmax(0, 1fr) auto; gap: 10px; align-items: center; padding: 8px 0; border-top: 1px solid rgb(var(--tint) / .06); }
.dvp-b-link code { min-width: 0; font-size: 12px; word-break: break-all; padding: 6px 8px; }
@media (max-width: 600px) { .dvp-b-link { grid-template-columns: minmax(0, 1fr) auto; } .dvp-b-link .cf-eyebrow { grid-column: 1 / -1; } }
@keyframes dvp-fade { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .dvp-b-prev img { animation: none; } }

/* on this page: a third column from 1280 */
.dvp-toc { display: none; }
@media (min-width: 1280px) {
  .dvp-shell { grid-template-columns: 240px minmax(0, 1fr) 200px; }
  .dvp-toc:not([hidden]) { display: grid; gap: 2px; align-content: start; position: sticky; top: 88px; align-self: start; padding: var(--sp-8) 0 0; max-height: calc(100vh - 100px); overflow: auto; }
  .dvp-toc .cf-eyebrow { margin-bottom: 8px; }
  .dvp-toc a { padding: 6px 0 6px 12px; border-left: 2px solid var(--glass-edge); color: var(--text-3); font: 500 13px var(--font-body); }
  .dvp-toc a:hover { color: var(--text-1); text-decoration: none; }
  .dvp-toc a.is-active { color: var(--accent-text-strong); border-left-color: var(--molten); }
}
.dvp-step > *, .dvp-code, .dvp-try-snip { min-width: 0; max-width: 100%; }
.dvp-try-snip .dvp-try-out { width: 100%; }

/* ── touch widths (<= 1024, the sweep's own definition): every control is a
   44px box. Where the design is tight the VISUAL keeps its size and the extra
   is a transparent border -- the control's own box grows (a tap, and the
   sweep's probe, read the box; a pseudo-element hit area is clipped by the
   button's overflow:hidden and counts for nothing), the fill is clipped to the
   padding box and the 1px rim is drawn inset, so the pill on screen is the
   same 36px pill. Rows that have room (nav, footer, parameter fields) simply
   take the 44px row. Nothing here applies from 1025px up. ── */
@media (max-width: 1024px) {
  .dvp-brand { min-width: 44px; min-height: 44px; padding: 4px; margin: -4px; }
  .dvp-search input { min-height: 44px; }   /* the 40px pill stays; the field's own box is the finger's */
  .dvp-icon { width: 44px; height: 44px; flex: 0 0 44px; border: 2px solid transparent; background-clip: padding-box; box-shadow: inset 0 0 0 1px var(--glass-edge); }
  /* a bare link in prose, a table or the footer ("see them all", "Build one",
     "About"): the line box and the words stay where they are; the link's own
     box reaches 44 (symmetric padding, the same negative margin) */
  .dvp-article a:not([class]), .dvp-foot a { display: inline-block; padding: 14px 8px; margin: -14px -8px; }
  .dvp .cf-btn--sm { min-height: 44px; border-width: 4px 0; border-color: transparent !important; background-clip: padding-box; box-shadow: inset 0 0 0 1px var(--glass-edge-hi), var(--shadow-1); }
  .dvp .cf-btn--sm.cf-btn--ghost { box-shadow: inset 0 0 0 1px var(--glass-edge-hi); }
  .dvp .cf-btn--sm.cf-btn--primary { box-shadow: inset 0 0 0 1px var(--molten-hi), 0 1px 0 rgb(var(--sheen-rgb) / .5) inset, 0 -2px 0 var(--molten-lo) inset, 0 6px 22px rgb(var(--glow) / .32), 0 2px 4px rgb(var(--shade) / .4); }
  .dvp-nav-a { min-height: 44px; }           /* the phone pill strip, and the rail at exactly 1024 */
  .dvp-section-chips .cf-chip { min-height: 44px; border-width: 6px 0; border-color: transparent; background-clip: padding-box; box-shadow: inset 0 0 0 1px var(--glass-edge); }
  .dvp-anchor { display: inline-grid; place-items: center; min-width: 44px; min-height: 44px; }
  .dvp-copy-inline { display: inline-flex; align-items: center; min-height: 44px; min-width: 44px; }
  .dvp-more > summary { min-height: 44px; }
  .dvp-params .cf-input, .dvp-param { height: 44px; }
  .dvp-seg button, .dvp-range button { min-height: 44px; }
  .dvp-code .cf-tab { min-height: 36px; }    /* + its own ::before hit box (inset -4px) inside the bar's 4px padding = 44 */
  .dvp-code .dvp-copy { top: 0; }            /* its 44px box lines up with the 44px tab bar; the pill sits where it did */
}


/* ---- static/cf-kb-widget.css ---- */
/* "Ask about Cartel Family" -- the support assistant (static/cf-kb-widget.js).
 * Syndicate Noir: glass panel, molten launcher, every colour a cf-theme.css
 * token (both themes), a drawer from 900px and a bottom sheet below it.
 * Reduced motion: no entrance, the finished state. */
.cfkb{--cfkb-w:400px;font-family:var(--font-ui,var(--font-body,system-ui))}
.cfkb-sr{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.cfkb-launch{position:fixed;right:max(16px,env(safe-area-inset-right));bottom:max(16px,env(safe-area-inset-bottom));z-index:var(--z-popover,900);
  display:inline-flex;align-items:center;gap:8px;min-height:44px;padding:0 16px 0 14px;border-radius:999px;cursor:pointer;
  border:1px solid rgb(var(--glow,61 151 255) / .45);background:var(--acc,#3d97ff);color:var(--onAcc,#04122a);
  font:700 13px/1 var(--font-ui,inherit);letter-spacing:.01em;box-shadow:var(--shadow-3,0 12px 32px rgba(0,0,0,.35));
  transition:transform .18s var(--ease-out,ease),box-shadow .18s}
.cfkb-launch:hover{transform:translateY(-1px);box-shadow:var(--shadow-3,0 12px 32px rgba(0,0,0,.35)),0 0 0 4px rgb(var(--glow,61 151 255) / .18)}
.cfkb-launch:focus-visible{outline:2px solid var(--acc,#3d97ff);outline-offset:3px}
.cfkb[data-state="open"] .cfkb-launch,.cfkb-launch[hidden]{display:none}
.cfkb-scrim{position:fixed;inset:0;z-index:var(--z-sheet,1500);background:rgb(var(--scrim-rgb,0 0 0) / .55);-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}
.cfkb-scrim[hidden],.cfkb-panel[hidden]{display:none}
.cfkb-panel{position:fixed;z-index:calc(var(--z-sheet,1500) + 1);left:0;right:0;bottom:0;max-height:88dvh;overflow:auto;overscroll-behavior:contain;
  padding:10px 16px calc(16px + env(safe-area-inset-bottom));border-radius:var(--r-sheet,20px) var(--r-sheet,20px) 0 0;
  background:linear-gradient(180deg,var(--sheet-hi,var(--s1)),var(--sheet-lo,var(--s1)));border:1px solid var(--glass-edge-hi,var(--line));border-bottom:0;
  box-shadow:var(--shadow-3,0 12px 32px rgba(0,0,0,.35));color:var(--ink);touch-action:pan-y}
.cfkb-panel.is-in{animation:cfkb-up .42s var(--ease-spring,cubic-bezier(.2,.9,.3,1.1))}
.cfkb-panel.is-out{animation:cfkb-down .24s ease-in forwards}
@keyframes cfkb-up{from{transform:translateY(100%)}to{transform:none}}
@keyframes cfkb-down{to{transform:translateY(105%)}}
.cfkb-grab{width:44px;height:5px;margin:0 auto 12px;border-radius:3px;background:var(--ink-5,var(--line))}
.cfkb-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}
.cfkb-eyebrow{display:block;font:700 10px/1 var(--font-ui,inherit);letter-spacing:.14em;text-transform:uppercase;color:var(--accT,var(--acc));margin-bottom:6px}
.cfkb-head h2{margin:0;font:700 20px/1.2 var(--font-display,var(--font-ui,inherit));letter-spacing:-.02em;color:var(--ink)}
.cfkb-x{flex:none;width:36px;height:36px;border-radius:10px;border:1px solid var(--line);background:transparent;color:var(--ink2);font:400 22px/1 var(--font-ui,inherit);cursor:pointer}
.cfkb-x:hover{color:var(--ink);background:var(--s2)}
.cfkb-sub{margin:8px 0 10px;font:500 12.5px/1.5 var(--font-ui,inherit);color:var(--ink2)}
.cfkb-mode{color:var(--pro,var(--ink3));font-weight:600}
.cfkb-chips{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:10px}
.cfkb-chip{min-height:32px;padding:0 11px;border-radius:999px;border:1px solid var(--line);background:var(--s2);color:var(--ink);font:600 12px var(--font-ui,inherit);cursor:pointer;position:relative}
.cfkb-chip::before{content:'';position:absolute;inset:-6px}
.cfkb-chip:hover{border-color:var(--acc)}
.cfkb-form{display:flex;gap:8px}
.cfkb-in{flex:1;min-width:0;height:44px;padding:0 12px;border-radius:12px;border:1px solid var(--line);background:var(--bg);color:var(--ink);font:500 14px var(--font-ui,inherit);outline:none}
.cfkb-in:focus{border-color:var(--acc);box-shadow:0 0 0 3px rgb(var(--glow,61 151 255) / .18)}
.cfkb-ask{height:44px;padding:0 16px;border-radius:12px;border:1px solid var(--acc);background:var(--acc);color:var(--onAcc,#04122a);font:700 13px var(--font-ui,inherit);cursor:pointer}
.cfkb-ask:disabled{opacity:.5;cursor:progress}
.cfkb-out{margin-top:12px;font:500 14px/1.55 var(--font-ui,inherit);color:var(--ink)}
.cfkb-out.is-in{animation:cfkb-fade .35s ease-out}
@keyframes cfkb-fade{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
.cfkb-out:empty{display:none}
.cfkb-answer p{margin:0 0 8px}
.cfkb-cite{color:var(--accT,var(--acc));text-decoration:none;font:700 12px var(--font-num,monospace)}
.cfkb-cite--f{color:var(--ion,var(--accT))}
.cfkb-cite:hover{text-decoration:underline}
.cfkb-note{padding:10px 12px;border-radius:12px;background:var(--s2);color:var(--ink2);font:600 12.5px/1.45 var(--font-ui,inherit)}
.cfkb-h3{margin:12px 0 6px;font:700 10px/1 var(--font-ui,inherit);letter-spacing:.14em;text-transform:uppercase;color:var(--ink3)}
.cfkb-src{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}
.cfkb-src-i{padding:8px 0;border-top:1px solid var(--line);display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 8px}
.cfkb-src-i:first-child{border-top:0}
.cfkb-src-i.is-used{background:linear-gradient(90deg,rgb(var(--glow,61 151 255) / .08),transparent)}
.cfkb-src-i a{color:var(--ink);text-decoration:none;font-weight:600;font-size:13px;flex:1;min-width:0}
.cfkb-src-i a:hover{color:var(--accT,var(--acc))}
.cfkb-n{color:var(--accT,var(--acc));font:700 12px var(--font-num,monospace)}
.cfkb-dim{color:var(--ink3);font-weight:500}
.cfkb-date{font:500 11px var(--font-num,monospace);color:var(--ink3)}
.cfkb-snip{flex-basis:100%;margin:2px 0 0;font:500 12.5px/1.5 var(--font-ui,inherit);color:var(--ink2)}
.cfkb-toggle{margin-top:10px;background:transparent;border:0;padding:0;color:var(--ink2);font:600 12px var(--font-ui,inherit);cursor:pointer;text-decoration:underline dotted;min-height:32px}
.cfkb-facts{list-style:none;margin:4px 0 0;padding:0;font:500 12.5px/1.5 var(--font-ui,inherit);color:var(--ink2)}
.cfkb-facts li{padding:4px 0;border-top:1px solid var(--line)}
.cfkb-num{font-family:var(--font-num,monospace);font-variant-numeric:tabular-nums;color:var(--ink)}
.cfkb-model{margin:10px 0 0;font:500 11.5px/1.45 var(--font-ui,inherit);color:var(--ink3)}
.cfkb-empty{color:var(--ink2);font-size:13px}
.cfkb-empty a,.cfkb-foot a{color:var(--accT,var(--acc))}
.cfkb-err{padding:10px 12px;border-radius:12px;background:var(--dnBg,rgba(255,80,80,.12));color:var(--dn,#ff6b6b);font:600 13px/1.45 var(--font-ui,inherit)}
.cfkb-err p{margin:0 0 8px}
.cfkb-loading{display:flex;align-items:center;gap:6px;color:var(--ink2);font:600 13px var(--font-ui,inherit)}
.cfkb-dot{width:6px;height:6px;border-radius:50%;background:var(--acc);animation:cfkb-beat 1s infinite ease-in-out}
.cfkb-dot:nth-child(2){animation-delay:.15s}.cfkb-dot:nth-child(3){animation-delay:.3s}
@keyframes cfkb-beat{0%,100%{opacity:.35;transform:scale(.8)}50%{opacity:1;transform:scale(1)}}
.cfkb-foot{margin-top:14px;padding-top:10px;border-top:1px solid var(--line);font:500 11.5px/1.45 var(--font-ui,inherit);color:var(--ink3)}
@media (min-width:900px){
  .cfkb-panel{left:auto;right:24px;bottom:24px;width:var(--cfkb-w);max-height:min(78vh,720px);border-radius:var(--r-lg,20px);border-bottom:1px solid var(--glass-edge-hi,var(--line));padding:16px 18px 18px}
  .cfkb-panel.is-in{animation:cfkb-pop .32s var(--ease-out,ease)}
  .cfkb-panel.is-out{animation:cfkb-pop-out .2s ease-in forwards}
  @keyframes cfkb-pop{from{opacity:0;transform:translateY(14px) scale(.985)}to{opacity:1;transform:none}}
  @keyframes cfkb-pop-out{to{opacity:0;transform:translateY(10px) scale(.985)}}
  .cfkb-grab{display:none}
  .cfkb-scrim{background:transparent;-webkit-backdrop-filter:none;backdrop-filter:none}
}
@media (max-width:480px){.cfkb-launch-t{display:none}.cfkb-launch{width:48px;height:48px;padding:0;justify-content:center}}
@media (prefers-reduced-motion:reduce){
  .cfkb-panel.is-in,.cfkb-panel.is-out,.cfkb-out.is-in,.cfkb-dot{animation:none}
  .cfkb-launch,.cfkb-launch:hover{transition:none;transform:none}
}

