/* ──────────────────────────────────────────────────────────────
   Themes — each one repaints the whole app.

   A theme declares only five things:
     --bg-0  deepest background colour
     --bg-1  gradient partner
     --bg-2  the glow in the corner
     --tint  the hue that bleeds into every card surface
     --accent / --accent-ink

   Everything else — text, borders, shadows, chart colours — is
   derived from [data-mode], so a new theme is five lines.
   ────────────────────────────────────────────────────────────── */

/* ── derived: dark modes ────────────────────────────────────── */

html[data-mode="dark"] {
  color-scheme: dark;

  --surface-1: color-mix(in oklab, var(--tint) 14%, #16161a);
  --surface-2: color-mix(in oklab, var(--tint) 16%, #1e1e23);
  --surface-3: color-mix(in oklab, var(--tint) 20%, #2a2a31);
  --surface-glass: color-mix(in oklab, var(--bg-0) 72%, transparent);
  --surface-bar: color-mix(in oklab, var(--tint) 7%, #121216);

  --line: rgba(255, 255, 255, 0.10);
  --line-strong: rgba(255, 255, 255, 0.19);
  --text: #f3f2ef;
  --text-dim: color-mix(in oklab, var(--tint) 18%, #9c9ca6);
  --danger: #ff7272;
  --good: #58d98a;
  --shadow: 0 18px 44px rgba(0, 0, 0, 0.5);
  --shadow-sm: 0 2px 10px rgba(0, 0, 0, 0.3);

  --accent-text: var(--accent);
  --accent-soft: color-mix(in oklab, var(--accent) 16%, transparent);
  --accent-line: color-mix(in oklab, var(--accent) 42%, transparent);

  /* chart palette, validated against a dark surface */
  --viz-1: #3987e5;
  --viz-2: #d95926;
  --viz-seq: #3987e5;
  --viz-pos: #3987e5;
  --viz-neg: #e66767;
  --viz-axis: rgba(255, 255, 255, 0.15);
}

/* ── derived: light modes ───────────────────────────────────── */

html[data-mode="light"] {
  color-scheme: light;

  --surface-1: color-mix(in oklab, var(--tint) 7%, #ffffff);
  --surface-2: color-mix(in oklab, var(--tint) 11%, #f8f8f6);
  --surface-3: color-mix(in oklab, var(--tint) 16%, #ececeb);
  --surface-glass: color-mix(in oklab, var(--bg-0) 78%, transparent);
  --surface-bar: color-mix(in oklab, var(--tint) 5%, #ffffff);

  --line: rgba(0, 0, 0, 0.10);
  --line-strong: rgba(0, 0, 0, 0.18);
  --text: #17171b;
  --text-dim: color-mix(in oklab, var(--tint) 22%, #6b6b74);
  --danger: #cf3030;
  --good: #0a9b3f;
  --shadow: 0 16px 38px rgba(31, 27, 20, 0.14);
  --shadow-sm: 0 1px 4px rgba(31, 27, 20, 0.1);

  --accent-text: color-mix(in oklab, var(--accent) 88%, #000);
  --accent-soft: color-mix(in oklab, var(--accent) 14%, transparent);
  --accent-line: color-mix(in oklab, var(--accent) 48%, transparent);

  /* chart palette, validated against a light surface */
  --viz-1: #2a78d6;
  --viz-2: #eb6834;
  --viz-seq: #2a78d6;
  --viz-pos: #2a78d6;
  --viz-neg: #e34948;
  --viz-axis: rgba(0, 0, 0, 0.14);
}

html { --viz-ink: var(--text); --viz-muted: var(--text-dim); }

/* ══════════════════════════════════════════════════════════════
   The themes themselves
   ══════════════════════════════════════════════════════════════ */

html[data-theme="midnight"] {
  --bg-0: #080b16; --bg-1: #0e1427; --bg-2: #1e2f63;
  --tint: #3b5ba8; --accent: #7aa2ff; --accent-ink: #060a18;
}

html[data-theme="carbon"] {
  --bg-0: #0b0b0c; --bg-1: #121214; --bg-2: #2b2b30;
  --tint: #6e6e78; --accent: #c2f04a; --accent-ink: #11160a;
}

html[data-theme="forest"] {
  --bg-0: #04100a; --bg-1: #081b11; --bg-2: #14492a;
  --tint: #2f7d4e; --accent: #7ee787; --accent-ink: #052010;
}

html[data-theme="ocean"] {
  --bg-0: #01131d; --bg-1: #031f2e; --bg-2: #0a4e6b;
  --tint: #1f7fa3; --accent: #4ad7f0; --accent-ink: #022029;
}

html[data-theme="sunset"] {
  --bg-0: #160506; --bg-1: #260b09; --bg-2: #6b2614;
  --tint: #a85634; --accent: #ffa552; --accent-ink: #26100a;
}

html[data-theme="crimson"] {
  --bg-0: #120509; --bg-1: #1f0810; --bg-2: #581226;
  --tint: #9c2f4a; --accent: #ff7a8a; --accent-ink: #210610;
}

html[data-theme="violet"] {
  --bg-0: #0c0618; --bg-1: #150b2b; --bg-2: #3a1d6e;
  --tint: #6b46c1; --accent: #c4a2ff; --accent-ink: #130823;
}

html[data-theme="granite"] {
  --bg-0: #0f1011; --bg-1: #17191b; --bg-2: #333a41;
  --tint: #5d6b78; --accent: #9fd8ff; --accent-ink: #0a1620;
}

html[data-theme="chalk"] {
  --bg-0: #eeeeec; --bg-1: #f7f7f5; --bg-2: #ffffff;
  --tint: #8c8c86; --accent: #22222a; --accent-ink: #ffffff;
}

html[data-theme="arctic"] {
  --bg-0: #e2edfa; --bg-1: #eef5fd; --bg-2: #ffffff;
  --tint: #74a4d8; --accent: #2a78d6; --accent-ink: #ffffff;
}

html[data-theme="sand"] {
  --bg-0: #f0e6d7; --bg-1: #f8f1e6; --bg-2: #fffbf4;
  --tint: #c0a076; --accent: #b4651a; --accent-ink: #fff6ec;
}

html[data-theme="bloom"] {
  --bg-0: #fae2ec; --bg-1: #fdeef4; --bg-2: #fffbfd;
  --tint: #dd94b2; --accent: #c2366b; --accent-ink: #fff2f7;
}

/* ── switching themes ───────────────────────────────────────────
   For half a second after a theme is picked, everything that carries a
   colour is given a transition. The whole interface — background, cards,
   text, borders, even the chart bars — eases into the new palette instead
   of snapping to it. The class is removed as soon as the tween is over,
   so nothing else in the app pays for these rules.
   ────────────────────────────────────────────────────────────── */

/* A colour cross-fade is not motion, so this one survives the system's
   "reduce motion" setting. Its selector outranks the blanket rule in
   base.css, which is what keeps it alive there. */
html.is-theming,
html.is-theming *,
html.is-theming *::before,
html.is-theming *::after {
  transition:
    background-color 480ms cubic-bezier(0.4, 0, 0.2, 1),
    background-image 480ms cubic-bezier(0.4, 0, 0.2, 1),
    color 420ms cubic-bezier(0.4, 0, 0.2, 1),
    border-color 480ms cubic-bezier(0.4, 0, 0.2, 1),
    fill 480ms cubic-bezier(0.4, 0, 0.2, 1),
    stroke 480ms cubic-bezier(0.4, 0, 0.2, 1),
    box-shadow 480ms cubic-bezier(0.4, 0, 0.2, 1) !important;
}

/* The swatch you tapped gives a little nod — that one is motion, so it
   does respect the system setting. */
@media (prefers-reduced-motion: no-preference) {
  .theme-card.is-picking { animation: theme-pick 460ms cubic-bezier(0.34, 1.4, 0.5, 1); }

  @keyframes theme-pick {
    0% { transform: scale(1); }
    38% { transform: scale(1.07); }
    100% { transform: scale(1); }
  }
}

/* ── the painted background ─────────────────────────────────── */

body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(90rem 55rem at 82% -15%, var(--bg-2), transparent 62%),
    radial-gradient(70rem 48rem at -10% 108%, var(--bg-2), transparent 58%),
    linear-gradient(168deg, var(--bg-1), var(--bg-0) 72%);
}

/* A faint grain so big flat gradients do not band on wide screens.
   Only on wide screens: it is one more full-viewport composited layer,
   and a phone has neither the banding problem nor the memory to spare. */
@media (min-width: 900px) {
  body::after {
    content: '';
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    opacity: 0.4;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)' opacity='.035'/%3E%3C/svg%3E");
  }

  html[data-mode="light"] body::after { opacity: 0.55; }
}
