@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/cf-grow.css ---- */
/* Grow — Promote, Token Launch and Auto Bot (design §6.13, §6.17, §6.18).
 *
 * Measured from CFGrow.dc.html. One stylesheet for the three pages because
 * the design draws them from one component: the same page frame, the same
 * s1 card, the same 56px setting row with a segmented control, the same
 * status pill. Three copies would be three slightly different cards.
 *
 *   page     padding 24/28 desktop, 12/16/24 phone; gap 14; max 1100
 *   title    26/800, tabs (s2 track, 34px, radius 12/9) on the right
 *   card     s1, 1px line, radius 16; head 14/16/8, 15/800
 *   row      padding 10/16, border-top line, min-height 56-60
 *   field    44px, --bg, 1px line, radius 10, 14 mono
 *   primary  52px, radius 14, 15/800, acc on onAcc
 *
 * Every colour is a cf-theme.css design token; light mode is the same rules
 * on the other palette. Nothing rests at opacity:0.
 *
 * SYNDICATE NOIR (2026-10-12): the same class names drawn as /design/a/*
 * (COMPONENTS.md): cards are glass panels with the 1px light edge, tabs and
 * segmented controls are the ink track with a molten thumb, the primary is
 * the molten pill with the light sweep, pills are mono chips, the switch is
 * the Noir switch, the curve is the molten bar, every figure is mono.
 */

body.cf-grow{ color:var(--ink); font-family:var(--font-body,var(--font-ui)); min-height:100%; margin:0; }
body.cf-grow *{ box-sizing:border-box; }

.gr-wrap{
  width:100%; max-width:var(--maxw,1320px);
  padding:24px 28px 96px;
  display:flex; flex-direction:column; gap:14px;
}
@media (max-width:767px){
  .gr-wrap{ padding:12px 16px 24px; }
  .gr-wrap > .cf-phone-hub{ margin:0 -16px; padding:0 16px; }
}
.gr-sr{ position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; }
.gr-mono{ font-family:var(--font-mono); font-variant-numeric:tabular-nums; }

/* ── title + tabs ─────────────────────────────────────────────────────── */
.gr-head{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; }
.gr-head h1{ margin:0; font:700 var(--fs-page-title,26px)/1.15 var(--font-display,var(--font-ui)); letter-spacing:-.03em; color:var(--ink); }
.gr-tabs{ margin-left:auto; display:flex; gap:2px; background:var(--ink-2); border:1px solid var(--glass-edge); border-radius:var(--r-pill,999px); padding:4px; }
.gr-tab{
  height:36px; padding:0 15px; border:0; border-radius:var(--r-pill,999px); cursor:pointer;
  display:flex; align-items:center; font:600 13px var(--font-display,var(--font-ui));
  background:transparent; color:var(--ink2); text-decoration:none;
  transition:color var(--t-med,.28s),background var(--t-med,.28s),box-shadow var(--t-med,.28s);
}
.gr-tab.is-on{ background:var(--molten); color:var(--on-molten); box-shadow:0 4px 14px rgb(var(--glow) / .35); }
@media (hover:hover){ .gr-tab:not(.is-on):hover{ color:var(--ink); } }

/* ── layout ───────────────────────────────────────────────────────────── */
.gr-two{ display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:16px; align-items:start; }
.gr-col{ display:flex; flex-direction:column; gap:16px; min-width:0; }
@media (max-width:1023px){ .gr-two{ grid-template-columns:1fr; } }

/* ── card ─────────────────────────────────────────────────────────────── */
.gr-card{ position:relative; border-radius:var(--r-lg,20px); overflow:hidden; min-width:0; 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)); }
.gr-card::before, .gr-launch::before, .gr-bot::before{
  content:''; position:absolute; inset:0; 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;
}
.gr-card-pad{ padding:16px; display:flex; flex-direction:column; gap:12px; }
.gr-card-pad.tight{ padding:14px; gap:8px; }
.gr-card-h{
  padding:14px 16px 8px; display:flex; align-items:baseline; justify-content:space-between; gap:10px;
  font:600 17px/1.3 var(--font-display,var(--font-ui)); letter-spacing:-.01em; color:var(--ink);
}
.gr-card-h small{ font:600 10.5px var(--font-mono); letter-spacing:.12em; text-transform:uppercase; color:var(--ink3); }
/* The design's list cards (Bot positions, Recently graduated, Promotions)
   close their head 6px above the first row; the setting cards 8px. */
.gr-card-h.p6{ padding-bottom:6px; }
.gr-card-title{ margin:0; font:600 18px/1.2 var(--font-display,var(--font-ui)); letter-spacing:-.01em; color:var(--ink); }
.gr-card-sub{ margin:0; font:600 16px/1.3 var(--font-display,var(--font-ui)); color:var(--ink); }

/* A list row, 56-60px, hairline above. */
.gr-row{
  display:flex; align-items:center; gap:12px; padding:10px 16px;
  border-top:1px solid rgb(var(--tint) / .05); min-height:56px; flex-wrap:wrap;
}
.gr-row-l{ font:600 14.5px/1.3 var(--font-display,var(--font-ui)); flex:1; min-width:140px; color:var(--ink); }
.gr-row-note{ display:block; font:500 12.5px/1.4 var(--font-body,var(--font-ui)); color:var(--ink2); margin-top:2px; }

/* Segmented control on s2: 32px options, the chosen one on s1. */
.gr-seg{ display:flex; background:var(--ink-2); border:1px solid var(--glass-edge); border-radius:var(--r-pill,999px); padding:2px; flex-wrap:wrap; }
.gr-seg button{
  height:32px; padding:0 11px; border:0; border-radius:var(--r-pill,999px); cursor:pointer;
  display:flex; align-items:center; background:transparent; color:var(--ink2);
  font:600 12px var(--font-mono); transition:color var(--t-med,.28s),background var(--t-med,.28s);
}
.gr-seg button[aria-pressed="true"]{ background:var(--molten); color:var(--on-molten); box-shadow:0 3px 12px rgb(var(--glow) / .3); }
.gr-seg button:disabled{ cursor:default; }
/* The editable last segment (Auto Bot): the same 32px option, holding a
   free-entry value the presets do not cover. Pressed when that value is the
   saved one. */
.gr-seg-custom{ display:flex; align-items:center; height:32px; padding:0 10px; border-radius:var(--r-pill,999px); }
.gr-seg-custom input{
  width:6.5ch; height:100%; background:transparent; border:0; outline:0; padding:0;
  font:600 12px var(--font-mono); color:var(--ink2); text-align:center;
}
.gr-seg-custom input::placeholder{ color:var(--ink2); }
.gr-seg-custom[aria-pressed="true"]{ background:var(--molten); }
.gr-seg-custom[aria-pressed="true"] input{ color:var(--on-molten); }
.gr-seg-custom:focus-within{ box-shadow:var(--focus-ring); }
/* At 390 a row is 322px inside: the three presets plus a narrow custom
   segment fit beside the label only with the label's minimum at 120 (no
   drawn label is wider than 107) and the custom segment at 4ch. */
@media (max-width:767px){
  /* app-ux.css keeps every input at 16px on a phone (iOS zooms below it),
     so the custom segment is 4ch of 16px mono: 50px. The widest track
     (Max trade: $50 $100 $250 + custom) is 194, and 112 + 12 + 194 fits the
     row's 324 inside; no drawn label is wider than 107. */
  .gr-row-l{ min-width:112px; }
  .gr-seg-custom{ padding:0 6px; }
  .gr-seg-custom input{ width:4ch; }
}

/* Field */
.gr-field{ display:flex; flex-direction:column; gap:6px; }
.gr-field > span{ font:600 var(--fs-micro,11px)/1.2 var(--font-mono); letter-spacing:var(--tr-caps,.16em); text-transform:uppercase; color:var(--ink3); }
/* 46: the prototype's 44px input is content-box, so its box renders 46. */
.gr-input{
  width:100%; height:46px; padding:0 14px; background:var(--ink-2);
  border:1px solid var(--glass-edge-hi); border-radius:var(--r-md,14px); outline:0;
  font:500 15px var(--font-mono); color:var(--ink);
  transition:border-color var(--t-fast,.16s),box-shadow var(--t-fast,.16s);
}
.gr-input::placeholder{ color:var(--ink3); }
.gr-input:focus{ border-color:var(--gold-400,var(--acc)); box-shadow:0 0 0 3px rgb(var(--glow) / .2); }
textarea.gr-input{ height:auto; padding:10px 12px; resize:vertical; font-size:13px; }

/* Key/value receipt on --bg */
.gr-sum{
  background:var(--well); border:1px solid rgb(var(--tint) / .04); border-radius:var(--r-md,14px); padding:12px 14px;
  display:flex; flex-direction:column; gap:7px; font:500 13px var(--font-mono); color:var(--ink2);
}
.gr-sum > div{ display:flex; justify-content:space-between; gap:12px; }
.gr-sum > div > span:last-child{ color:var(--ink); text-align:right; word-break:break-all; }
.gr-sum > div.b{ font-weight:600; color:var(--ink); padding-top:7px; border-top:1px dashed var(--glass-edge); }
.gr-sum > div.b > span:last-child{ color:var(--accent-text-strong); }

/* Buttons */
.gr-primary{
  width:100%; height:54px; border:1px solid var(--molten-hi); border-radius:var(--r-pill,999px); cursor:pointer;
  display:flex; align-items:center; justify-content:center; text-decoration:none;
  background-image:linear-gradient(105deg,transparent 30%,rgb(var(--sheen-rgb) / .38) 46%,rgb(var(--sheen-rgb) / .06) 54%,transparent 64%),var(--molten); background-size:300% 100%,100% 100%; background-position:100% 0,0 0; background-repeat:no-repeat; color:var(--on-molten); font:600 16px var(--font-display,var(--font-ui));
  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) / .32),0 2px 4px rgb(var(--shade) / .4);
  transition:background-position var(--t-sweep,.76s) var(--ease-out,ease),box-shadow var(--t-med,.28s),transform var(--t-med,.28s) var(--ease-spring,ease);
}
.gr-primary:disabled{ background:var(--ink-4); border-color:var(--glass-edge); color:var(--ink3); cursor:default; box-shadow:none; text-shadow:none; }
.gr-btn{
  height:40px; padding:0 18px; border:1px solid var(--molten-hi); border-radius:var(--r-pill,999px); cursor:pointer;
  display:inline-flex; align-items:center; justify-content:center; text-decoration:none;
  background-image:linear-gradient(105deg,transparent 30%,rgb(var(--sheen-rgb) / .38) 46%,rgb(var(--sheen-rgb) / .06) 54%,transparent 64%),var(--molten); background-size:300% 100%,100% 100%; background-position:100% 0,0 0; background-repeat:no-repeat; color:var(--on-molten); font:600 13.5px var(--font-display,var(--font-ui)); white-space:nowrap;
  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) / .32),0 2px 4px rgb(var(--shade) / .4);
  transition:background-position var(--t-sweep,.76s) var(--ease-out,ease),box-shadow var(--t-med,.28s),border-color var(--t-med,.28s),transform var(--t-med,.28s) var(--ease-spring,ease);
}
.gr-btn.ghost{ background:var(--ink-4); border-color:var(--glass-edge-hi); color:var(--ink); text-shadow:none; box-shadow:var(--shadow-1); }
.gr-btn.outline{ background:rgb(var(--glow) / .08); border:1px solid rgb(var(--glow) / .45); color:var(--accent-text-strong); text-shadow:none; box-shadow:none; }
.gr-btn:disabled{ opacity:.5; cursor:default; }
@media (hover:hover){
  .gr-primary:not(:disabled):hover,.gr-btn:not(:disabled):not(.ghost):not(.outline):hover{ background-position:0 0,0 0; 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); }
  .gr-btn.ghost:not(:disabled):hover,.gr-btn.outline:not(:disabled):hover{ border-color:rgb(var(--glow) / .5); box-shadow:var(--shadow-2),0 0 0 1px rgb(var(--glow) / .18); }
}
.gr-primary:not(:disabled):active,.gr-btn:not(:disabled):active{ transform:scale(.96); transition-duration:90ms; }
.gr-primary:focus-visible,.gr-btn:focus-visible,.gr-tab:focus-visible,.gr-seg button:focus-visible,
.gr-pick:focus-visible,.gr-switch:focus-visible,.gr-dur:focus-visible,.gr-chainbtn:focus-visible,.gr-step:focus-visible{ outline:none; box-shadow:var(--focus-ring); }

/* Status pill: 11/700, radius 6 */
.gr-pill{
  display:inline-flex; align-items:center; gap:6px; height:22px; padding:0 9px; border-radius:var(--r-pill,999px); white-space:nowrap;
  font:600 10.5px/1 var(--font-mono); letter-spacing:.08em; text-transform:uppercase;
  background:rgb(var(--tint) / .05); border:1px solid var(--glass-edge); color:var(--ink2);
}
.gr-pill.up{ color:var(--up); background:var(--up-dim,var(--upBg)); border-color:rgb(var(--up-rgb) / .3); }
.gr-pill.pro{ color:var(--accent-text-strong); background:rgb(var(--glow) / .12); border-color:rgb(var(--glow) / .35); }
.gr-pill.mute{ color:var(--ink3); }
.gr-pill.dn{ color:var(--dn); background:var(--dn-dim,var(--dnBg)); border-color:rgb(var(--dn-rgb) / .3); }

.gr-up{ color:var(--up); text-shadow:0 0 12px rgb(var(--up-rgb) / .3); } .gr-dn{ color:var(--dn); text-shadow:0 0 12px rgb(var(--dn-rgb) / .3); } .gr-dim{ color:var(--ink2); } .gr-pro{ color:var(--accent-text-strong); }

.gr-empty{ padding:22px 16px 20px; border-top:1px solid rgb(var(--tint) / .05); font:500 13.5px/1.5 var(--font-body,var(--font-ui)); color:var(--ink2); text-align:center; }
.gr-empty.cf-has-vault{ align-items:center; }
.gr-note{ margin:0; font:500 12.5px/1.5 var(--font-body,var(--font-ui)); color:var(--ink2); }
.gr-err{ margin:0; font:600 13px/1.45 var(--font-body,var(--font-ui)); color:var(--dn); }
.gr-err:empty{ display:none; }
/* A link that appears once a field is filled: hidden really hides it. */
.gr-claim-link{ display:inline-flex; align-items:center; min-height:44px; color:var(--accent-text-strong); font-weight:600; text-decoration:none; }
.gr-claim-link[hidden]{ display:none; }

/* Busy / done strips (checkout, wizard) */
.gr-busy{ display:flex; align-items:center; gap:10px; background:rgb(var(--ion-rgb) / .06); border:1px solid rgb(var(--ion-rgb) / .22); border-radius:var(--r-md,14px); padding:12px 14px; font:600 13.5px var(--font-display,var(--font-ui)); }
.gr-spin{ width:20px; height:20px; border-radius:50%; border:3px solid rgb(var(--tint) / .1); border-top-color:var(--ion); flex:none; }
.gr-done{ display:flex; align-items:center; gap:10px; background:var(--up-dim,var(--upBg)); border:1px solid rgb(var(--up-rgb) / .3); border-radius:var(--r-md,14px); padding:12px 14px; font:600 13.5px var(--font-display,var(--font-ui)); }
.gr-done b{ font:700 16px var(--font-display,var(--font-ui)); color:var(--up); }
.gr-fail{ display:flex; align-items:center; gap:10px; background:var(--dn-dim,var(--dnBg)); border:1px solid rgb(var(--dn-rgb) / .4); border-radius:var(--r-md,14px); padding:12px 14px; font:600 13.5px var(--font-display,var(--font-ui)); color:var(--ink); }

/* Toggle switch (bot on/off 64x36, AI 44x26) */
.gr-switch{
  position:relative; width:64px; height:36px; border-radius:18px; border:0; padding:0; cursor:pointer;
  background:var(--ink-2); box-shadow:inset 0 0 0 1px var(--glass-edge-hi); flex:none; transition:background var(--t-med,.28s),box-shadow var(--t-med,.28s);
}
.gr-switch::after{
  content:""; position:absolute; top:4px; left:4px; width:28px; height:28px; border-radius:50%;
  background:var(--ink3); box-shadow:var(--shadow-1); transition:left var(--t-med,.28s) var(--ease-spring,ease),background var(--t-med,.28s);
}
.gr-switch[aria-checked="true"]{ background:rgb(var(--glow) / .25); box-shadow:inset 0 0 0 1px rgb(var(--glow) / .6); }
.gr-switch[aria-checked="true"]::after{ left:32px; background:var(--molten); box-shadow:0 0 12px rgb(var(--glow) / .6); }
.gr-switch.sm{ width:44px; height:26px; border-radius:13px; }
.gr-switch.sm::after{ top:3px; left:3px; width:20px; height:20px; }
.gr-switch.sm[aria-checked="true"]::after{ left:21px; }
.gr-switch:disabled{ cursor:default; opacity:.6; }

/* ── Promote ──────────────────────────────────────────────────────────── */
.gr-pick{
  width:100%; border:0; background:transparent; color:inherit; text-align:left; cursor:pointer;
  display:flex; align-items:center; gap:12px; padding:10px 16px; min-height:60px;
  border-top:1px solid rgb(var(--tint) / .05); font:inherit; transition:background var(--t-fast,.16s);
}
@media (hover:hover){ .gr-pick:not(.is-on):hover{ background:rgb(var(--tint) / .03); } }
.gr-pick.is-on{ background:linear-gradient(90deg,rgb(var(--glow) / .14),rgb(var(--glow) / .03)); box-shadow:inset 3px 0 0 var(--gold-400); }
.gr-ring{
  width:20px; height:20px; border-radius:50%; border:2px solid var(--glass-edge-hi); flex:none;
  display:flex; align-items:center; justify-content:center;
}
.gr-ring i{ width:10px; height:10px; border-radius:50%; background:transparent; }
.gr-pick.is-on .gr-ring{ border-color:var(--gold-400); }
.gr-pick.is-on .gr-ring i{ background:var(--molten); box-shadow:0 0 8px rgb(var(--glow) / .6); }
.gr-pick-t{ display:flex; flex-direction:column; gap:2px; flex:1; min-width:0; }
.gr-pick-t b{ font:600 14.5px var(--font-display,var(--font-ui)); color:var(--ink); }
.gr-pick-t span{ font:500 12.5px var(--font-body,var(--font-ui)); color:var(--ink2); }
.gr-pick-r{ display:flex; flex-direction:column; align-items:flex-end; gap:2px; flex:none; }
.gr-pick-r b{ font:600 13.5px var(--font-mono); color:var(--accent-text-strong); white-space:nowrap; }
/* Availability: "available" in the up colour, a live count in the second
   ink, an unknown in the third (the design's availFg). */
.gr-pick-r span{ font:600 10.5px var(--font-mono); letter-spacing:.06em; text-transform:uppercase; color:var(--up); white-space:nowrap; }
.gr-pick-r span.busy{ color:var(--ink2); }
.gr-pick-r span.unk{ color:var(--ink3); }
.pr-h-r{ display:inline-flex; align-items:center; gap:12px; flex-wrap:wrap; }
.gr-group-note{ padding:10px 16px 14px; border-top:1px solid rgb(var(--tint) / .05); font:500 12.5px/1.5 var(--font-body,var(--font-ui)); color:var(--ink2); margin:0; }

/* Duration chips: the chosen one is ink on ink-ground, the rest s2. */
.gr-durs{ display:flex; gap:6px; }
.gr-dur{
  flex:1; height:40px; border:1px solid var(--glass-edge); border-radius:var(--r-pill,999px); display:flex; align-items:center; justify-content:center;
  font:600 13px var(--font-mono); background:rgb(var(--tint) / .05); color:var(--ink2); cursor:pointer;
  transition:background var(--t-fast,.16s),color var(--t-fast,.16s),border-color var(--t-fast,.16s);
}
.gr-dur[aria-checked="true"]{ background:rgb(var(--glow) / .2); border-color:rgb(var(--glow) / .55); color:var(--accent-text-strong); }

.gr-mine{ display:flex; align-items:center; gap:10px; padding:10px 16px; border-top:1px solid rgb(var(--tint) / .05); flex-wrap:wrap; }
.gr-mine-s{ font:600 14.5px var(--font-display,var(--font-ui)); flex:1; min-width:120px; color:var(--ink); }
.gr-mine-s span{ font:500 12.5px var(--font-body,var(--font-ui)); color:var(--ink2); }
.gr-mine-w{ font:500 12px var(--font-mono); color:var(--ink3); }

/* ── Token Launch ─────────────────────────────────────────────────────── */
.gr-board{ display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:16px; }
@media (max-width:1023px){ .gr-board{ grid-template-columns:1fr; } }
.gr-launch{ position:relative; border-radius:var(--r-lg,20px); padding:16px; display:flex; flex-direction:column; gap:10px; min-width:0; 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));
  transition:transform var(--t-med,.28s) var(--ease-out,ease),border-color var(--t-med,.28s),box-shadow var(--t-med,.28s); }
@media (hover:hover){ .gr-launch:not(.dashed):hover{ transform:translateY(-2px); border-color:rgb(var(--glow) / .22); box-shadow:var(--shadow-3); } }
.gr-launch.dashed{ border-style:dashed; border-color:rgb(var(--glow) / .28); justify-content:center; align-items:flex-start; background:linear-gradient(160deg,rgb(var(--glow) / .07),rgb(var(--raise) / .4)); }
.gr-launch.dashed::before{ display:none; }
.gr-tok{ display:flex; align-items:center; gap:10px; }
.gr-tok-av{
  width:44px; height:44px; border-radius:13px; background:var(--ink-4); flex:none; overflow:hidden; position:relative;
  font:700 14px/44px var(--font-mono); color:var(--accent-text-strong); text-align:center;
  box-shadow:0 0 0 1px var(--glass-edge-hi),var(--shadow-1);
}
.gr-tok-av img{ width:100%; height:100%; object-fit:cover; display:block; }
.gr-tok-t{ display:flex; flex-direction:column; gap:2px; flex:1; min-width:0; }
.gr-tok-t b{ font:700 17px var(--font-display,var(--font-ui)); letter-spacing:-.01em; color:var(--ink); }
.gr-tok-t span{ font:500 12px var(--font-mono); color:var(--ink3); }
.gr-chain{ font:600 10px var(--font-mono); letter-spacing:.06em; text-transform:uppercase; color:var(--ink2); background:rgb(var(--tint) / .05); border:1px solid var(--glass-edge); padding:2px 6px; border-radius:var(--r-pill,999px); vertical-align:middle; }
.gr-curve{ height:6px; border-radius:3px; background:rgb(var(--tint) / .06); overflow:hidden; }
.gr-curve i{ display:block; height:100%; background:var(--molten); border-radius:3px; box-shadow:0 0 10px rgb(var(--glow) / .5); transition:width 900ms var(--ease-out,ease); }
.gr-kv{ display:flex; justify-content:space-between; gap:8px; font:500 12px var(--font-mono); color:var(--ink2); white-space:nowrap; }
.gr-soon{ display:inline-flex; align-items:center; height:22px; padding:0 9px; border-radius:var(--r-pill,999px); font:600 10.5px/1 var(--font-mono); letter-spacing:.08em; text-transform:uppercase; color:var(--accent-text-strong); background:rgb(var(--glow) / .12); border:1px solid rgb(var(--glow) / .35); }

.gr-steps{ display:flex; gap:6px; overflow-x:auto; }
.gr-step{
  flex:1; min-width:110px; display:flex; flex-direction:column; gap:6px; cursor:pointer;
  border:0; background:transparent; padding:0; text-align:left; color:var(--ink3); font:600 10.5px var(--font-mono); letter-spacing:.1em; text-transform:uppercase;
}
.gr-step i{ height:4px; border-radius:2px; background:rgb(var(--tint) / .08); display:block; transition:background var(--t-med,.28s),box-shadow var(--t-med,.28s); }
.gr-step.done i{ background:var(--molten); box-shadow:0 0 10px rgb(var(--glow) / .45); }
.gr-step.cur{ color:var(--accent-text-strong); }
.gr-chains{ display:grid; grid-template-columns:repeat(5,minmax(0,1fr)); gap:8px; }
@media (max-width:767px){ .gr-chains{ grid-template-columns:repeat(2,minmax(0,1fr)); } }
.gr-chainbtn{
  height:64px; border-radius:var(--r-md,14px); border:1px solid var(--glass-edge-hi); background:var(--ink-2); cursor:pointer;
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:2px; color:var(--ink);
  transition:border-color var(--t-fast,.16s),background var(--t-fast,.16s),box-shadow var(--t-fast,.16s);
}
.gr-chainbtn b{ font:600 14px var(--font-display,var(--font-ui)); }
.gr-chainbtn span{ font:500 11px var(--font-mono); color:var(--ink3); }
@media (hover:hover){ .gr-chainbtn:hover{ border-color:rgb(var(--glow) / .4); } }
.gr-chainbtn[aria-pressed="true"]{ border-color:rgb(var(--glow) / .65); background:rgb(var(--glow) / .12); box-shadow:var(--glow-gold,0 0 24px rgb(var(--glow) / .25)); }
.gr-img{
  width:120px; height:120px; border-radius:var(--r-lg,20px); flex:none;
  background:var(--ink-2); border:1px dashed rgb(var(--glow) / .35);
  display:flex; align-items:center; justify-content:center; text-align:center;
  font:500 11px var(--font-mono); color:var(--ink3);
}
.gr-actions{ display:flex; gap:8px; justify-content:flex-end; flex-wrap:wrap; }
/* The wizard's footer (design): Back on s2, 700 14px, 20px sides; the
   primary 800 14px with 24px sides; both 48 tall, radius 12. */
.gr-actions .gr-btn{ height:48px; padding:0 26px; font:600 14.5px var(--font-display,var(--font-ui)); }
.gr-actions .gr-btn.ghost{ padding:0 22px; }

/* ── Auto Bot ─────────────────────────────────────────────────────────── */
.gr-bot{
  position:relative; border-radius:var(--r-lg,20px); padding:20px 22px; 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));
  display:flex; align-items:center; gap:16px; flex-wrap:wrap;
}
.gr-bot.is-on{ border-color:rgb(var(--up-rgb) / .45); box-shadow:var(--shadow-2),0 0 34px rgb(var(--up-rgb) / .12); }
.gr-mascot{ width:64px; height:64px; border-radius:50%; overflow:hidden; position:relative; flex:none; background:var(--ink-0); box-shadow:0 0 0 2px var(--ink-1),0 0 0 3px rgb(var(--glow) / .5),0 0 22px rgb(var(--glow) / .25); }
.gr-bot.is-on .gr-mascot{ box-shadow:0 0 0 2px var(--ink-1),0 0 0 3px var(--up),0 0 22px rgb(var(--up-rgb) / .35); }
/* app-ux.css caps every img at max-width:100%; the design crops this one at
   170% of its circle so the face fills it. */
.gr-mascot img{ position:absolute; width:170%; max-width:none; left:-35%; top:-18%; }
/* min-width 180 is the design's: at 390 the switch wraps under the text. */
.gr-bot-t{ display:flex; flex-direction:column; gap:4px; flex:1; min-width:180px; }
.gr-bot-t b{ font:700 20px var(--font-display,var(--font-ui)); letter-spacing:-.02em; color:var(--ink); }
.gr-bot-t span{ font:600 13px var(--font-mono); color:var(--ink2); }
.gr-bot.is-on .gr-bot-t span{ color:var(--up); }
.gr-stats{ display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:12px; }
@media (max-width:767px){ .gr-stats{ grid-template-columns:repeat(2,minmax(0,1fr)); } }
.gr-stat{ position:relative; border-radius:var(--r-lg,20px); padding:14px 16px; display:flex; flex-direction:column; gap:6px; min-width:0;
  background:linear-gradient(180deg,rgb(var(--raise) / .66),var(--glass)); border:1px solid var(--glass-edge); box-shadow:var(--shadow-2); }
.gr-stat span{ font:600 10px/1.2 var(--font-mono); letter-spacing:.14em; text-transform:uppercase; color:var(--ink3); }
.gr-stat b{ font:600 22px var(--font-mono); letter-spacing:-.02em; color:var(--ink); font-variant-numeric:tabular-nums; }
/* a signed tile figure takes its sign's colour (the bare .gr-up/.gr-dn lost to the rule above) */
.gr-stat b.gr-up{ color:var(--up); } .gr-stat b.gr-dn{ color:var(--dn); }
.gr-tiers{ padding:10px 16px 14px; border-top:1px solid rgb(var(--tint) / .05); display:flex; flex-direction:column; gap:8px; }
/* The tiered switch sits beside a 17px title without making that line any
   taller than the design draws it. */
.gr-tiers .gr-switch.sm{ margin:-5px 0; }
.gr-tier{ display:flex; align-items:center; gap:10px; font:500 13px var(--font-mono); color:var(--ink2); }
.gr-tier > span:first-child{ width:70px; flex:none; }
.gr-tier .gr-curve{ flex:1; }
.gr-tier .gr-curve i{ border-radius:0; }
.gr-tier > span:last-child{ color:var(--ink); white-space:nowrap; min-width:23ch; text-align:right; }
/* the tier lines state the whole rule now; on a phone they wrap instead of running off the card */
@media (max-width:640px){ .gr-tier{ flex-wrap:wrap; } .gr-tier > span:last-child{ white-space:normal; min-width:0; flex:1 1 100%; text-align:left; } }
.gr-ai{ background:var(--well); border:1px solid rgb(var(--tint) / .04); border-radius:var(--r-md,14px); padding:12px 14px; display:flex; flex-direction:column; gap:6px; }
.gr-ai b{ font:600 14px var(--font-display,var(--font-ui)); color:var(--ink); }
.gr-ai p{ margin:0; font:500 13.5px/1.5 var(--font-body,var(--font-ui)); color:var(--body); }
.gr-ai small{ font:500 11px var(--font-mono); color:var(--ink3); }
.gr-pos{ display:flex; align-items:center; gap:10px; padding:10px 16px; border-top:1px solid rgb(var(--tint) / .05); transition:background var(--t-fast,.16s); }
@media (hover:hover){ .gr-pos:hover{ background:rgb(var(--tint) / .03); } }
.gr-pos-s{ font:600 14.5px var(--font-display,var(--font-ui)); flex:1; min-width:0; color:var(--ink); }
.gr-pos-s span{ font:500 12px var(--font-mono); color:var(--ink3); }
.gr-pos-p{ font:600 13.5px var(--font-mono); }

@media (prefers-reduced-motion:no-preference){
  @keyframes gr-spin{ to{ transform:rotate(360deg); } }
  .gr-spin{ animation:gr-spin .8s linear infinite; }
}
@media (prefers-reduced-motion:reduce){
  .gr-switch,.gr-switch::after,.gr-primary,.gr-btn,.gr-launch,.gr-curve i,.gr-step i{ transition:none; }
}

/* ── touch targets ──────────────────────────────────────────────────────
 * Design §9: every control is at least 44px on touch. The design DRAWS these
 * at 26-40px, so on a touch screen the box grows to 44 with a transparent
 * border and the fill is clipped to the padding box: the control you see is
 * the size the design drew, the target a thumb hits is 44. Outer radius =
 * drawn radius + border, so the inner corners are unchanged. A switch's knob
 * is positioned against the padding box, so it does not move.
 */
@media (pointer: coarse), (any-pointer: coarse){
  /* The transparent border is matched by a negative margin of the same
     size, so the hit area grows and the LAYOUT box stays the drawn one: a
     56px row stays 56, a 36px switch still wraps where the design's does. */
  .gr-tab{ height:44px; border:5px solid transparent; margin:-5px; background-clip:padding-box; border-radius:14px; }
  .gr-tabs{ padding:3px; }
  .gr-seg button,.gr-seg-custom{ height:44px; border:6px solid transparent; margin:-6px; background-clip:padding-box; border-radius:14px; }
  .gr-seg{ padding:2px; }
  .gr-btn,.gr-dur{ height:44px; border:2px solid transparent; margin:-2px; background-clip:padding-box; border-radius:12px; }
  .gr-btn.outline{ border:1px solid rgb(var(--glow) / .45); margin:0; background-clip:border-box; }
  .gr-switch{ width:72px; height:44px; border:4px solid transparent; margin:-4px; background-clip:padding-box; border-radius:22px; }
  .gr-switch.sm{ width:54px; height:44px; border-width:9px 5px; margin:-9px -5px; border-radius:22px; }
  .gr-tiers .gr-switch.sm{ margin:-14px -5px; }
}

/* ── Auto Bot (templates/auto_trading_bot.html), 2026-10-13 ──────────────
 * The honest status strip, chain chips, the Noir segmented rows (.cf-tabs
 * on a 44px track -- the chosen pill is the molten indicator INSIDE the
 * track, never taller or wider than it), read-only facts with a caption,
 * the scanner card and the position sparks. Tokens only.
 */
.bt-strip{
  display:flex; align-items:center; gap:10px; flex-wrap:wrap; padding:12px 16px; min-height:52px;
  border-radius:var(--r-lg,20px); border:1px solid var(--glass-edge);
  background:linear-gradient(180deg,rgb(var(--raise) / .66),var(--glass)); box-shadow:var(--shadow-1);
  transition:border-color var(--t-med,.28s),box-shadow var(--t-med,.28s);
}
.bt-strip-text{ flex:1 1 240px; min-width:0; font:600 13px/1.45 var(--font-mono); color:var(--ink); overflow-wrap:anywhere; }
.bt-strip-age{ font:500 11px var(--font-mono); color:var(--ink3); font-variant-numeric:tabular-nums; min-width:5ch; }
.bt-strip-age:empty{ display:none; }
.bt-strip-act{ margin-left:auto; }
.bt-strip-act[hidden]{ display:none; }   /* .cf-btn's display beats the UA's [hidden] */
.bt-strip[data-state="ok"]{ border-color:rgb(var(--ion-rgb) / .35); box-shadow:var(--shadow-1),0 0 24px rgb(var(--ion-rgb) / .10); }
.bt-strip[data-state="blocked"]{ border-color:rgb(var(--dn-rgb) / .45); }
.bt-strip[data-state="blocked"] .bt-strip-text{ color:var(--dn); }
.bt-strip[data-state="stale"]{ border-color:rgb(var(--glow) / .4); }
.bt-strip[data-state="stale"] .bt-strip-text{ color:var(--accent-text-strong); }
.bt-strip[data-state="off"] .bt-strip-text{ color:var(--ink2); }
.bt-strip.cf-pulse{ animation:bt-strip-pulse 700ms var(--ease-out,ease); }
@keyframes bt-strip-pulse{ 0%{ box-shadow:0 0 0 0 rgb(var(--glow) / .35); } 100%{ box-shadow:0 0 0 12px rgb(var(--glow) / 0); } }

/* chain chips */
.bt-chains{ display:flex; align-items:center; gap:6px; flex-wrap:wrap; margin-top:4px; }
.bt-chains-list{ display:flex; flex-wrap:wrap; gap:6px; }
.bt-chains-n{ display:none; }
@media (max-width:767px){
  .bt-chains-n{ display:inline-flex; min-height:44px; padding:0 14px; }
  /* .cf-chip draws a fixed short height; this one is a phone tap target. */
  .bt-chains .bt-chains-n.cf-chip{ height:44px; min-width:44px; justify-content:center; }
  .bt-chains-list{ display:none; width:100%; }
  .bt-chains.is-open .bt-chains-list{ display:flex; }
}

/* rows: label (+ caption) · control */
.bt-row{ align-items:center; }
.bt-row .gr-row-l{ flex:1 1 160px; }
.bt-fact{
  display:inline-flex; align-items:center; height:32px; padding:0 12px; border-radius:var(--r-pill,999px);
  border:1px solid var(--glass-edge); background:rgb(var(--tint) / .04);
  font:600 12px var(--font-mono); color:var(--ink2); white-space:nowrap;
}
/* the Noir segmented control (cf-noir .cf-tabs): 36px tabs, 4px inset, the
   molten indicator slides under the pressed one and is clipped to the track */
.bt-seg{ flex:none; flex-wrap:nowrap; }
.bt-seg .cf-tab{ font-family:var(--font-mono); font-size:12.5px; padding:0 12px; }
.bt-seg .cf-tab[aria-pressed="true"]{ color:var(--on-molten); }
.bt-seg .cf-tab:focus-visible{ outline:none; box-shadow:var(--focus-ring); }
.bt-custom{ display:inline-flex; align-items:center; gap:1px; cursor:text; min-width:72px; justify-content:center; }
.bt-custom-l{ font:600 9px/1 var(--font-mono); letter-spacing:.12em; text-transform:uppercase; opacity:.8; margin-right:5px; }
.bt-custom input{
  /* the tab is 36px on a 44px track; the field's own box is the track's 44 */
  width:3.5ch; height:44px; margin:-4px 0; padding:0; border:0; outline:0; background:transparent; text-align:center;
  font:600 12.5px var(--font-mono); color:inherit; -moz-appearance:textfield;
}
.bt-custom input::-webkit-outer-spin-button,.bt-custom input::-webkit-inner-spin-button{ -webkit-appearance:none; margin:0; }
.bt-custom input::placeholder{ color:currentColor; opacity:.55; }
.bt-custom-pre,.bt-custom-suf{ display:none; font:600 12.5px var(--font-mono); }
.bt-custom.has-v .bt-custom-pre,.bt-custom.has-v .bt-custom-suf{ display:inline; }
.bt-custom.has-v input{ width:4.5ch; text-align:left; }
.bt-custom:focus-within{ box-shadow:var(--focus-ring); }
@media (max-width:767px){
  /* 390: label above, the track full width, four equal segments */
  .bt-row{ flex-direction:column; align-items:stretch; gap:8px; padding:12px 16px; }
  .bt-row .gr-row-l{ flex:none; min-width:0; }
  .bt-fact{ align-self:flex-start; }
  .bt-seg{ display:flex; width:100%; }
  .bt-seg .cf-tab{ flex:1 1 0; min-width:0; padding:0 6px; display:inline-flex; align-items:center; justify-content:center; }
  .bt-custom{ flex:1.25 1 0; min-width:0; }
  .bt-custom input{ font-size:16px; width:3ch; }
  .bt-custom.has-v input{ width:4ch; }
  .bt-custom-l{ margin-right:3px; }
  /* A typed value takes the room; the label would clip to "USTOM". */
  .bt-custom.has-v .bt-custom-l{ display:none; }
}

/* cards on the right */
.bt-card-h{ display:flex; align-items:baseline; justify-content:space-between; gap:10px; }
.bt-total{ font:600 15px var(--font-mono); font-variant-numeric:tabular-nums; }
.bt-total:empty{ display:none; }
.bt-scan-sum{ font:600 10.5px var(--font-mono); letter-spacing:.12em; text-transform:uppercase; color:var(--ink3); text-align:right; }
.bt-two{ align-items:stretch; }
#bt-scan-card{ flex:1 1 auto; }
.bt-scan{ flex:1 1 auto; min-height:110px; display:flex; flex-direction:column; }
.bt-scan .cf-chart-svg{ flex:1 1 auto; min-height:90px; }
.bt-scan .cf-chart-empty{ flex:1; }
.bt-skips{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:4px; }
.bt-skips[hidden]{ display:none; }
.bt-skips li{ display:flex; align-items:baseline; gap:8px; font:500 12px/1.4 var(--font-mono); color:var(--ink2); min-width:0; }
.bt-skip-n{ min-width:2ch; text-align:right; color:var(--ink); font-weight:600; font-variant-numeric:tabular-nums; }
.bt-skip-l{ flex:1; min-width:0; }
.bt-skip-s{ color:var(--ink3); white-space:nowrap; }
/* a reason opens its plain explanation in place (tap / Enter / hover title) */
.bt-skip-d{ flex:1; min-width:0; }
.bt-skip-d > summary{ display:flex; align-items:center; gap:8px; min-height:32px; cursor:pointer; list-style:none; border-radius:8px; }
.bt-skip-d > summary::-webkit-details-marker{ display:none; }
.bt-skip-d > summary:hover .bt-skip-l{ color:var(--ink); }
.bt-skip-d > summary:focus-visible{ outline:2px solid var(--acc); outline-offset:2px; }
.bt-skip-q{ font-style:normal; flex:none; width:18px; height:18px; border-radius:50%; border:1px solid var(--line); display:inline-grid; place-items:center; font:700 10px/1 var(--font-ui, inherit); color:var(--ink3); }
.bt-skip-d[open] .bt-skip-q{ background:var(--acc); border-color:var(--acc); color:var(--onAcc, var(--bg)); }
.bt-skip-x{ margin:2px 0 6px calc(2ch + 8px); font:500 12.5px/1.45 var(--font-ui, inherit); color:var(--ink2); white-space:normal; }
.bt-stats-note{ margin:-6px 0 0; font-size:12px; color:var(--ink3); }
/* closed bot trades: what happened to every exit */
.bt-closed{ display:flex; flex-direction:column; }
.bt-cl{ display:grid; grid-template-columns:minmax(0,1fr) auto; gap:2px 12px; padding:10px 16px; border-top:1px solid var(--line); }
.bt-cl:first-child{ border-top:0; }
.bt-cl-t{ font-weight:700; color:var(--ink); min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.bt-cl-p{ font:600 13px/1.3 var(--font-mono); text-align:right; font-variant-numeric:tabular-nums; }
.bt-cl-r{ grid-column:1 / -1; font-size:12.5px; color:var(--ink2); }
.bt-cl-r b{ color:var(--ink); font-weight:600; }
.bt-cl-f{ grid-column:1 / -1; font:500 11.5px/1.45 var(--font-mono); color:var(--ink3); overflow-wrap:anywhere; }
.cf-bar-live{ width:7px; height:7px; }

/* positions: a spark of the last hour, ticked live */
.bt-pos-spark{ position:relative; flex:none; width:72px; height:26px; }
.bt-pos-spark .cf-chart{ height:26px; }
@media (max-width:420px){ .bt-pos-spark{ width:52px; } }

/* tier bars enter from the left; the resting width is the real one */
.bt-grow{ transform-origin:left center; animation:bt-grow 700ms var(--ease-out,ease) var(--cf-delay,0ms) both; }
@keyframes bt-grow{ from{ transform:scaleX(0); } to{ transform:none; } }
@media (prefers-reduced-motion:reduce){
  .bt-grow,.bt-strip.cf-pulse{ animation:none; }
  .bt-strip{ transition:none; }
}


/* ---- static/cf-pages.css ---- */
/* Cartel Family — Syndicate Noir pieces the people and account pages share
 * (the behaviour is static/cf-pages.js). Every value is a token from
 * cf-theme.css; the components themselves are cf-noir.css.
 *
 *   .cf-noir-in        the Noir entrance: rise 16px + scale .985 + blur 4px
 *                      (added by script, removed on animationend)
 *   .cf-has-vault      an empty line with the engraved vault drawn above it
 *   .cf-page-head      title + right-hand actions, as /design/a/* draws it
 *   .cf-stat-row       the reference's mono figure row (dt caps / dd mono)
 *   .cf-rowlist        a list of person/token rows inside a glass panel
 */
@media (prefers-reduced-motion:no-preference){
  .cf-noir-in{ animation:cf-noir-rise var(--t-enter,600ms) var(--ease-out,cubic-bezier(.2,.75,.3,1)) both; }
  @keyframes cf-noir-rise{ from{ opacity:0; transform:translateY(16px) scale(.985); filter:blur(4px); } to{ opacity:1; transform:none; filter:none; } }
}

/* the vault above an empty line */
.cf-has-vault{ display:flex; flex-direction:column; align-items:center; justify-content:center; gap:10px; text-align:center; }
.cf-has-vault > .cf-vault{ width:54px; height:54px; flex:none; opacity:.9; }
.cf-noir-empty > span{ max-width:44ch; color:var(--ink3); font:500 12.5px/1.5 var(--font-body); }
.cf-noir-empty .cf-btn{ margin-top:6px; }

/* a page head: the title left, actions right */
.cf-page-head{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; }
.cf-page-head > .cf-tabs, .cf-page-head > .cf-page-acts{ margin-left:auto; }
.cf-page-acts{ display:flex; gap:8px; flex-wrap:wrap; align-items:center; }

/* the reference's figure row: caps label, mono figure */
.cf-stat-row{ display:flex; gap:22px; flex-wrap:wrap; margin:0; }
.cf-stat-row > div{ min-width:70px; }
.cf-stat-row dt{ font:600 10px/1 var(--font-mono); letter-spacing:.14em; text-transform:uppercase; color:var(--ink3); }
.cf-stat-row dd{ margin:6px 0 0; font:600 20px/1 var(--font-mono); font-variant-numeric:tabular-nums; color:var(--ink); }

/* rows inside a glass panel (traders, calls, referrals, notifications) */
.cf-rowlist{ display:grid; gap:2px; }
.cf-rowlist > *{ border-radius:var(--r-md); transition:background var(--t-fast); }
@media (hover:hover){ .cf-rowlist > *:hover{ background:rgb(var(--tint) / .03); } }

/* a figure well (stats inside a card) */
.cf-wells{ display:grid; grid-template-columns:repeat(auto-fit,minmax(120px,1fr)); gap:10px; }
.cf-wells > div{ padding:12px; border-radius:var(--r-md); background:var(--well); border:1px solid rgb(var(--tint) / .04); min-width:0; }
.cf-wells dt, .cf-wells span{ display:block; font:600 10px/1.2 var(--font-mono); letter-spacing:.12em; text-transform:uppercase; color:var(--ink3); }
.cf-wells dd, .cf-wells b{ display:block; margin:6px 0 0; font:600 18px/1.1 var(--font-mono); color:var(--ink); }

/* figures glow in their direction */
.cf-glow-up{ color:var(--up); text-shadow:0 0 14px rgb(var(--up-rgb) / .35); }
.cf-glow-dn{ color:var(--dn); text-shadow:0 0 14px rgb(var(--dn-rgb) / .35); }


/* ---- static/cf-launch.css ---- */
/* Token Launch -- the board, the wizard, and the token page's launch strip.
 *
 * Builds on cf-grow.css (the page frame, card, field, segmented control,
 * curve bar and wizard steps the design draws for §6.18) and adds only what
 * the live launchpad needs that the preview did not: a sort row, real launch
 * cards with Buy / Copy creator, a skeleton in the card's own shape, the
 * economics donuts, the quote table and the sign states.
 *
 * Every colour is a cf-theme.css token. Nothing rests at opacity:0: entrance
 * classes are added from script and removed when they end, and reduced
 * motion shows the finished state.
 */

.lp-wrap{ margin:0 auto; }
.lp-pane{ display:flex; flex-direction:column; gap:14px; min-width:0; }
.lp-pane[hidden]{ display:none; }

/* ── board ────────────────────────────────────────────────────────────── */
.lp-bar{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; }
.lp-sorts{ flex-wrap:nowrap; overflow-x:auto; max-width:100%; scrollbar-width:none; }
.lp-sorts::-webkit-scrollbar{ display:none; }
.lp-sorts button{ white-space:nowrap; font-family:var(--font-ui); padding:0 12px; }
.lp-live{ margin-left:auto; font:500 12px var(--font-num); color:var(--ink3); white-space:nowrap; }
.lp-live::before{ content:""; display:inline-block; width:6px; height:6px; border-radius:50%; background:var(--up); margin-right:6px; vertical-align:middle; }
.lp-live:empty{ display:none; }
.lp-chain-note{ margin:0; font:500 12px/1.5 var(--font-ui); color:var(--pro); }
.lp-chain-note[hidden]{ display:none; }

.lp-board{ display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:12px; }
@media (max-width:1180px){ .lp-board{ grid-template-columns:repeat(2,minmax(0,1fr)); } }
@media (max-width:640px){ .lp-board{ grid-template-columns:1fr; } }

.lp-card{ position:relative; }
.lp-card.lp-in{ animation:lp-rise .5s cubic-bezier(.2,.9,.25,1) both; }
.lp-top{ display:flex; align-items:flex-start; gap:10px; min-width:0; }
.lp-top .gr-tok-t{ min-width:0; }
.lp-top .gr-tok-t b{ display:flex; align-items:center; gap:6px; min-width:0; }
.lp-top .gr-tok-t b > span:first-child{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.lp-top .gr-tok-t > span{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.lp-top .gr-tok-t a{ color:var(--ink2); text-decoration:none; }
.lp-top .gr-tok-t a:hover{ color:var(--accT); }
.lp-mc{ margin-left:auto; display:flex; flex-direction:column; align-items:flex-end; gap:2px; flex:none; }
.lp-mc b{ font:600 13px var(--font-num); color:var(--ink); white-space:nowrap; }
.lp-mc span{ font:600 10px var(--font-ui); color:var(--ink3); letter-spacing:.06em; text-transform:uppercase; }
.lp-tok-link{ display:contents; color:inherit; text-decoration:none; }

.lp-curve{ position:relative; }
.lp-curve i{ width:0; transition:width .6s cubic-bezier(.2,.9,.25,1); }
.lp-curve.reading{ background:linear-gradient(90deg,var(--s2) 0%,var(--line) 50%,var(--s2) 100%); background-size:200% 100%; }
.lp-curve.grad i{ background:var(--up); }
.lp-reading{ font:500 12px var(--font-num); color:var(--ink3); }
.lp-kv{ display:flex; justify-content:space-between; gap:8px; font:500 12px var(--font-num); color:var(--ink2); flex-wrap:wrap; }
.lp-kv b{ color:var(--ink); font-weight:500; }

.lp-foot{ display:flex; align-items:center; gap:8px; margin-top:auto; flex-wrap:wrap; }
.lp-copyable{ font:700 12px var(--font-ui); color:var(--accT); flex:1; min-width:120px; }
.lp-copyable.mute{ color:var(--ink3); font-weight:600; }
.lp-foot .gr-btn{ height:40px; }
.lp-foot .gr-btn.outline{ padding:0 12px; }

/* Skeleton in the card's own shape; it is visible at rest (a grey card),
   and only shimmers when motion is allowed. */
.lp-sk{ min-height:170px; gap:12px; }
.lp-sk i{ display:block; height:14px; border-radius:7px; background:var(--s2); }
.lp-sk i:nth-child(1){ width:60%; height:44px; border-radius:22px; }
.lp-sk i:nth-child(2){ width:100%; height:8px; }
.lp-sk i:nth-child(3){ width:40%; margin-top:auto; height:40px; border-radius:10px; align-self:flex-end; }

.lp-status-card b{ font:800 16px var(--font-ui); color:var(--ink); }
.lp-status-card .gr-btn{ margin-top:4px; }

/* Recently graduated rows */
.lp-grow{ display:flex; align-items:center; gap:10px; padding:10px 16px; border-top:1px solid var(--line); min-height:52px; color:var(--ink); text-decoration:none; }
.lp-grow b{ font:800 14px var(--font-ui); }
.lp-grow span{ font:500 12px var(--font-ui); color:var(--ink2); flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.lp-grow em{ font:500 12px var(--font-num); color:var(--ink2); font-style:normal; white-space:nowrap; }
.lp-grow:hover{ background:var(--s2); }

/* ── wizard ───────────────────────────────────────────────────────────── */
.lp-soon{ display:flex; align-items:center; gap:10px 14px; flex-wrap:wrap; background:var(--proBg); border:1px solid var(--proLine); border-radius:12px; padding:12px 14px; font:500 13px/1.5 var(--font-ui); color:var(--ink); }
.lp-soon b{ font:800 14px var(--font-ui); }
.lp-soon span{ flex:1; min-width:220px; color:var(--ink2); }
.lp-soon[hidden]{ display:none; }
.lp-wiz{ gap:14px; }
.lp-step{ display:flex; flex-direction:column; gap:12px; min-width:0; }
.lp-step[hidden]{ display:none; }
.lp-step.lp-in{ animation:lp-fade .35s ease both; }
.lp-step-title{ outline:0; }

.lp-id{ display:flex; gap:14px; flex-wrap:wrap; }
.lp-img-col{ display:flex; flex-direction:column; gap:6px; }
.lp-img{ cursor:pointer; overflow:hidden; position:relative; padding:8px; }
.lp-img img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
.lp-img:focus-within,.lp-img:hover{ outline:2px solid var(--acc); outline-offset:2px; }
#lp-image:focus-visible + *{ outline:2px solid var(--acc); }
.lp-id-fields{ flex:1; min-width:220px; display:flex; flex-direction:column; gap:8px; }
.lp-text{ font-family:var(--font-ui); }
.lp-count{ font:500 11px var(--font-num); color:var(--ink3); font-style:normal; margin-left:6px; }
.lp-count.over{ color:var(--dn); }
.lp-ticker,.lp-sol{ position:relative; display:block; }
.lp-ticker i{ position:absolute; left:12px; top:50%; transform:translateY(-50%); font:700 14px var(--font-num); color:var(--ink3); font-style:normal; pointer-events:none; }
.lp-ticker input{ padding-left:26px; text-transform:uppercase; }
.lp-sol i{ position:absolute; right:12px; top:50%; transform:translateY(-50%); font:700 13px var(--font-num); color:var(--ink3); font-style:normal; pointer-events:none; }
.lp-sol input{ padding-right:52px; }
.lp-links{ display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:10px; }
@media (max-width:767px){ .lp-links{ grid-template-columns:1fr; } }

.lp-econ{ display:flex; flex-direction:column; gap:12px; }
.lp-econ-grid{ display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:12px; }
@media (max-width:767px){ .lp-econ-grid{ grid-template-columns:1fr; } }
.lp-panel{ background:var(--bg); border:1px solid var(--line); border-radius:12px; padding:12px; display:flex; flex-direction:column; gap:8px; min-width:0; }
.lp-panel h3{ margin:0; font:800 13px var(--font-ui); color:var(--ink); }
.lp-panel .cf-donut{ padding:4px 0; }
.lp-panel .cf-donut-svg{ width:140px; height:140px; }
/* the venue choice (Meteora | DEEP), step 2, and the DEEP tag on board cards */
.lp-venue-tag{ color:var(--accT, var(--acc)); }
.lp-venues{ display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:10px; margin-bottom:14px; }
@media (max-width:520px){ .lp-venues{ grid-template-columns:1fr; } }
.lp-venue{ display:flex; flex-direction:column; gap:4px; text-align:left; min-height:44px; padding:12px 14px; border-radius:12px;
  border:1px solid var(--line); background:var(--bg); color:var(--ink); font:500 12px/1.4 var(--font-ui); cursor:pointer;
  transition:border-color .2s ease, box-shadow .2s ease; }
.lp-venue b{ font:800 14px var(--font-ui); display:flex; align-items:center; gap:6px; }
.lp-venue span{ color:var(--ink2); }
.lp-venue[aria-checked="true"]{ border-color:var(--acc); box-shadow:0 0 0 1px var(--acc) inset; }
.lp-venue[disabled]{ opacity:.55; cursor:not-allowed; }
.lp-venue:focus-visible{ outline:2px solid var(--acc); outline-offset:2px; }
.lp-presets{ display:flex; flex-wrap:wrap; gap:6px; }
.lp-presets button{ min-height:44px; min-width:56px; padding:0 12px; border-radius:10px; border:1px solid var(--line);
  background:var(--bg); color:var(--ink); font:700 13px var(--font-num); cursor:pointer; }
.lp-presets button[aria-pressed="true"]{ background:var(--ink); color:var(--bg); border-color:var(--ink); }
.lp-presets button:focus-visible{ outline:2px solid var(--acc); outline-offset:2px; }
@media (prefers-reduced-motion: reduce){ .lp-venue{ transition:none; } }
.lp-fixed{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; font:600 13px var(--font-ui); color:var(--ink); }
.lp-fixed .gr-pill{ font-family:var(--font-num); }

.lp-amt{ display:flex; align-items:flex-end; gap:12px; flex-wrap:wrap; }
.lp-amt-field{ flex:1; min-width:180px; max-width:260px; }
.lp-presets button{ font-family:var(--font-num); }
.lp-quote > div > span:last-child{ word-break:normal; }
.lp-quote.stale{ opacity:.7; }
.lp-bal{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; font:500 13px var(--font-num); color:var(--ink2); }
.lp-bal:empty{ display:none; }
.lp-bal .ok{ color:var(--up); font-weight:700; font-family:var(--font-ui); }
.lp-bal .no{ color:var(--dn); font-weight:700; font-family:var(--font-ui); }

.lp-review{ display:flex; flex-direction:column; gap:12px; }
.lp-rev-head{ display:flex; align-items:center; gap:12px; min-width:0; }
.lp-rev-head .gr-tok-av{ width:56px; height:56px; line-height:56px; font-size:18px; }
.lp-rev-head div{ min-width:0; }
.lp-rev-head b{ display:block; font:800 18px var(--font-ui); color:var(--ink); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.lp-rev-head span{ font:500 13px var(--font-ui); color:var(--ink2); }
.lp-launch-btn{ margin-top:2px; }
.lp-outcome{ display:flex; flex-direction:column; gap:10px; }
.lp-done{ flex-direction:column; align-items:flex-start; }
.lp-done dl{ margin:0; display:grid; grid-template-columns:auto minmax(0,1fr); gap:4px 12px; font:500 12px var(--font-num); color:var(--ink2); width:100%; }
.lp-done dd{ margin:0; color:var(--ink); word-break:break-all; }
.lp-row-btns{ display:flex; gap:8px; flex-wrap:wrap; }
.lp-fail{ flex-direction:column; align-items:flex-start; }
.lp-fail a{ color:var(--accT); }

/* ── token page strip ─────────────────────────────────────────────────── */
.lp-strip{ display:flex; flex-direction:column; gap:10px; padding:14px 16px; }
.lp-strip[hidden]{ display:none; }
.lp-strip-h{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; font:800 14px var(--font-ui); color:var(--ink); }
.lp-strip-h .gr-pill{ margin-left:auto; }
.lp-strip-h a{ color:var(--accT); text-decoration:none; font-weight:700; }
.lp-strip-fees{ display:flex; align-items:center; gap:10px; flex-wrap:wrap; border-top:1px solid var(--line); padding-top:10px; font:500 13px var(--font-num); color:var(--ink2); }
.lp-strip-fees b{ color:var(--ink); font-weight:600; }
.lp-strip-fees .gr-btn{ margin-left:auto; }
.lp-strip-msg{ margin:0; font:600 12px/1.45 var(--font-ui); }
.lp-strip-msg.ok{ color:var(--up); } .lp-strip-msg.bad{ color:var(--dn); }
.lp-strip-msg:empty{ display:none; }
.lp-strip-msg a{ color:var(--accT); }

/* ── motion ───────────────────────────────────────────────────────────── */
@keyframes lp-rise{ from{ transform:translateY(10px); } to{ transform:none; } }
@keyframes lp-fade{ from{ transform:translateY(4px); } to{ transform:none; } }
@keyframes lp-shim{ from{ background-position:200% 0; } to{ background-position:-200% 0; } }
@media (prefers-reduced-motion:no-preference){
  .lp-curve.reading,.lp-sk i{ animation:lp-shim 1.4s linear infinite; background-image:linear-gradient(90deg,var(--s2) 0%,var(--line) 50%,var(--s2) 100%); background-size:200% 100%; }
}
@media (prefers-reduced-motion:reduce){
  .lp-card.lp-in,.lp-step.lp-in{ animation:none; }
  .lp-curve i{ transition:none; }
}

/* ── touch ────────────────────────────────────────────────────────────── */
@media (pointer: coarse), (any-pointer: coarse){
  .lp-foot .gr-btn{ height:44px; }
  .gr-step{ min-height:44px; justify-content:center; }
  .lp-grow{ min-height:52px; }
  .lp-strip-h a{ display:inline-flex; align-items:center; min-height:44px; }
}

/* `hidden` must win over the buttons' and panels' own display. */
.lp-wiz [hidden],.lp-pane [hidden]{ display:none !important; }

/* Receipts inside the wizard: a value breaks between words, never inside
   "425.00 SOL" (cf-grow's .gr-sum breaks anywhere, for wallet addresses). */
.lp-wiz .gr-sum > div > span:first-child{ flex:0 1 auto; min-width:0; }
.lp-wiz .gr-sum > div > span:last-child{ word-break:normal; overflow-wrap:break-word; min-width:0; }
.lp-done dd{ word-break:break-all; }

/* Steps on a phone: every bar keeps its slot, only the current step names
   itself, so five steps fit 320px without a sideways scroll. */
@media (max-width:640px){
  .lp-steps{ overflow:visible; gap:4px; }
  .lp-steps .gr-step{ min-width:44px; flex:1; }   /* six 44px targets fit 320px with 4px gaps */
  .lp-steps .gr-step.cur{ flex:2; }
  .lp-steps .gr-step:not(.cur) .lp-step-l{ display:none; }
}
@media (max-width:360px){ .lp-steps .gr-step .lp-step-l{ display:none; } }   /* the title under the bar names the step */
/* The board's chain filter is a finger target on touch widths like the chips beside it. */
@media (max-width:1024px){ .lp-chains-bar .cf-chip{ min-height:44px; } }

/* The step's number and its name sit on one line under the bar. */
.lp-steps .gr-step{ flex-direction:row; flex-wrap:wrap; align-content:flex-start; column-gap:0; }
.lp-steps .gr-step i{ flex-basis:100%; }

/* ── where it launches (chain-first, 2026-10-13) ─────────────────────────── */
.lp-chains{ display:flex; gap:8px; flex-wrap:wrap; margin:4px 0 12px; }
.lp-chains-bar{ margin:0; }
.lp-chain{ display:inline-flex; align-items:center; gap:8px; min-height:44px; padding:8px 14px; }
.lp-chain small{ font:600 11px var(--font-num); color:var(--ink3); letter-spacing:.04em; }
.lp-chain[aria-checked="true"],.lp-chains-bar .cf-chip[aria-pressed="true"]{ color:var(--accent-text-strong, var(--accT)); border-color:rgb(var(--glow) / .55); background:rgb(var(--glow) / .2); box-shadow:var(--glow-gold, none); }
.lp-chain[aria-disabled="true"]{ opacity:.6; }   /* closed, still readable: a tap shows that chain's terms and the "not open" reason */
.lp-chain:focus-visible,.lp-chains-bar .cf-chip:focus-visible{ outline:2px solid var(--acc); outline-offset:2px; }
.lp-launchable{ margin:-6px 0 0; font:500 12px/1.5 var(--font-ui); color:var(--ink3); }
.lp-launchable:empty{ display:none; }
@media (min-width:1100px){ .lp-venues{ grid-template-columns:repeat(3,minmax(0,1fr)); } .lp-venues:has(> :nth-child(2):last-child){ grid-template-columns:minmax(0,1fr) minmax(0,1fr); } }
.lp-venue.cf-card{ padding:12px 14px; }
.lp-venue[aria-disabled="true"]{ opacity:.6; cursor:not-allowed; }
.lp-venue-why{ color:var(--pro); font:600 12px var(--font-ui); }
.lp-remembered{ color:var(--ink3); font:500 12px var(--font-ui); }
.lp-dc-presets,.lp-dc-caps,.lp-dc-tax,.lp-dc-days{ flex-wrap:wrap; }
.lp-dc-presets button,.lp-dc-caps button,.lp-dc-tax button,.lp-dc-days button{ min-height:40px; font-family:var(--font-ui); padding:0 12px; }
.lp-dc-days{ margin-top:8px; }
.lp-bal .gr-btn{ height:36px; }
@media (max-width:420px){ .lp-chain{ padding:8px 10px; } .lp-chain small{ display:none; } .lp-chain[aria-disabled="true"] small{ display:inline; } }
@media (prefers-reduced-motion: reduce){ .lp-chain,.lp-venue{ transition:none; } }

/* Brand marks beside chain and launchpad names (brand_logos.py + cf-brand.js, 2026-10-13). Fixed boxes, no shift; the dot only where no mark exists. */
.lp-chain .cf-logo{width:16px;height:16px;margin-left:0}
.lp-chains-bar .cf-chip .cf-logo{width:14px;height:14px}
.lp-venue b .cf-logo{width:20px;height:20px;border-radius:5px}
.gr-chain .cf-logo{width:12px;height:12px;margin-right:3px;vertical-align:-2px;border-radius:2px}

.lp-strip-soc{ display:flex; gap:14px; flex-wrap:wrap; }
.lp-strip-soc a{ display:inline-flex; align-items:center; min-height:44px; color:var(--accT); font:600 13px var(--font-ui); text-decoration:none; }


/* ---- static/cf-launch-form.css ---- */
/* The one-screen token launch form (cf-launch-form.js).
 *
 * Built from the Noir components (cf-btn, cf-chip, cf-input, cf-card, cf-sheet)
 * and tokens only: no hex, no per-venue styling. The same markup mounts in a
 * page pane (/launch) and in the in-place sheet, and the Mini App and phone
 * app draw the same order: logo + name + ticker, one line, socials, where,
 * first buy, cost, advanced, ONE button.
 *
 * Nothing rests invisible; entrances are classes script adds and removes;
 * reduced motion shows the finished state.
 */

.lf-host{ container-type:inline-size; width:100%; box-sizing:border-box; }
.lf,.lf [data-lf-form]{ display:flex; flex-direction:column; gap:22px; min-width:0; color:var(--ink); font-family:var(--font-ui); }
.lf[hidden],.lf [hidden]{ display:none !important; }
.lf-sec{ display:flex; flex-direction:column; gap:10px; min-width:0; }
.lf-h{ margin:0; font:600 var(--fs-micro,11px)/1.2 var(--font-mono,var(--font-num)); letter-spacing:var(--tr-caps,.16em); text-transform:uppercase; color:var(--ink3); }
.lf-note{ margin:0; font:500 12.5px/1.5 var(--font-ui); color:var(--ink2); }
.lf-err{ margin:0; font:600 12px/1.4 var(--font-ui); color:var(--dn); }
.lf-err:empty{ display:none; }

.lf-sr{ position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; }
.lf-optag{ text-transform:none; letter-spacing:0; font-weight:500; }
.lf-err-wide{ grid-column:1 / -1; }
.lf-h-opt{ margin:0; }
.lf-usd{ color:var(--ink3); }
.lf-tok-t{ min-width:0; }
.lf-done-h{ font:800 17px var(--font-ui); }
.lf-done-p{ margin-top:4px; }

/* ── identity: logo + name + ticker ───────────────────────────────────── */
.lf-id{ display:grid; grid-template-columns:96px minmax(0,1fr); gap:14px; align-items:start; }
.lf-logo{ position:relative; box-sizing:border-box; width:96px; height:96px; border-radius:var(--r-lg,18px); overflow:hidden; cursor:pointer;
  background:var(--well,var(--s2)); border:1.5px dashed var(--glass-edge-hi,var(--line)); display:flex; align-items:center; justify-content:center;
  text-align:center; color:var(--ink2); font:600 11px/1.3 var(--font-ui); padding:6px; transition:border-color .2s ease, background .2s ease; }
.lf-logo:hover,.lf-logo.is-over,.lf-logo:focus-within{ border-color:var(--gold-400,var(--acc)); background:rgb(var(--glow,var(--tint)) / .08); }
.lf-logo:focus-within{ box-shadow:0 0 0 3px rgb(var(--glow,var(--tint)) / .2); }
.lf-logo.has{ border-style:solid; padding:0; }
.lf-logo img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
.lf-logo svg{ width:26px; height:26px; display:block; margin:0 auto 4px; color:var(--accT,var(--acc)); }
.lf-logo input[type=file]{ position:absolute; inset:0; opacity:.001; width:100%; height:100%; cursor:pointer; font-size:0; }   /* the label is the control; focus ring above */
.lf-logo-tools{ grid-column:1 / -1; display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin-top:-4px; }
.lf-linkbtn{ min-height:44px; padding:0 4px; border:0; background:none; color:var(--accT,var(--acc)); font:600 13px var(--font-ui); cursor:pointer; text-decoration:underline; text-underline-offset:3px; }
.lf-linkbtn:focus-visible{ outline:2px solid var(--acc); outline-offset:2px; border-radius:6px; }
.lf-url{ display:flex; gap:8px; flex:1; min-width:200px; }
.lf-url .cf-input{ flex:1; min-width:0; }
.lf-fields{ display:flex; flex-direction:column; gap:10px; min-width:0; }
.lf-field{ display:flex; flex-direction:column; gap:6px; min-width:0; }
.lf-field > label,.lf-field > .lf-lab{ display:flex; justify-content:space-between; gap:8px; font:600 var(--fs-micro,11px)/1.2 var(--font-mono,var(--font-num)); letter-spacing:var(--tr-caps,.16em); text-transform:uppercase; color:var(--ink3); }
.lf-count{ font:500 11px var(--font-num); letter-spacing:0; text-transform:none; color:var(--ink3); font-style:normal; }
.lf-count.over{ color:var(--dn); }
.lf .cf-input{ width:100%; box-sizing:border-box; min-height:46px; font-size:16px; }   /* 16px: iOS does not zoom on focus */
.lf-ticker,.lf-amt-box{ position:relative; display:block; }
.lf-ticker i{ position:absolute; left:14px; top:50%; transform:translateY(-50%); font:700 15px var(--font-num); color:var(--ink3); font-style:normal; pointer-events:none; }
.lf-ticker .cf-input{ padding-left:30px; text-transform:uppercase; font-family:var(--font-num); letter-spacing:.04em; }
.lf-desc .cf-input{ resize:none; min-height:46px; padding-top:12px; line-height:1.4; }

/* ── socials ──────────────────────────────────────────────────────────── */
.lf-socials{ display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:10px; }
.lf-soc:last-child{ grid-column:1 / -1; }
.lf-soc{ position:relative; display:block; }
.lf-soc svg{ position:absolute; left:13px; top:50%; transform:translateY(-50%); width:18px; height:18px; color:var(--ink3); pointer-events:none; }
.lf-soc .cf-input{ padding-left:40px; }
.lf-soc:focus-within svg{ color:var(--accT,var(--acc)); }

/* ── where: chain chips, venue chips ──────────────────────────────────── */
.lf-chips{ display:flex; flex-wrap:wrap; gap:8px; }
.lf-chips .cf-chip{ min-height:44px; padding:0 14px; gap:8px; cursor:pointer; font-size:13px; }
.lf-chips .cf-chip[aria-checked="true"]{ color:var(--accent-text-strong,var(--accT)); border-color:rgb(var(--glow) / .55); background:rgb(var(--glow) / .18); box-shadow:0 0 0 1px rgb(var(--glow) / .35) inset; }
.lf-chips .cf-chip[aria-disabled="true"]{ opacity:.55; }
.lf-chips .cf-chip:focus-visible{ outline:2px solid var(--acc); outline-offset:2px; }
.lf-chips .cf-chip .cf-logo{ width:18px; height:18px; margin-left:0; }
.lf-venue-why{ margin:0; font:600 12px/1.4 var(--font-ui); color:var(--pro,var(--ink2)); }
.lf-sum{ margin:0; padding:0; list-style:none; display:flex; flex-direction:column; gap:4px; font:500 12.5px/1.45 var(--font-ui); color:var(--ink2); }
.lf-sum li::before{ content:""; display:inline-block; width:5px; height:5px; margin:0 8px 2px 0; border-radius:50%; background:var(--acc); opacity:.7; }

/* ── first buy ────────────────────────────────────────────────────────── */
.lf-amt-box .cf-input{ padding-right:64px; font-family:var(--font-num); font-weight:600; }
.lf-amt-box i{ position:absolute; right:14px; top:50%; transform:translateY(-50%); font:700 13px var(--font-num); color:var(--ink3); font-style:normal; pointer-events:none; }
.lf-presets{ display:flex; flex-wrap:wrap; gap:8px; }
.lf-presets button{ min-height:44px; min-width:56px; padding:0 14px; border-radius:var(--r-pill,999px); border:1px solid var(--glass-edge,var(--line)); background:var(--ink-2,var(--s2));
  color:var(--ink); font:700 13px var(--font-num); cursor:pointer; transition:background .15s ease, color .15s ease; }
.lf-presets button[aria-pressed="true"]{ background:var(--molten,var(--acc)); color:var(--on-molten,var(--onAcc)); border-color:transparent; }
.lf-presets button:disabled{ opacity:.45; cursor:default; }
.lf-presets button:focus-visible{ outline:2px solid var(--acc); outline-offset:2px; }
.lf-avail{ display:flex; flex-wrap:wrap; align-items:center; gap:4px 10px; font:500 12.5px var(--font-num); color:var(--ink2); }
.lf-avail b{ color:var(--ink); font-weight:600; }
.lf-avail .lf-addr{ color:var(--ink3); }

/* ── cost ─────────────────────────────────────────────────────────────── */
.lf-cost{ display:flex; flex-direction:column; gap:7px; padding:14px; border-radius:var(--r-md,12px); background:var(--well,var(--s2)); border:1px solid rgb(var(--tint) / .06); font:500 13px/1.4 var(--font-ui); }
.lf-cost.is-stale{ opacity:.7; }
.lf-cost > div{ display:flex; justify-content:space-between; gap:12px; color:var(--ink2); }
.lf-cost > div > span:last-child{ color:var(--ink); text-align:right; font-family:var(--font-num); white-space:normal; overflow-wrap:anywhere; }
.lf-cost > div.is-incl{ opacity:.75; font-size:12px; }
.lf-cost > div.is-total{ margin-top:2px; padding-top:9px; border-top:1px dashed var(--glass-edge,var(--line)); font-weight:700; color:var(--ink); }
.lf-cost > div.is-total > span:last-child{ color:var(--accent-text-strong,var(--accT)); }
.lf-cost .lf-from{ display:block; margin-top:2px; font:500 12px var(--font-ui); color:var(--ink3); }
.lf-cost-empty{ color:var(--ink3); font:500 13px/1.45 var(--font-ui); }
.lf-bal{ display:flex; flex-wrap:wrap; align-items:center; gap:6px 10px; font:600 12.5px var(--font-ui); }
.lf-bal.ok{ color:var(--up); } .lf-bal.no{ color:var(--dn); }
.lf-bal span{ font-family:var(--font-num); font-weight:500; color:var(--ink2); }

/* ── advanced ─────────────────────────────────────────────────────────── */
.lf-adv{ border-radius:var(--r-md,12px); border:1px solid var(--glass-edge,var(--line)); background:rgb(var(--tint) / .02); }
.lf-adv > summary{ list-style:none; cursor:pointer; min-height:48px; padding:0 14px; display:flex; align-items:center; justify-content:space-between; gap:8px; font:700 13px var(--font-ui); color:var(--ink); }
.lf-adv > summary::-webkit-details-marker{ display:none; }
.lf-adv > summary::after{ content:""; width:8px; height:8px; border-right:2px solid var(--ink3); border-bottom:2px solid var(--ink3); transform:rotate(45deg); transition:transform .2s ease; margin-right:4px; }
.lf-adv[open] > summary::after{ transform:rotate(-135deg); }
.lf-adv > summary small{ font:500 12px var(--font-ui); color:var(--ink3); margin-left:auto; }
.lf-adv > summary:focus-visible{ outline:2px solid var(--acc); outline-offset:-2px; border-radius:var(--r-md,12px); }
.lf-adv-body{ display:flex; flex-direction:column; gap:16px; padding:2px 14px 14px; }
.lf-opt{ display:flex; flex-direction:column; gap:8px; }
.lf-opt .lf-presets button{ font-family:var(--font-ui); }

/* ── the one button, confirm, progress, result ────────────────────────── */
.lf-go{ display:flex; flex-direction:column; gap:10px; }
.lf-go .cf-btn{ width:100%; min-height:54px; font-size:16px; }
.lf-go-note{ margin:0; text-align:center; font:500 12px/1.5 var(--font-ui); color:var(--ink3); }
.lf-confirm,.lf-busy,.lf-done,.lf-fail{ display:flex; flex-direction:column; gap:14px; }
.lf-tok{ display:flex; align-items:center; gap:12px; min-width:0; }
.lf-tok-av{ flex:none; width:56px; height:56px; border-radius:16px; overflow:hidden; background:var(--well,var(--s2)); display:flex; align-items:center; justify-content:center; font:800 20px var(--font-ui); color:var(--ink2); }
.lf-tok-av img{ width:100%; height:100%; object-fit:cover; display:block; }
.lf-tok b{ display:block; font:800 18px/1.2 var(--font-ui); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.lf-tok span{ font:500 13px var(--font-ui); color:var(--ink2); display:inline-flex; align-items:center; gap:6px; flex-wrap:wrap; }
.lf-tok span .cf-logo{ width:14px; height:14px; }
.lf-row{ display:flex; gap:10px; flex-wrap:wrap; }
.lf-row .cf-btn{ flex:1 1 140px; min-height:48px; }
.lf-steps{ display:flex; flex-direction:column; gap:10px; margin:0; padding:0; list-style:none; }
.lf-steps li{ display:flex; align-items:center; gap:10px; font:600 14px var(--font-ui); color:var(--ink3); min-height:28px; }
.lf-steps li i{ flex:none; width:22px; height:22px; border-radius:50%; border:2px solid var(--glass-edge-hi,var(--line)); display:flex; align-items:center; justify-content:center; font-style:normal; font-size:12px; }
.lf-steps li.is-now{ color:var(--ink); }
.lf-steps li.is-now i{ border-color:var(--acc); border-top-color:transparent; }
.lf-steps li.is-done{ color:var(--up); }
.lf-steps li.is-done i{ background:var(--up); border-color:var(--up); color:var(--bg); }
.lf-steps li.is-done i::before{ content:"\2713"; font-weight:800; }
.lf-fail-box{ padding:14px; border-radius:var(--r-md,12px); background:var(--dn-dim,var(--s2)); border:1px solid rgb(var(--dn-rgb,255 80 80) / .35); display:flex; flex-direction:column; gap:6px; }
.lf-fail-box b{ color:var(--dn); font:800 15px var(--font-ui); }
.lf-fail-box span{ font:500 13px/1.5 var(--font-ui); color:var(--ink); overflow-wrap:anywhere; }
.lf-fail-box a{ color:var(--accT,var(--acc)); }
.lf-addr-row{ display:flex; align-items:center; gap:8px; padding:10px 12px; border-radius:var(--r-md,12px); background:var(--well,var(--s2)); font:500 12px var(--font-num); color:var(--ink2); min-width:0; }
.lf-addr-row code{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font:inherit; color:var(--ink); }
.lf-addr-row button{ flex:none; min-height:44px; padding:0 12px; border:0; border-radius:10px; background:rgb(var(--tint) / .06); color:var(--ink); font:700 12px var(--font-ui); cursor:pointer; }
.lf-addr-row button:focus-visible{ outline:2px solid var(--acc); outline-offset:2px; }
.lf-spin{ width:18px; height:18px; border-radius:50%; border:2px solid var(--glass-edge-hi,var(--line)); border-top-color:var(--acc); display:inline-block; vertical-align:-3px; }

@media (prefers-reduced-motion:no-preference){
  .lf-steps li.is-now i,.lf-spin{ animation:lf-spin .9s linear infinite; }
  .lf-in{ animation:lf-rise .35s cubic-bezier(.2,.9,.25,1) both; }
}
@keyframes lf-spin{ to{ transform:rotate(360deg); } }
@keyframes lf-rise{ from{ transform:translateY(8px); } to{ transform:none; } }
@media (prefers-reduced-motion:reduce){ .lf-logo,.lf-adv > summary::after,.lf-presets button{ transition:none; } }

/* ── page pane: the form in a card ────────────────────────────────────── */
.lf-page{ width:100%; box-sizing:border-box; max-width:640px; margin:0 auto; padding:var(--sp-5,20px); border-radius:var(--r-xl,22px); background:linear-gradient(180deg,var(--sheet-hi,var(--s1)),var(--sheet-lo,var(--s1))); border:1px solid var(--glass-edge-hi,var(--line)); box-shadow:var(--shadow-2,none); }

/* ── the in-place sheet ───────────────────────────────────────────────── */
.lf-sheet{ display:flex; flex-direction:column; }
.lf-sheet-top{ display:flex; align-items:center; gap:10px; margin:0 0 14px; }
.lf-sheet-top h2{ margin:0; flex:1; font:700 22px/1.2 var(--font-display,var(--font-ui)); letter-spacing:-.02em; }
.lf-x{ flex:none; width:44px; height:44px; border-radius:50%; border:1px solid var(--glass-edge,var(--line)); background:var(--ink-2,var(--s2)); color:var(--ink); font:600 18px/1 var(--font-ui); cursor:pointer; }
.lf-x:focus-visible{ outline:2px solid var(--acc); outline-offset:2px; }
/* Leave a real band of scrim above the sheet on phones: at 94vh the app's top bar
   covered the only scrim left, so tapping outside could not close it (390, 2026-10-14). */
.cf-sheet.lf-sheet{ max-height:calc(100dvh - 120px); }
@media (min-width:900px){ .cf-sheet.lf-sheet{ width:480px; max-height:none; } }

@media (max-width:640px){
  .lf-page{ padding:16px; border-radius:var(--r-lg,18px); }
}
@container (max-width:430px){ .lf-socials{ grid-template-columns:1fr; } }
@media (max-width:360px){ .lf-id{ grid-template-columns:80px minmax(0,1fr); gap:10px; } .lf-logo{ width:80px; height:80px; } }


/* ---- static/cf-signin-methods.css ---- */
/* Get-started sheet: the passkey, EVM-wallet, password and "secure your
   sign-in" screens added by wallet-onboarding.js. Tokens only (cf-theme.css);
   a literal colour works in one theme and breaks the other. Injected by
   passkeys.py beside cf-passkey.js. */
.oa-ob-modal .oa-ob-remember{margin:14px 0 4px;justify-content:center}
.oa-ob-modal .oa-ob-pk{display:flex;flex-direction:column;gap:10px}
.oa-ob-modal .oa-ob-pk-lead{margin:0;font:600 14px/1.45 var(--font-ui);color:var(--ink)}
.oa-ob-modal .oa-ob-pk-lead[data-kind="bad"]{color:var(--dn)}
.oa-ob-modal .oa-ob-pk-note{margin:0;font:500 12.5px/1.5 var(--font-ui);color:var(--ink2)}
.oa-ob-modal .oa-ob-pk-note b{color:var(--ink);font-weight:700}
.oa-ob-modal .oa-ob-secure{display:flex;flex-direction:column;gap:12px}
.oa-ob-modal .oa-ob-secure .oa-ob-method[disabled]{opacity:.55;cursor:not-allowed}
.oa-ob-modal .oa-ob-mnote[data-kind="good"]{color:var(--up)}
.oa-ob-modal .oa-ob-mnote[data-kind="bad"]{color:var(--dn)}
.oa-ob-modal .oa-ob-secure-pw{display:flex;flex-direction:column;gap:8px}
.oa-ob-modal .oa-ob-secure-pw[hidden]{display:none}
.oa-ob-modal .oa-ob-inline-btn{
  align-self:flex-start;min-height:44px;padding:0 16px;border-radius:10px;border:1px solid var(--line);
  background:var(--acc);color:var(--onAcc);font:700 13px var(--font-ui);cursor:pointer}
.oa-ob-modal .oa-ob-inline-btn:disabled{opacity:.6;cursor:progress}


/* ---- static/cf-modal.css ---- */
/* Cartel Family — the one modal / dialog / bottom-sheet surface.
 *
 * CLAUDE.md, "Design system": *one* set of modals and sheets. Before this file
 * the app had `.s-modal` duplicated verbatim into six templates (each with a
 * slightly different `.s-title`), a bespoke `.oa-ob-*` shell for wallet
 * onboarding, `.gd-modal-*`, `.w-modal-*`, `.lm-token-modal`, `.pt-sheet-*`
 * and more — none of which agreed on padding, radius, close-button position,
 * focus handling or where an error message goes.
 *
 * Shape follows static/cf-trade-sheet.js, which already got this right:
 * centred dialog from 768px up, bottom sheet below it, same scrim, same
 * swipe-to-dismiss, same reduced-motion behaviour. This is that behaviour
 * generalised, not a second system next to it.
 *
 * COLOURS: tokens from cf-theme.css only. A literal works in one theme and
 * breaks the other (`.pt-nb-more-item{color:#c7ccd4}` was legible on dark and
 * nearly invisible on light). The one colour defined here is --cf-scrim,
 * because cf-theme.css ships no scrim token — and it is declared for BOTH
 * themes below, in all three of the theme states cf-theme.css defines
 * (system / forced light / forced dark), so it cannot have that bug.
 */

:root{
  --cf-scrim:rgba(3,8,14,.74);
  --cf-modal-shadow:0 24px 64px rgba(0,0,0,.55);
}
:root[data-theme="light"] body.cf-themable,
html:not([data-theme]) body.cf-themable.cf-light{
  --cf-scrim:rgba(11,20,32,.44);
  --cf-modal-shadow:0 18px 48px rgba(11,20,32,.18);
}
@media (prefers-color-scheme: light){
  :root:not([data-theme]) body.cf-themable{
    --cf-scrim:rgba(11,20,32,.44);
    --cf-modal-shadow:0 18px 48px rgba(11,20,32,.18);
  }
}

/* ── layer ──────────────────────────────────────────────────────────────
 * One layer per open modal. Stacking (a modal opened from a modal) is just
 * another layer at a higher z-index; nothing about the scroll lock or the
 * focus trap is per-instance state that a second instance could corrupt.
 * Above cf-trade-sheet (9001) and above app-ux.css's forced 1500 for the
 * legacy shells, so a confirm raised from either one is never buried.
 */
.cf-modal-layer{
  position:fixed;inset:0;z-index:9400;
  display:flex;align-items:center;justify-content:center;
  /* Safe-area aware, so a dialog never sits under a notch or a home
     indicator. The side gutter stays 16px at every width. */
  padding:calc(var(--space-md,16px) + env(safe-area-inset-top,0px))
          var(--space-md,16px)
          calc(var(--space-md,16px) + env(safe-area-inset-bottom,0px));
  font-family:var(--font-ui,system-ui,-apple-system,sans-serif);
}


.cf-modal-scrim{
  position:absolute;inset:0;
  background:var(--scrim,var(--cf-scrim));
  opacity:0;transition:opacity .3s ease;
}
.cf-modal-layer.cf-on .cf-modal-scrim{opacity:1}

/* ── the sheet (DESIGN_PROMPT §4) ───────────────────────────────────────
 * Desktop: a 440px right drawer, full height. Phone: a bottom sheet, 22px top
 * corners, a 5px grab handle, max-height 90%. Both move on .38s
 * var(--ease-spring). A small confirm (size "sm") stays a centred dialog on
 * desktop -- a one-line question does not need a drawer. Measured from the
 * design's sheet shell; every colour is a design token.
 */
.cf-modal{
  position:relative;
  display:flex;flex-direction:column;
  width:100%;max-width:440px;max-height:100%;
  background:var(--s1);
  color:var(--ink);
  border:0;
  border-radius:16px;
  box-shadow:var(--e2);
  overflow:hidden;
  opacity:0;transform:translateY(8px) scale(.98);
  transition:opacity .2s ease,transform .38s var(--ease-spring);
  text-align:left;
}
.cf-modal-layer.cf-on .cf-modal{opacity:1;transform:none}
.cf-modal:focus{outline:none}
.cf-modal[data-size="sm"]{max-width:380px;border:1px solid var(--line)}

@media (min-width:768px){
  .cf-modal-layer:has(.cf-modal:not([data-size="sm"])){align-items:stretch;justify-content:flex-end;padding:0}
  .cf-modal:not([data-size="sm"]){
    max-width:440px;height:100%;max-height:none;border-radius:0;
    border-left:1px solid var(--line);box-shadow:-20px 0 60px rgba(0,0,0,.35);
    opacity:1;transform:translateX(100%);
  }
  .cf-modal[data-size="lg"]{max-width:520px}
  .cf-modal-layer.cf-on .cf-modal:not([data-size="sm"]){transform:none}
}

/* Grip is sheet-only. */
.cf-modal-grip{display:none}

/* ── header: title 18/800, a 36px round close ─────────────────────────── */
.cf-modal-head{
  display:flex;align-items:center;gap:10px;
  padding:10px 20px 6px;
  flex:0 0 auto;
}
.cf-modal-heading{min-width:0;flex:1;display:flex;flex-direction:column;gap:2px}
.cf-modal-title{margin:0;font:800 18px/1.3 var(--font-ui);color:var(--ink)}
.cf-modal-sub{margin:0;font:500 13px/1.45 var(--font-ui);color:var(--ink2)}

.cf-modal-back,.cf-modal-x{
  flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;
  width:36px;height:36px;margin:0;padding:0;
  border:0;border-radius:50%;
  background:var(--s2);color:var(--ink2);cursor:pointer;
  transition:color .14s,background .14s;
}
.cf-modal-back:hover,.cf-modal-x:hover{color:var(--ink)}
.cf-modal-back svg{width:17px;height:17px;display:block}
.cf-modal-x svg{width:14px;height:14px;display:block}
.cf-modal-x:focus-visible,.cf-modal-back:focus-visible,
.cf-modal-act:focus-visible{outline:2px solid var(--acc);outline-offset:2px}
/* On touch widths the 36px disc keeps its size and takes a 44px tap: the
   fill is clipped to the content box, as navbar.css draws the avatar. The
   negative margin keeps the header's geometry unchanged. */
@media (pointer:coarse),(hover:none),(max-width:1024px){
  .cf-modal-back,.cf-modal-x{
    width:44px;height:44px;margin:-4px;padding:4px;box-sizing:border-box;background-clip:content-box;
  }
}

/* ── body ───────────────────────────────────────────────────────────── */
.cf-modal-body{
  flex:1 1 auto;min-height:0;
  padding:8px 20px 24px;
  overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;
  font:500 14px/1.45 var(--font-ui);color:var(--body);
}
.cf-modal-body:empty{padding-bottom:8px}
.cf-modal-body p{margin:0 0 10px}
.cf-modal-body p:last-child{margin-bottom:0}
.cf-modal-body strong,.cf-modal-body b{color:var(--ink);font-weight:700}
.cf-modal-body a{color:var(--accT)}

/* Explicit empty state: say there is nothing rather than draw something
   plausible (CLAUDE.md, "no invented data, ever"). */
.cf-modal-empty{display:flex;flex-direction:column;align-items:center;gap:6px;padding:24px 16px;text-align:center}
.cf-modal-empty-mark{
  width:40px;height:40px;border-radius:50%;border:1px dashed var(--ink3);
  display:grid;place-items:center;color:var(--ink2);margin-bottom:2px;
}
.cf-modal-empty-mark svg{width:16px;height:16px;display:block}
.cf-modal-empty-title{font:700 14px var(--font-ui);color:var(--ink)}
.cf-modal-empty-text{font:500 13px/1.5 var(--font-ui);color:var(--ink2);max-width:34ch}

/* Field primitives, so a migrated sheet does not have to bring its own. */
.cf-modal-field{display:block;margin:0 0 12px}
.cf-modal-label{display:block;margin:0 0 6px;font:600 12px/1.3 var(--font-ui);color:var(--ink2)}
.cf-modal-input,.cf-modal-textarea{
  box-sizing:border-box;width:100%;
  background:var(--bg);color:var(--ink);
  border:1px solid var(--line);border-radius:12px;
  font:500 15px/1.4 var(--font-num);
  padding:12px;outline:none;min-height:48px;
}
.cf-modal-textarea{min-height:96px;resize:none;font-size:13px;line-height:1.5}
.cf-modal-select{
  box-sizing:border-box;width:100%;min-height:48px;
  background:var(--bg);color:var(--ink);
  border:1px solid var(--line);border-radius:12px;
  font:600 14px/1.4 var(--font-ui);padding:11px 12px;outline:none;
}
.cf-modal-input:focus,.cf-modal-textarea:focus,.cf-modal-select:focus{border-color:var(--acc)}
.cf-modal-input::placeholder,.cf-modal-textarea::placeholder{color:var(--ink2)}
.cf-modal-input:disabled,.cf-modal-select:disabled{opacity:.6;cursor:not-allowed}

/* input + trailing button (Max, paste, scan). */
.cf-modal-row{display:flex;gap:8px;align-items:stretch}
.cf-modal-row .cf-modal-input{flex:1;min-width:0}
.cf-modal-row-btn{
  flex:0 0 auto;min-width:64px;border:0;border-radius:12px;
  background:var(--s2);color:var(--accT);font:700 12px/1 var(--font-ui);cursor:pointer;
}
.cf-modal-row-btn:disabled{opacity:.45;cursor:not-allowed}

/* Secondary line under a field: chain, balance, unit. */
.cf-modal-meta{
  display:flex;justify-content:space-between;gap:10px;margin-top:6px;
  font:500 12px/1.35 var(--font-num);color:var(--ink2);
}
.cf-modal-meta .cf-accent{color:var(--accT)}

.cf-modal-stat{display:flex;gap:8px;margin:0 0 12px}
.cf-modal-stat>div{flex:1;min-width:0;background:var(--bg);border:1px solid var(--line);border-radius:12px;padding:10px}
.cf-modal-stat dt{margin:0 0 2px;font:600 11px var(--font-ui);color:var(--ink2)}
.cf-modal-stat dd{
  margin:0;font:500 16px/1.2 var(--font-num);font-variant-numeric:tabular-nums;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;
}
.cf-modal-stat dd.cf-accent{color:var(--accT)}

.cf-modal-copy{
  display:flex;align-items:center;gap:8px;background:var(--bg);border:1px solid var(--line);
  border-radius:14px;padding:12px 14px;margin:0 0 6px;
}
.cf-modal-copy code{flex:1;min-width:0;word-break:break-all;font:500 13px/1.5 var(--font-num);color:var(--ink)}
.cf-modal-copy button{
  flex:0 0 auto;width:36px;height:36px;display:grid;place-items:center;border:0;border-radius:10px;
  background:var(--s2);color:var(--ink2);cursor:pointer;transition:color .14s;
}
.cf-modal-copy button:hover{color:var(--ink)}
.cf-modal-copy button.cf-done{color:var(--up)}
.cf-modal-copy button svg{width:15px;height:15px;display:block}

.cf-modal-hint{min-height:15px;margin:0 0 4px;font:700 12px/15px var(--font-ui);color:var(--accT)}

.cf-modal-check{
  display:flex;align-items:center;gap:10px;margin:14px 0 0;
  font:600 14px/1.4 var(--font-ui);color:var(--ink);cursor:pointer;
}
.cf-modal-check input{flex:0 0 auto;width:22px;height:22px;margin:0;accent-color:var(--acc);cursor:pointer}

/* ── footer: actions, and the message that belongs WITH them ────────────
 * The failure text sits immediately above the button that produced it. */
.cf-modal-foot{
  flex:0 0 auto;padding:0 20px 20px;
  padding-bottom:calc(20px + env(safe-area-inset-bottom,0px));
  display:flex;flex-direction:column;gap:10px;
}
.cf-modal-foot[hidden]{display:none}

.cf-modal-note{display:flex;align-items:flex-start;gap:8px;padding:10px 12px;border-radius:12px;font:500 13px/1.5 var(--font-ui);border:0}
.cf-modal-note[hidden]{display:none}
.cf-modal-note svg{flex:0 0 auto;width:15px;height:15px;margin-top:2px;display:block}
.cf-modal-note[data-kind="error"]{color:var(--dn);background:var(--dnBg)}
.cf-modal-note[data-kind="success"]{color:var(--up);background:var(--upBg)}
.cf-modal-note[data-kind="info"]{color:var(--ink2);background:var(--s2)}

.cf-modal-actions{display:flex;gap:8px;flex-wrap:wrap}
.cf-modal-actions:empty{display:none}

.cf-modal-act{
  flex:1 1 auto;min-width:120px;min-height:48px;
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  border:0;border-radius:12px;font:700 14px/1 var(--font-ui);
  cursor:pointer;padding:0 16px;transition:opacity .14s,background .14s,color .14s;
}
/* The class rule above would beat the UA's [hidden]{display:none}; this
   re-asserts it with more specificity so setAction({hidden:true}) hides. */
.cf-modal-act[hidden]{display:none}

/* The accent is a FILL with ink text (--onAcc), never a text colour. */
.cf-modal-act[data-variant="primary"]{background:var(--acc);color:var(--onAcc)}
.cf-modal-act[data-variant="primary"][data-full="1"]{min-height:54px;border-radius:14px;font-weight:800;font-size:15px}
.cf-modal-act[data-variant="ghost"]{background:var(--s2);color:var(--ink)}
/* Destructive is outlined, so no single foreground has to read on a red fill
   in both themes. */
.cf-modal-act[data-variant="danger"]{background:transparent;color:var(--dn);border:1px solid var(--dn)}
.cf-modal-act:disabled{background:var(--s2);color:var(--ink2);cursor:not-allowed}
.cf-modal-act[data-full="1"]{flex:1 1 100%}

/* Busy: the spinner joins the label, so the button never changes width. */
.cf-modal-spin{
  width:14px;height:14px;flex:0 0 auto;border-radius:50%;
  border:2px solid currentColor;border-top-color:transparent;
  animation:cf-modal-spin .62s linear infinite;
}
@keyframes cf-modal-spin{to{transform:rotate(360deg)}}

/* An action waiting on a dependency it does not have yet says so, and cannot
   be pressed. */
.cf-modal-act[data-pending="1"]{cursor:progress}

/* ── phone: bottom sheet ────────────────────────────────────────────── */
@media (max-width:767px){
  .cf-modal-layer{align-items:flex-end;padding:0}
  .cf-modal,.cf-modal[data-size="sm"]{
    /* dvh, not vh: on a phone the URL bar collapses and expands. */
    max-width:none;width:100%;max-height:90dvh;
    border:0;border-top:1px solid var(--line);
    border-radius:22px 22px 0 0;
    transform:translateY(100%) scale(1);
    transition:transform .38s var(--ease-spring);
    opacity:1;
  }
  .cf-modal-layer.cf-on .cf-modal{transform:translateY(0)}
  .cf-modal.cf-drag{transition:none}
  .cf-modal-grip{
    display:block;flex:0 0 auto;width:40px;height:5px;margin:10px auto 0;
    border-radius:3px;background:var(--line);
  }
  .cf-modal-head{padding-top:10px}
  .cf-modal-act{min-width:0}
  /* A phone keyboard must never hide the primary action. */
  .cf-modal-foot{position:sticky;bottom:0;background:var(--s1)}
  /* 16px minimum or iOS zooms the whole sheet on focus. */
  .cf-modal-input,.cf-modal-textarea{font-size:16px}
}

/* ── reduced motion: the finished state ─────────────────────────────── */
@media (prefers-reduced-motion:reduce){
  .cf-modal,.cf-modal-scrim{transition:none}
  .cf-modal,.cf-modal-layer .cf-modal,.cf-modal-layer .cf-modal:not([data-size="sm"]){transform:none;opacity:1}
  .cf-modal-layer:not(.cf-on){opacity:0}
  .cf-modal-spin{animation-duration:1.4s}
}


/* ---- static/wallet-onboarding.css ---- */
/* Cartel Family — "Get started" (DESIGN_PROMPT §4), inside the shared sheet.
 *
 * There is no dialog in this file. The frame, the scrim, the heading, the
 * footer, the focus trap, the scroll lock and the phone bottom sheet all come
 * from cf-modal.css / cf-modal.js — the app's one sheet system. What is here
 * is only what is specific to the onboarding steps, scoped under
 * `.oa-ob-modal`, which the script stamps on the dialog element. Measured
 * from CFFlows.dc.html.
 *
 * COLOURS: design tokens from cf-theme.css only. This stylesheet is injected
 * into EVERY HTML response, so one literal here is a literal everywhere, and
 * the app has a light and a dark palette. The method tiles take token
 * colours rather than each wallet's brand hex for the same reason.
 */

/* ── the chooser: pick a method ────────────────────────────────────────── */
.oa-ob-modal .cf-modal-act[hidden]{display:none}
.oa-ob-modal .cf-modal-body{display:flex;flex-direction:column;gap:14px}

/* ── the join screen (owner, 2026-10-15): mark, title, pitch, three feature
   rows, one molten button, one outlined button, a footnote. The dialog's
   own heading stays for assistive tech and is hidden visually here; the ✕
   keeps the top-right corner. */
.oa-ob-modal.oa-ob-chooser .cf-modal-heading{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.oa-ob-modal.oa-ob-chooser .cf-modal-head{padding-bottom:0}
.oa-ob-modal.oa-ob-chooser .cf-modal-x{margin-left:auto}
.oa-ob-modal .oa-ob-join{display:flex;flex-direction:column;align-items:center;gap:14px;text-align:center;padding-top:2px}
.oa-ob-modal .oa-ob-mark{
  position:relative;width:64px;height:64px;border-radius:18px;overflow:hidden;flex:none;background:var(--s2);
  box-shadow:0 0 0 1px var(--line),0 10px 28px var(--accBg);
}
/* The kit's small lockup crop (cf-rail.css): the Boss Bull's face fills the
   tile; the whole icon at this size is mostly dark padding. */
.oa-ob-modal .oa-ob-mark img{position:absolute;width:118%;height:118%;max-width:none;left:-9%;top:-8%;display:block;object-fit:cover}
.oa-ob-modal .oa-ob-title{margin:-2px 0 0;font:700 24px/1.15 var(--font-display);letter-spacing:-.02em;color:var(--ink)}
.oa-ob-modal .oa-ob-pitch{margin:-4px 0 0;max-width:38ch;font:500 14px/1.5 var(--font-ui);color:var(--ink2)}
.oa-ob-modal .oa-ob-feats{list-style:none;margin:2px 0 0;padding:0;width:100%;display:flex;flex-direction:column;gap:14px;text-align:left}
.oa-ob-modal .oa-ob-feat{display:flex;align-items:flex-start;gap:14px}
.oa-ob-modal .oa-ob-feat-ico{width:44px;height:44px;border-radius:50%;flex:none;display:grid;place-items:center;background:var(--accBg);color:var(--accT)}
.oa-ob-modal .oa-ob-feat-ico svg{width:22px;height:22px;display:block}
.oa-ob-modal .oa-ob-feat-text{display:grid;gap:2px;min-width:0;padding-top:2px}
.oa-ob-modal .oa-ob-feat-text b{font:700 15px/1.3 var(--font-ui);color:var(--ink)}
.oa-ob-modal .oa-ob-feat-text span{font:500 13px/1.45 var(--font-ui);color:var(--ink2)}
.oa-ob-modal .oa-ob-ctas{width:100%;display:flex;flex-direction:column;gap:10px;margin-top:2px}
/* The labels name every method ("Sign in with Telegram, X, Google or Apple"),
   so the pill may wrap at 320px instead of clipping. */
.oa-ob-modal .oa-ob-cta{white-space:normal;line-height:1.25;padding:12px 18px;min-height:54px;height:auto}
.oa-ob-modal .oa-ob-foot{margin:0;max-width:42ch;font:500 12px/1.5 var(--font-ui);color:var(--ink2)}
@media (prefers-reduced-motion:no-preference){
  /* A short rise, position only: a paused animation (app-ux.css pauses a
     hidden tab) leaves the rows visible, never parked at opacity 0. */
  .oa-ob-modal .oa-ob-feat{animation:oaObRise .5s var(--ease-out,ease-out) both}
  .oa-ob-modal .oa-ob-feat:nth-child(2){animation-delay:.06s}
  .oa-ob-modal .oa-ob-feat:nth-child(3){animation-delay:.12s}
  @keyframes oaObRise{from{transform:translateY(8px)}to{transform:none}}
}

.oa-ob-modal .oa-ob-methods{display:flex;flex-direction:column;gap:14px}
.oa-ob-modal .oa-ob-method{
  min-height:56px;display:flex;align-items:center;gap:12px;padding:0 14px;width:100%;
  background:var(--bg);border:1px solid var(--line);border-radius:14px;cursor:pointer;
  color:var(--ink);text-align:left;transition:border-color .14s;
}
.oa-ob-modal .oa-ob-method:hover:not(:disabled){border-color:var(--acc)}
.oa-ob-modal .oa-ob-method:focus-visible{outline:2px solid var(--acc);outline-offset:2px}
.oa-ob-modal .oa-ob-method:disabled{cursor:progress;opacity:.6}
.oa-ob-modal .oa-ob-code{
  position:relative;width:36px;height:36px;border-radius:10px;flex:none;display:flex;align-items:center;justify-content:center;
  background:var(--s2);border:1px solid var(--line);color:var(--ink2);overflow:hidden;
}
/* Our own methods draw a single-stroke glyph; a third-party brand draws its
   own mark (CFBrand.wallet), which replaces the generic wallet glyph. */
.oa-ob-modal .oa-ob-glyph{width:20px;height:20px;flex:none}
.oa-ob-modal .oa-ob-code .cf-logo{width:24px;height:24px;margin:0;vertical-align:0;border-radius:6px;object-fit:contain}
.oa-ob-modal .oa-ob-code:has(.cf-logo) .oa-ob-glyph{display:none}
.oa-ob-modal .oa-ob-method:hover:not(:disabled) .oa-ob-code{border-color:var(--acc)}
.oa-ob-modal .oa-ob-method:hover:not(:disabled) .oa-ob-glyph{color:var(--acc)}
.oa-ob-modal .oa-ob-mlabel{font:700 15px var(--font-ui);flex:1;min-width:0}
/* The note wraps on the right (46% at most) rather than riding over the label at 320px. */
.oa-ob-modal .oa-ob-mnote{font:500 12px/1.3 var(--font-ui);color:var(--ink2);flex:none;max-width:46%;text-align:right}

/* The three big rows (the "Sign in" step): Telegram, X, Google (Apple when
   configured). 64px, a 40px mark tile, the label at 16/700; the lit edge is
   the one gold line the Noir component library draws on a primary control. */
.oa-ob-modal .oa-ob-primary{gap:10px}
.oa-ob-modal .oa-ob-method.is-primary{
  min-height:64px;padding:0 16px;gap:14px;border-radius:16px;background:var(--s1);
  border-color:var(--line);position:relative;
}
.oa-ob-modal .oa-ob-method.is-primary .oa-ob-code{width:40px;height:40px;border-radius:12px}
.oa-ob-modal .oa-ob-method.is-primary .oa-ob-code .cf-logo{width:26px;height:26px}
.oa-ob-modal .oa-ob-method.is-primary .oa-ob-mlabel{font-size:16px}
.oa-ob-modal .oa-ob-method.is-primary::after{
  content:"";position:absolute;left:14px;right:14px;top:-1px;height:1px;opacity:0;
  background:linear-gradient(90deg,transparent,var(--acc),transparent);transition:opacity .16s;
}
.oa-ob-modal .oa-ob-method.is-primary:hover:not(:disabled)::after,
.oa-ob-modal .oa-ob-method.is-primary:focus-visible::after{opacity:1}

@media (prefers-reduced-motion:reduce){
  .oa-ob-modal .oa-ob-method.is-primary::after{transition:none}
}

.oa-ob-modal .oa-ob-foot-note,
.oa-ob-modal .oa-ob-security-note,.oa-ob-modal .oa-ob-lock-note{
  display:flex;align-items:center;justify-content:center;gap:7px;
  font:500 12px var(--font-ui);color:var(--ink2);
}
.oa-ob-modal .oa-ob-foot-note svg,.oa-ob-modal .oa-ob-security-note svg,
.oa-ob-modal .oa-ob-lock-note svg{width:14px;height:14px;flex:0 0 auto}
.oa-ob-modal .oa-ob-foot-note b{padding:0 2px;color:var(--ink2);font-weight:700}
.oa-ob-modal .oa-ob-security-note{justify-content:flex-start}

/* ── Telegram login mounts here ─────────────────────────────────────── */
.oa-ob-modal .oa-ob-tg{background:var(--bg);border:1px solid var(--line);border-radius:14px;padding:16px}

/* ── create: progress, warning, the keys (revealed on demand) ─────────── */
.oa-ob-modal .oa-ob-progress{
  display:grid;grid-template-columns:auto 1fr auto 1fr auto;align-items:start;gap:8px;
}
.oa-ob-modal .oa-ob-progress-line{height:1px;background:var(--line);margin-top:13px}
.oa-ob-modal .oa-ob-step{display:grid;justify-items:center;gap:5px;color:var(--ink2);font:600 11px var(--font-ui);white-space:nowrap}
.oa-ob-modal .oa-ob-step-dot{
  display:grid;place-items:center;width:26px;height:26px;border-radius:50%;
  background:var(--s2);color:var(--ink2);font:700 11px var(--font-ui);
}
.oa-ob-modal .oa-ob-step.done,.oa-ob-modal .oa-ob-step.active{color:var(--accT)}
.oa-ob-modal .oa-ob-step.done .oa-ob-step-dot,
.oa-ob-modal .oa-ob-step.active .oa-ob-step-dot{background:var(--acc);color:var(--onAcc)}

.oa-ob-modal .oa-ob-warning{
  display:grid;grid-template-columns:22px 1fr;align-items:center;gap:10px;
  padding:10px 12px;border:1px solid var(--proLine);border-radius:12px;background:var(--proBg);
  font:600 13px/1.45 var(--font-ui);color:var(--ink);
}
.oa-ob-modal .oa-ob-shield{width:20px;height:22px;color:var(--pro)}

.oa-ob-modal .oa-ob-fields{display:flex;flex-direction:column;gap:10px;background:var(--bg);
  border:1px solid var(--line);border-radius:14px;padding:14px}
.oa-ob-modal .oa-ob-field-card{display:flex;flex-direction:column;gap:6px}
.oa-ob-modal .oa-ob-field-label{font:500 12px var(--font-num);color:var(--ink2)}
.oa-ob-modal .oa-ob-value-row{display:flex;align-items:stretch;gap:6px;min-width:0}
.oa-ob-modal .oa-ob-value{
  display:flex;align-items:center;min-width:0;min-height:44px;flex:1;
  border-radius:10px;background:var(--s2);color:var(--ink);padding:0 12px;
  font:500 13px/1.5 var(--font-num);
}
.oa-ob-modal .oa-ob-value-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.oa-ob-modal .oa-ob-secret-input{
  box-sizing:border-box;width:100%;min-width:0;border:0;outline:0;
  background:transparent;color:var(--ink);font:500 13px/1 var(--font-num);
}
.oa-ob-modal .oa-ob-secret-input[type=password]{letter-spacing:.14em}
.oa-ob-modal .oa-ob-icon-btn,.oa-ob-modal .oa-ob-show-btn{
  display:flex;align-items:center;justify-content:center;gap:5px;flex:0 0 auto;min-height:44px;
  border:0;border-radius:10px;background:var(--s2);color:var(--accT);
  font:700 12px/1 var(--font-ui);cursor:pointer;
}
.oa-ob-modal .oa-ob-icon-btn{width:44px}
.oa-ob-modal .oa-ob-show-btn{padding:0 12px}
.oa-ob-modal .oa-ob-icon-btn.copied{color:var(--up)}
.oa-ob-modal .oa-ob-icon-btn:focus-visible,.oa-ob-modal .oa-ob-show-btn:focus-visible{outline:2px solid var(--acc);outline-offset:2px}
.oa-ob-modal .oa-ob-icon{width:17px;height:17px;display:block}
.oa-ob-modal .oa-ob-check{margin:0}

/* ── import: base58 / JSON array, validated live ────────────────────── */
.oa-ob-modal .oa-ob-seg{display:flex;background:var(--s2);border-radius:10px;padding:2px}
.oa-ob-modal .oa-ob-seg button{
  flex:1;height:34px;border:0;border-radius:8px;background:transparent;
  font:700 13px var(--font-ui);color:var(--ink2);cursor:pointer;
}
.oa-ob-modal .oa-ob-seg button.on{background:var(--s1);color:var(--ink)}
.oa-ob-modal .oa-ob-seg button:focus-visible{outline:2px solid var(--acc);outline-offset:2px}
.oa-ob-modal .cf-modal-body>.cf-modal-label{margin:0 0 -8px}
.oa-ob-modal textarea.oa-ob-secret{min-height:96px}
.oa-ob-modal textarea.oa-ob-bad{border-color:var(--dn)}
.oa-ob-modal .oa-ob-keymsg{font:600 12px var(--font-ui);color:var(--ink2);margin-top:-6px}
.oa-ob-modal .oa-ob-keymsg[data-kind="bad"]{color:var(--dn)}
.oa-ob-modal .oa-ob-keymsg[data-kind="good"]{color:var(--up)}
.oa-ob-modal .oa-ob-label-optional small{font-size:11px;font-weight:600;color:var(--ink2)}

@media (max-width:767px){
  /* The reveal button keeps its 44px target but drops the word. */
  .oa-ob-modal .oa-ob-show-btn{width:44px;padding:0;font-size:0}
  .oa-ob-modal .oa-ob-show-btn .oa-ob-icon{width:19px;height:19px}
}
@media (max-width:370px){
  .oa-ob-modal .oa-ob-progress{gap:4px}
  .oa-ob-modal .oa-ob-step{font-size:10px}
}

/* ── the pairing-code sheet (cf-wallet-connect.js, 2026-10-12) ──────────
   The home-screen app types the code the signing page shows. Tokens only. */
.cf-pair-sheet .cf-pair-lede{margin:0 0 14px;font:500 14px/1.5 var(--font-ui);color:var(--body,var(--ink))}
.cf-pair-sheet .cf-pair-input{
  height:56px;text-align:center;
  font:700 26px/1 var(--font-num);letter-spacing:.18em;text-transform:uppercase;
  color:var(--ink);font-variant-numeric:tabular-nums;
}
.cf-pair-sheet .cf-pair-fine{margin:10px 0 0;font:500 12px/1.45 var(--font-ui);color:var(--ink2)}
.cf-pair-sheet .cf-pair-steps{margin:0;padding:0 0 0 20px;display:grid;gap:8px;
  font:500 14px/1.45 var(--font-ui);color:var(--body,var(--ink))}
.cf-pair-sheet .cf-pair-steps b{color:var(--ink);font-weight:700}
.cf-pair-sheet .cf-pair-steps li::marker{color:var(--accT);font-weight:700}

