/* ══════════════════════════════════
   DESIGN TOKENS — Kelda Finance
   Design System v2.0 — Palette × Mode
   Colour is driven by two independent attributes on <html>:
     data-palette = kelda | fintech | emerald | slate | harvest
     data-mode    = dark | light
   Each palette states only 13 source colour tokens per mode; every other
   colour token below DERIVES from those, so a palette never has to restate
   nav/input/shadow/tint values. Non-colour tokens (spacing, radii, type,
   layout) are palette/mode agnostic and live in :root.
   ══════════════════════════════════ */

:root {
  /* ── 13 source colour tokens: seeded with Kelda-dark so the app still
        renders if the attributes are ever missing (FOUC / no-JS fallback) ── */
  --n950:#080C18; --card:#111830; --card2:#18213E; --card3:#1E2A4A;
  --primary:#F0538A; --primary-text:#080C18; --purple:#818CF8;
  --success:#00C896; --warn:#F59E0B; --danger:#EF4444;
  --text:#E8EDF5; --muted:#8094B8; --border:rgba(98,120,160,0.2);

  /* ── Legacy navy scale now DERIVES from the semantic tokens above, so the
        handful of components still referencing --n### follow the palette ── */
  --n900:var(--card); --n800:var(--card); --n700:var(--card2);
  --n600:var(--card3); --n300:var(--muted);

  /* ── Page + surface + nav + input (follow the palette) ── */
  --bg:var(--n950);
  --nav-bg:var(--card); --nav-text:var(--muted); --nav-active:var(--primary-ink);
  --input-bg:var(--card2); --input-border:var(--border);

  /* ── Accent derivations. Semantic tint backgrounds use color-mix so they
        follow the palette in both modes (target browsers: iOS Safari 16.2+,
        Chrome/Safari desktop) ── */
  --pink-light:var(--primary-ink); --pink-dark:var(--primary); --success-lt:var(--success);
  --success-bg:color-mix(in srgb, var(--success) 15%, transparent);
  --warn-bg:color-mix(in srgb, var(--warn) 15%, transparent);
  --danger-bg:color-mix(in srgb, var(--danger) 15%, transparent);
  /* Status text that sits on those tints. The raw status colour falls
     under 4.5:1 on its own tint in most palettes, so mix it toward --text. */
  --success-ink:color-mix(in srgb, var(--success) 60%, var(--text));
  --warn-ink:color-mix(in srgb, var(--warn) 60%, var(--text));
  --danger-ink:color-mix(in srgb, var(--danger) 60%, var(--text));
  --purple-bg:color-mix(in srgb, var(--purple) 15%, transparent);
  --purple-ink:color-mix(in srgb, var(--purple) 50%, var(--text));
  /* Primary as text (links, active labels). Light modes pull it toward
     --text and Fintech dark sets a lighter blurple; fills keep --primary. */
  --primary-ink:var(--primary);
  --pink-soft:var(--primary-ink);
  /* Hover fill for primary buttons whose label is --primary-text. */
  --primary-fill-hover:var(--pink-light);

  /* ── Prototype aliases (onboarding + dashboard redesign) ── */
  --pink:var(--primary); --green:var(--success); --amber:var(--warn);
  --red:var(--danger); --white:#ffffff;
  --pink-dim:color-mix(in srgb, var(--primary) 8%, transparent);
  --pink-dim-strong:color-mix(in srgb, var(--primary) 13%, transparent);
  --green-dim:color-mix(in srgb, var(--success) 8%, transparent);
  --amber-dim:color-mix(in srgb, var(--warn) 8%, transparent);

  /* ── Spacing tokens (8pt grid) ── */
  --sp1:4px; --sp2:8px; --sp3:12px; --sp4:16px;
  --sp6:24px; --sp8:32px; --sp12:48px; --sp16:64px;
  /* ── Radii ── */
  --radius:16px; --radius-sm:10px; --radius-lg:20px; --radius-pill:9999px;
  /* ── Typography ── */
  --font-display:'Sora',system-ui,sans-serif;
  --font-body:'DM Sans',system-ui,sans-serif;
  --font-mono:'DM Mono',monospace;
  --font-head:var(--font-display);
  /* ── Layout ── */
  --nav-w:56px; --nav-w-open:200px; --topbar-h:52px; --tabbar-h:60px;
}

/* ── Shadows depend on MODE only (dark needs heavier depth than light) ── */
[data-mode="dark"]{
  /* Raw success/warn already read at 6:1+ on dark cards, so dark mode uses
     them as they are. Danger keeps the mix: raw red falls under 4.5:1 on
     several dark cards. */
  --success-ink:var(--success); --warn-ink:var(--warn);
  --shadow-sm:0 2px 8px rgba(0,0,0,.35);
  --shadow:0 8px 32px rgba(0,0,0,.45);
  --shadow-lg:0 16px 48px rgba(0,0,0,.55);
}
[data-mode="light"]{
  /* Light primaries sit at 3.7-4.4:1 on --card2 and the pink tints, so
     primary text is pulled a little toward --text. */
  --primary-ink:color-mix(in srgb, var(--primary) 80%, var(--text));
  --shadow-sm:0 2px 8px rgba(0,0,0,.08);
  --shadow:0 4px 24px rgba(0,0,0,.12);
  --shadow-lg:0 16px 48px rgba(0,0,0,.16);
}

/* ══════════════════════════════════════════════════════════════════
   PALETTE × MODE BLOCKS (5 palettes × 2 modes = 10)
   Each block states only the 13 source tokens; all other colours cascade.
   Provenance is called out where a value is load-bearing vs. adjustable.
   ══════════════════════════════════════════════════════════════════ */

/* KELDA — dark = exact current shipped default. Baseline every other palette
   is judged against. Do NOT alter without explicit sign-off.
   2.5.6 contrast pass: --primary-text, --muted and --pink-dark changed so
   labels on the pink fill and muted text reach WCAG AA (4.5:1). */
[data-palette="kelda"][data-mode="dark"]{
  --n950:#080C18; --card:#111830; --card2:#18213E; --card3:#1E2A4A;
  --primary:#F0538A; --primary-text:#080C18;
  --purple:#818CF8; --success:#00C896; --warn:#F59E0B; --danger:#EF4444;
  --text:#E8EDF5; --muted:#8094B8; --border:rgba(98,120,160,.2);
  /* baseline-exact overrides so the shipped dark look is byte-identical */
  --nav-bg:#0D1225; --pink-light:#F56CA0; --pink-dark:#DE4A7E; --success-lt:#22D9A9;
  --pink-soft:#F48CB2;
}
[data-palette="kelda"][data-mode="light"]{
  --n950:#FBF7F9; --card:#FFFFFF; --card2:#F7EEF2; --card3:#F0E1E8;
  --primary:#C73A6A; --primary-text:#FFFFFF;
  --purple:#5A54D6; --success:#0F9E73; --warn:#C97A0E; --danger:#D6392E;
  --text:#231827; --muted:#7A5D6E; --border:rgba(199,58,106,.14);
}

/* FINTECH — accent sourced from Stripe blurple #635BFF. Light mode uses
   Stripe's real published bg/text tokens (#F6F9FC / #0A2540) — the only block
   in this set extracted from a real external system rather than originated. */
[data-palette="fintech"][data-mode="dark"]{
  --n950:#0A0E1A; --card:#111B34; --card2:#16213E; --card3:#1C2A4C;
  --primary:#635BFF; --primary-text:#FFFFFF;
  --purple:#8B85FF; --success:#00C896; --warn:#F5A623; --danger:#EF4444;
  --text:#EAF0FA; --muted:#8695B0; --border:rgba(107,124,153,.22);
  /* #635BFF is 3.6:1 on --card, so text uses a lighter blurple (5.4:1+ on
     every card). Fills stay #635BFF so white labels keep their contrast. */
  --primary-ink:#9A94FF; --primary-fill-hover:var(--primary);
}
[data-palette="fintech"][data-mode="light"]{
  --n950:#F6F9FC; --card:#FFFFFF; --card2:#F0F3F9; --card3:#E7ECF5;
  --primary:#5851E8; --primary-text:#FFFFFF;
  --purple:#6C63E0; --success:#0F9E73; --warn:#C97A0E; --danger:#D6392E;
  --text:#0A2540; --muted:#5A6B85; --border:rgba(10,37,64,.12);
}

/* EMERALD — original, forest/finance-green. */
[data-palette="emerald"][data-mode="dark"]{
  --n950:#081410; --card:#0B1913; --card2:#0F2018; --card3:#14291F;
  --primary:#2FBF8F; --primary-text:#052014;
  --purple:#6FB98C; --success:#3ED598; --warn:#E8B44A; --danger:#E15B5B;
  --text:#E5F2EB; --muted:#769D8B; --border:rgba(94,138,117,.22);
}
[data-palette="emerald"][data-mode="light"]{
  --n950:#F4FAF6; --card:#FFFFFF; --card2:#EBF5EF; --card3:#DEEEE4;
  /* primary darkened from spec #1F9E73 → #18855F to reach AA 4.5:1 on white
     (spec value measured 3.4:1, below AA for button labels) */
  --primary:#18855F; --primary-text:#FFFFFF;
  --purple:#4C8F68; --success:#188A5E; --warn:#B87A17; --danger:#C43D3D;
  --text:#0F2A1C; --muted:#4C6B5A; --border:rgba(15,42,28,.12);
}

/* SLATE — sourced from 5 user hexes: #708090 Slate Grey, #1F2A37 Charcoal Navy,
   #F4F1EC Warm Off-White, #6BAED6 Sky Blue (primary), #E8B4B8 Dusty Rose.
   Dusty rose is NOT used — danger overridden to red/rust for cross-palette
   semantic consistency (dusty rose read too soft next to the danger convention
   in the other 4 palettes; no --rose token added, per handoff decision). */
[data-palette="slate"][data-mode="dark"]{
  --n950:#171F29; --card:#1F2A37; --card2:#283443; --card3:#323F4F;
  --primary:#6BAED6; --primary-text:#0D1D28;
  --purple:#8FA3B8; --success:#4ADE80; --warn:#FBBF24; --danger:#E15C4F;
  --text:#F4F1EC; --muted:#9FADBA; --border:rgba(112,128,144,.25);
}
[data-palette="slate"][data-mode="light"]{
  --n950:#F4F1EC; --card:#FFFFFF; --card2:#EAE6DE; --card3:#DCD6CA;
  --primary:#3A7CA5; --primary-text:#FFFFFF;
  --purple:#5C6B7A; --success:#1D9A56; --warn:#B4780F; --danger:#C4392E;
  --text:#1F2A37; --muted:#4F5D6B; --border:rgba(31,42,55,.14);
  /* Weakest light primary: primary text needs a stronger pull to pass on --card2 tints. */
  --primary-ink:color-mix(in srgb, var(--primary) 70%, var(--text));
}

/* HARVEST — sourced from 5 user hexes: #264653 Dark Teal, #2A9D8F Persian Green
   (primary), #E9C46A Pale Gold, #F4A261 Sandy Orange, #E76F51 Burnt Sienna.
   Neutrals are original — none of the 5 source hexes was dark/light enough to
   serve as a surface colour. */
[data-palette="harvest"][data-mode="dark"]{
  --n950:#12100D; --card:#1A1611; --card2:#221D16; --card3:#2B241A;
  --primary:#2A9D8F; --primary-text:#052420;
  --purple:#264653; --success:#2A9D8F; --warn:#E9C46A; --danger:#E76F51;
  --text:#F5EFE4; --muted:#A6957C; --border:rgba(166,149,124,.22);
  /* Raw #2A9D8F is 4.5:1 on its own tint, so badges need a small lift. */
  --success-ink:color-mix(in srgb, var(--success) 90%, var(--text));
}
[data-palette="harvest"][data-mode="light"]{
  --n950:#FBF8F2; --card:#FFFFFF; --card2:#F5EFE2; --card3:#EEE4D0;
  --primary:#217F74; --primary-text:#FFFFFF;
  --purple:#264653; --success:#1F8073; --warn:#B4841F; --danger:#C6543A;
  --text:#211A10; --muted:#6E5F45; --border:rgba(33,26,16,.14);
}

/* ── CSS RESET ── */
*{box-sizing:border-box;margin:0;padding:0;}
html{-webkit-text-size-adjust:100%;}
/* A canvas with no chart drawn yet (empty page) keeps its 300px default width,
   which overflows narrow phones and stretches its card. Charts size themselves. */
canvas{max-width:100%;}
body{
  font-family:var(--font-body);background:var(--bg);color:var(--text);
  min-height:100vh;min-height:100dvh;font-size:15px;line-height:1.5;
  display:flex;flex-direction:row;overflow-x:hidden;
}
::selection{background:#e8457a44;}
img,svg{display:block;max-width:100%;}
/* Unstyled links would otherwise get the browser's blue, unreadable on dark cards. */
a{color:var(--primary-ink);}

/* ── DM Mono for all currency amounts ── */
.mono,.sv,.nw-val,.transfer-amt,.rsu-calculated,
.stat .sv,.dr-v,.amount-val{font-family:var(--font-mono)!important;}
.page-title{font-family:var(--font-display);}
h1,h2,h3,.heading{font-family:var(--font-display);}

/* ── ANIMATIONS ── */
@keyframes fadeUp{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
@keyframes shake{0%,100%{transform:translateX(0)}25%{transform:translateX(-8px)}75%{transform:translateX(8px)}}
@keyframes sheetUp{from{transform:translateY(40px);opacity:.4}to{transform:none;opacity:1}}
