/* =========================================================
   ZOZA TOKENS — the single source of truth for every colour,
   radius, font size, duration and row shape in the product.
   =========================================================

   THE RULE (docs/social-trading/FOMO-UI-QUALITY-AND-ZOZA-RENDER-SYSTEM-2026-08-29.md §3.1):

     > A colour, radius, font-size, duration or row shape may exist in
     > exactly ONE file. Everything else references it. If a surface
     > cannot reference it (native), it MIRRORS it and a test fails on
     > drift.

   This is that one file. Every hex in the product should be here.

   Consumers
   ---------
   · hosted pages      link/inline this file (publish-page.mjs inlines it
                       + the two font faces as data: URIs — server-blind,
                       NEVER a Google Fonts CDN)
   · design-preview    crates/cef-host/installer-assets/design-preview/tokens.css
                       carries a GENERATED copy of the block between the
                       ZOZA-TOKENS markers. Run `node scripts/sync-design-tokens.mjs`
                       after editing this file; CI checks it is in sync.
   · iOS               ios/ZozaBrowser/ZozaTheme.swift          (mirror)
   · Android           android/lib/zoza_theme.dart              (mirror)
   · desktop chrome    crates/cef-host/src/cef/scheme.rs        (mirror, chrome subset)

   Drift across those four mirrors is caught by
   `crates/wallet-core/tests/design_tokens_shell_xcheck.rs`, which fails
   loudly naming the token and every disagreeing value.

   Colour law (unchanged since tokens.css, restated because it is the
   whole reason FOMO's screens read faster than ours did):
     1. `--accent-primary` is the ONLY identity accent. Do not invent teals.
     2. Green/red come ONLY from `--mkt-up` / `--mkt-down` and mean market
        direction or a trade action — never generic success/error, never
        chrome. Spending the "up" channel on a nav bar is what made the
        Exchange unreadable at a glance.
     3. Product accents (`--p-*`) are locked and theme-invariant.
   ========================================================= */

/* ZOZA-TOKENS:FONTS:BEGIN */
/* Self-hosted variable fonts. Server-blind: NEVER a font CDN — a
   `fonts.googleapis.com` link would tell Google which Zoza page each user
   opened, which is the thing we sell against. `publish-page.mjs` rewrites
   these `zoza://design-preview/fonts/…` URLs to `data:` URIs so a
   cloud-hosted bundle carries its own faces, and refuses to publish a
   bundle that still names a remote font host or an unresolved zoza:// URL.

   WOFF2, not TTF: the bundles are self-contained single HTML files, and the
   three TTFs cost 2.6 MB of base64 in EVERY one of them against ~550 KB for
   the same glyphs as WOFF2. The desktop shell serves both (scheme.rs) so a
   previously published bundle keeps resolving.

   The italic face is deliberately last: nothing in the product sets
   `font-style: italic` today, so on most surfaces the browser never fetches
   it at all. */
@font-face {
  font-family: "Inter";
  src: url("/fonts/Inter-VariableFont_opsz_wght.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
/* JetBrains Mono — addresses, tx hashes, and nothing else. */
@font-face {
  font-family: "JetBrains Mono";
  src: url("/fonts/JetBrainsMono-VariableFont_wght.woff2") format("woff2-variations");
  font-weight: 100 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("/fonts/Inter-Italic-VariableFont_opsz_wght.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-style: italic;
  font-display: swap;
}
/* ZOZA-TOKENS:FONTS:END */

/* ZOZA-TOKENS:CORE:BEGIN */
:root {
  --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  /* Geometry / motion (theme-invariant) */
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 20px;
  --radius-pill: 999px;
  --ease-standard: cubic-bezier(0.2, 0.8, 0.2, 1);
  --dur-fast: 120ms;
  --dur-base: 200ms;
  --dur-slow: 320ms;

  /* Interaction motion — press/settle. A SECOND curve on purpose: the
     press spring is mirrored as compile-time constants in
     ZozaControls.swift (`pressScale .94`, `press .26/.55`,
     `settle timingCurve(.22,1,.36,1) 0.34`) and zoza_motion.dart, so
     retuning one means retuning all three. `--z-*` below are kept as
     aliases because ~15 chrome pages already reference them. */
  --ease-spring: cubic-bezier(0.22, 1, 0.36, 1);
  --dur-press: 260ms;
  --dur-settle: 340ms;
  --press-scale: 0.94;
  --z-ease: var(--ease-spring);
  --z-settle: var(--dur-settle);
  --z-press: var(--dur-press);
  --dur-sweep: 420ms;

  /* ---------- FOMO-derived layout scale (§2 of the render-system doc) ----------
     One row shape, four type sizes, one CTA height — repeated on every
     surface so a user who learned the wallet already knows the exchange. */
  --row-h: 64px;          /* every list row: tokens, holders, feed, leaderboard */
  --row-h-compact: 52px;  /* dense tables only (perps ladder) */
  --logo: 40px;           /* round token/avatar in a row */
  --logo-badge: 14px;     /* chain badge / verified check overlaid bottom-right */
  --logo-sm: 24px;        /* inline references inside a sentence */
  --avatar-stack: 20px;   /* ZAvatarStack members */
  --inset: 16px;          /* horizontal page inset, everywhere */
  --gap: 12px;
  --tap-min: 44px;        /* minimum tap target */

  --hero-size: 36px;      /* the one big number per screen */
  --hero-weight: 700;
  --hero-line: 40px;
  --title-size: 17px;     /* row title */
  --title-weight: 600;
  --meta-size: 13px;      /* row subtitle, deltas */
  --meta-weight: 400;
  --micro-size: 11px;     /* badges, timestamps, captions */
  --micro-weight: 500;

  --cta-h: 52px;          /* the one pinned primary button per screen */
  --sheet-radius: 20px;   /* bottom sheet top corners */
  --nav-pill-h: 60px;     /* floating frosted nav pill */
  --glass-blur: 24px;

  /* Tabular figures. Applied by .num / ZRow values / ZHero — a price
     column that does not align is the single most obvious "cheap app"
     tell, and we had `tabular-nums` in 2 places in 95KB of CSS. */
  --num-features: "tnum" 1, "ss01" 1, "cv11" 1, "liga" 0, "calt" 0;

  /* Locked product accents — identical across every theme. NEVER reference
     a theme variable for these. */
  --p-auth:      #19C3D6;
  --p-vault:     #7B5BFF;
  --p-verify:    #2ECC71;
  --p-shield:    #F5A623;
  --p-sign:      #FF7849;
  --p-ai:        #19C3D6;
  --p-messenger: #FF4D8D;

  /* Fixed inks for THIRD-PARTY brand fills — a coin bubble painted with
     Ethereum's #627EEA needs light text in every theme, so it cannot use
     --text-on-accent (which is dark ink on the Midnight cyan). Not mirrored
     on native: the shells render coin marks as images, not tinted circles.
     `--sheen` is the white highlight sweep on pressed/loading surfaces. */
  --on-brand: #FFFFFF;
  --sheen: rgba(255, 255, 255, 0.16);

  /* Status dots (locked) */
  --status-action: #FF7849;   /* needs-action orange */
  --status-ready:  #19C3D6;   /* session-ready cyan  */

  /* Market semantics (locked across themes) — the ONLY place red/green
     may come from on a trading surface. Identity accent stays cyan;
     green/red are reserved for market direction + trade actions. */
  --mkt-up:       #2BD48F;
  --mkt-up-dim:   rgba(43, 212, 143, 0.14);
  --mkt-down:     #FF5A5F;
  --mkt-down-dim: rgba(255, 90, 95, 0.14);
  --mkt-warn:     #E8A13C;

  /* Market colours have TWO roles and the product had only one name for
     them, which is why five different greens ended up in the tree.

       --mkt-up        the FILL: chart lines, area gradients, buy pills,
                       stat bars. Locked, identical in every theme — it is
                       the brand's green.
       --mkt-up-text   the same meaning as INK ON THE CANVAS. Must clear
                       WCAG on the theme it sits on, so it is theme-aware:
                       #2BD48F is a 1.7:1 smear on the Daybreak #F7F8FB
                       canvas and unreadable.

     Before this, zoza-wealth.html and zoza-agent-home.html each carried
     their own per-theme ladder (#2ECC71 / #138A55 / #127A4E and
     #FF5A5F / #D23B3B / #C2402F) copy-pasted and already drifted from
     each other and from these tokens. Same values, one home. */
  --mkt-up-text:   var(--mkt-up);
  --mkt-down-text: var(--mkt-down);
  --mkt-warn-text: var(--mkt-warn);

  --chart-line:   var(--mkt-up);
  /* Area-chart fill: gradient from this at the line to transparent. */
  --chart-fill-top: rgba(43, 212, 143, 0.28);

  /* ---------- THEME 1 — Midnight (default) ---------- */
  --bg-primary:    #0A0F1F;
  --bg-elevated:   #131A2E;
  --bg-hover:      #1B2240;
  --bg-sunken:     #060916;

  --text-primary:   #F5F7FA;
  --text-secondary: #7A8290;
  --text-muted:     #4A5168;
  --text-on-accent: #051018;

  --border-hairline: rgba(255, 255, 255, 0.06);
  --border-strong:   rgba(255, 255, 255, 0.12);

  --accent-primary: #19C3D6;

  --shadow-card:    0 2px 8px rgba(0,0,0,0.30), 0 0 1px rgba(25,195,214,0.10);
  --shadow-modal:   0 24px 64px rgba(0,0,0,0.55), 0 0 1px rgba(25,195,214,0.15);
  --shadow-popover: 0 8px 24px rgba(0,0,0,0.45), 0 0 1px rgba(255,255,255,0.08);

  --glow-identity:  0 0 24px rgba(25,195,214,0.35);
  --glow-identity-strong: 0 0 32px rgba(25,195,214,0.55);

  /* Frosted surfaces (nav pill, sheet scrim, sticky CTA bar) */
  --glass-bg:   rgba(19, 26, 46, 0.72);
  --glass-edge: rgba(255, 255, 255, 0.10);
  --scrim:      rgba(6, 9, 22, 0.60);
}

/* ---------- THEME 4 — Emerald (green glass) ----------
   2026-08-29, founder request: "this green glass color theme also missing in
   our browser".

   This palette is not new — it is the Exchange's, landed 2026-07-10 in
   `8a1c6847 feat(exchange): apply soft terminal design system` and lived in
   `zoza-ui.css` as that ONE page's private colour theory. Making it a real
   preset is the whole point: a look this good should be selectable on every
   surface, not hardcoded into one and unavailable everywhere else.

   ⚠ Known tension, stated rather than hidden: in a green-accent theme the
   identity accent sits close to `--mkt-up`. That ambiguity is exactly what
   made the old Exchange hard to read — there, `--accent` and `--gain` were
   the SAME hex (#3ddc84), so a gaining position was the same colour as the
   nav bar. Here they are deliberately separated: the accent is the brighter
   yellow-green #3DDC84, market-up stays the cooler teal-green #2BD48F, and
   the accent is still confined to its three jobs (primary CTA, selected tab,
   links). It is a narrower gap than in the other themes — if it reads as
   ambiguous on real data, the fix is to shift THIS theme's accent, not to
   move the market colours, which are locked. */
[data-theme="emerald"] {
  --bg-primary:  #0C120E;
  --bg-elevated: #121A14;
  --bg-hover:    #17211A;
  --bg-sunken:   #070C09;

  --text-primary:   #EEF3EE;
  --text-secondary: #9DB3A2;
  --text-muted:     #5F7465;
  --text-on-accent: #06130B;

  --border-hairline: rgba(255, 255, 255, 0.06);
  --border-strong:   rgba(255, 255, 255, 0.12);

  --accent-primary: #3DDC84;

  --shadow-card:    0 2px 8px rgba(0,0,0,0.34), 0 0 1px rgba(61,220,132,0.10);
  --shadow-modal:   0 24px 64px rgba(0,0,0,0.58), 0 0 1px rgba(61,220,132,0.15);
  --shadow-popover: 0 8px 24px rgba(0,0,0,0.48), 0 0 1px rgba(255,255,255,0.08);

  --glow-identity:        0 0 24px rgba(61,220,132,0.32);
  --glow-identity-strong: 0 0 32px rgba(61,220,132,0.50);

  --glass-bg:   rgba(18, 26, 20, 0.72);
  --glass-edge: rgba(255, 255, 255, 0.10);
  --scrim:      rgba(7, 12, 9, 0.62);
}

/* ---------- THEME 2 — Daybreak (light) ---------- */
[data-theme="daybreak"] {
  --bg-primary:  #F7F8FB;
  --bg-elevated: #FFFFFF;
  --bg-hover:    #EEF1F6;
  --bg-sunken:   #EEF1F6;

  --text-primary:   #0A0F1F;
  --text-secondary: #5A6275;
  --text-muted:     #9098A8;
  --text-on-accent: #FFFFFF;

  --border-hairline: rgba(10, 15, 31, 0.08);
  --border-strong:   rgba(10, 15, 31, 0.16);

  --accent-primary: #0E97A8;

  --shadow-card:    0 1px 4px rgba(10,15,31,0.06), 0 0 12px rgba(14,151,168,0.10);
  --shadow-modal:   0 12px 36px rgba(10,15,31,0.14), 0 0 1px rgba(14,151,168,0.18);
  --shadow-popover: 0 6px 20px rgba(10,15,31,0.10), 0 0 1px rgba(10,15,31,0.10);

  --glow-identity:        0 0 16px rgba(14,151,168,0.18);
  --glow-identity-strong: 0 0 24px rgba(14,151,168,0.30);

  --glass-bg:   rgba(255, 255, 255, 0.78);
  --glass-edge: rgba(10, 15, 31, 0.08);
  --scrim:      rgba(10, 15, 31, 0.32);

  /* Market ink, darkened for a light canvas (see the note at --mkt-up-text). */
  --mkt-up-text:   #138A55;
  --mkt-down-text: #D23B3B;
  --mkt-warn-text: #B5791A;
}

/* ---------- THEME 3 — Apricot (warm) ---------- */
[data-theme="apricot"] {
  --bg-primary:  #FFF1E5;
  --bg-elevated: #FFFAF3;
  --bg-hover:    #FBE7D2;
  --bg-sunken:   #FBE7D2;

  --text-primary:   #2A1810;
  --text-secondary: #7A5A48;
  --text-muted:     #B89888;
  --text-on-accent: #FFFAF3;

  --border-hairline: rgba(42, 24, 16, 0.10);
  --border-strong:   rgba(42, 24, 16, 0.18);

  /* Accent stays cyan-darker (matching Daybreak) — orange #E07A2C clashed
     with Sign product accent #FF7849, breaking the product-color hierarchy.
     Bg/text/shadows still warm; only accent is shared with Daybreak so the
     product accent system stays distinguishable across all 3 themes. */
  --accent-primary: #0E97A8;

  --shadow-card:    0 2px 6px rgba(42,24,16,0.08), 0 0 16px rgba(14,151,168,0.16);
  --shadow-modal:   0 16px 40px rgba(42,24,16,0.16), 0 0 1px rgba(14,151,168,0.20);
  --shadow-popover: 0 8px 22px rgba(42,24,16,0.12), 0 0 1px rgba(42,24,16,0.10);

  --glow-identity:        0 0 18px rgba(14,151,168,0.20);
  --glow-identity-strong: 0 0 26px rgba(14,151,168,0.32);

  --glass-bg:   rgba(255, 250, 243, 0.78);
  --glass-edge: rgba(42, 24, 16, 0.10);
  --scrim:      rgba(42, 24, 16, 0.32);

  /* Market ink on the warm canvas. */
  --mkt-up-text:   #127A4E;
  --mkt-down-text: #C2402F;
  --mkt-warn-text: #A86F1D;
}
/* ZOZA-TOKENS:CORE:END */

/* ZOZA-TOKENS:BASE:BEGIN */
/* =========================================================
   Base typography — the four sizes, and nothing else.
   ========================================================= */
html, body {
  margin: 0;
  background: var(--bg-primary);
  color: var(--text-primary);
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 20px;
  /* 2026-10-01 — Inter tuned, not default: single-storey a + open digits,
     and the variable font's optical sizes (display cut for big numbers).
     Mirrors ZozaTheme.textFeatures on the native shells. */
  font-feature-settings: "cv11" 1, "ss01" 1;
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Every digit the user might compare against another digit. */
.num, .z-num {
  font-variant-numeric: tabular-nums;
  font-feature-settings: var(--num-features);
}

.mono {
  font-family: var(--font-mono);
  font-feature-settings: "tnum", "liga" 0, "calt" 0;
}

.cap {
  font-family: var(--font-sans);
  font-size: var(--micro-size);
  line-height: 16px;
  font-weight: 500;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--text-secondary);
}
/* ZOZA-TOKENS:BASE:END */
