/* ===========================================================================
   Praiseach — design tokens. The single source of truth for colour, type,
   spacing, radius, elevation and motion.

   Rules this file exists to enforce (see tools/lint-tokens.js, which fails the
   build if styles.css breaks them):

     ACCENT      one hue, and it marks WHERE YOU ACT. In practice that is the
                 primary button (Home's Start), the state of a control you
                 operate (a switch that is on, a slider's thumb), and the focus
                 ring. Never a background, never a gradient, never a fill that
                 merely reports a value — a progress bar, a slider's filled
                 track and a chart are all readouts, so they are neutral.
                 On a screen with no action to take, no accent appears at all.
     CATEGORY    up to six genuinely categorical hues. They appear only in the
                 balance chart and as a 2-3px edge marker on a task card.
                 Never a fill, never on Home. (Used from Phase 2.)
     DIFFICULTY  one hue at three intensities. Difficulty is ordinal, not
                 categorical, so it gets a sequential ramp rather than three
                 unrelated hues — and it is always paired with the three-dot
                 marker in .diffdots so it survives greyscale and colour
                 blindness. Deliberately off the alarm palette: hard work is
                 demanding, not dangerous.
     DANGER      red, and red appears nowhere else. Destructive confirmation
                 only — deleting a module, deleting an account. Never
                 "overdue", never "hard", never "behind".

   Theme resolution, in precedence order:
     1. :root[data-theme="dark"|"light"]   explicit choice, set by the toggle
     2. prefers-color-scheme                the system, when no choice is stored
     3. :root                               light, as the base definition
   Every token is defined on bare :root first so nothing is ever undefined.
   =========================================================================== */

:root {
  color-scheme: light;

  /* ---- neutrals -------------------------------------------------------- */
  --bg: #F6F7F9;
  --surface: #FFFFFF;
  --surface-2: #F0F1F5;
  --surface-sunken: #EAEBF0;
  --border: #E2E4EA;
  --border-strong: #CBCDD7;
  /* The boundary of a form control, and only that. --border is a separator
     between areas, which WCAG does not ask to be visible; the edge of an input
     IS the thing that tells you an input is there, so 1.4.11 wants it at 3:1
     against both the field's own fill and the card behind it. Keeping the two
     jobs on separate tokens is what stops every hairline on the page having to
     darken to satisfy a rule that was only ever about controls. */
  --border-control: #868992;

  --text: #191A20;
  --text-secondary: #53555E;
  /* Was #83868F, which read 3.39:1 on --bg and 3.06:1 on --surface-sunken —
     under the 4.5:1 body-text floor everywhere it appeared, and it appears on
     126 rules. Darkened along the same hue until the worst pairing (on
     --surface-sunken, in .dg-block.rest) clears 4.5:1 at 4.53. */
  --text-muted: #686A73;
  --text-on-accent: #FFFFFF;

  /* ---- accent: "the action to take now", and nothing else --------------- */
  --accent: #4256CE;
  --accent-hover: #35459F;
  --accent-quiet: #ECEEFB;   /* focus ring / selected row tint only */

  /* ---- difficulty: one hue, three intensities, easy -> hard ------------- */
  --difficulty-1: #B3A2DC;
  --difficulty-2: #8A6BC9;
  --difficulty-3: #5B3BA4;
  --difficulty-track: #E6E2F2;

  /* ---- categories: Phase 2. Six hues, used in the balance chart and as a
         2-3px card edge marker. Never fills. ---------------------------- */
  --category-1: #3C6DB0;
  --category-2: #008B73;   /* validated: see docs/CHANGELOG.md */
  --category-3: #A06A2E;
  --category-4: #7A4E9E;
  --category-5: #4E7A3C;
  --category-6: #9B4A73;

  /* ---- danger: destructive confirmation only --------------------------- */
  --danger: #B5352C;
  --danger-hover: #93291F;
  --danger-quiet: #FBEDEC;
  --on-danger: #FFFFFF;

  /* ---- elevation ------------------------------------------------------- */
  --shadow-sm: 0 1px 2px rgba(16, 18, 28, 0.06);
  --shadow-md: 0 4px 16px rgba(16, 18, 28, 0.08);

  /* =======================================================================
     Everything below is theme-independent.
     ======================================================================= */

  /* ---- type: four sizes, two weights. That is the whole scale. ---------- */
  --font-xl: 1.75rem;    /* 28px — reserved for the one thing on Home       */
  --font-lg: 1.25rem;    /* 20px — screen and card headings                 */
  --font-base: 0.9375rem;/* 15px — body                                     */
  --font-sm: 0.8125rem;  /* 13px — meta, labels, secondary detail           */

  /* One exception to the four sizes, and it is a physical one: a quarter-hour
     block in the day grid is about 11px tall, so no size in the scale above
     fits inside it. --font-micro exists for .dg-block.micro / .nano and
     nothing else; the lint rule treats it as the only permitted extra step. */
  --font-micro: 0.625rem;  /* 10px — dense day-grid slots only               */

  --weight-body: 400;
  --weight-emphasis: 600;

  --leading-tight: 1.25;
  --leading-base: 1.5;

  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  /* ---- spacing: 4px base, 8px rhythm ----------------------------------- */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 48px;
  --space-16: 64px;

  /* ---- radius ---------------------------------------------------------- */
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 16px;
  --radius-full: 999px;

  /* ---- motion: calm. 150-250ms, ease-out, no bounce anywhere. ----------- */
  --duration-fast: 150ms;
  --duration-base: 200ms;
  --duration-slow: 250ms;
  --ease-out: cubic-bezier(0.22, 0.61, 0.36, 1);

  /* ---- touch ----------------------------------------------------------- */
  --tap-min: 44px;
}

/* Dark, chosen by the system, unless an explicit light choice is stored. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;

    --bg: #0D0E12;
    --surface: #15171D;
    --surface-2: #1D2027;
    --surface-sunken: #101218;
    --border: #262931;
    --border-strong: #363A45;
    --border-control: #666C7A;

    --text: #ECEDF1;
    --text-secondary: #A6A9B3;
    /* Was #747883 — 4.37:1 on --bg and 3.54:1 on --difficulty-track, so it
       missed 4.5:1 in dark too, just less obviously than in light. */
    --text-muted: #868A94;
    --text-on-accent: #0B0D14;

    --accent: #8098FF;
    --accent-hover: #9DAFFF;
    --accent-quiet: #1A1F35;

    --difficulty-1: #574A7C;
    --difficulty-2: #8A72CE;
    --difficulty-3: #BFA6F2;
    --difficulty-track: #24222F;

    --category-1: #6E9BD8;
    --category-2: #52C8B0;
    --category-3: #C79A56;
    --category-4: #A683C9;
    --category-5: #82AE6C;
    --category-6: #C57C9F;

    --danger: #E0776D;
    --danger-hover: #EC9289;
    --danger-quiet: #2A1917;
    /* White on this red is 2.99:1 — below even the 3:1 large-text floor, on the
       Delete account button of all things. The red is the destructive signal and
       is worth keeping exactly as it is, so the ink flips instead: 6.50:1. */
    --on-danger: #0B0D14;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.45);
  }
}

/* Explicit dark choice — wins over a light system preference. */
:root[data-theme="dark"] {
  color-scheme: dark;

  --bg: #0D0E12;
  --surface: #15171D;
  --surface-2: #1D2027;
  --surface-sunken: #101218;
  --border: #262931;
  --border-strong: #363A45;
  --border-control: #666C7A;

  --text: #ECEDF1;
  --text-secondary: #A6A9B3;
  --text-muted: #868A94;
  --text-on-accent: #0B0D14;

  --accent: #8098FF;
  --accent-hover: #9DAFFF;
  --accent-quiet: #1A1F35;

  --difficulty-1: #574A7C;
  --difficulty-2: #8A72CE;
  --difficulty-3: #BFA6F2;
  --difficulty-track: #24222F;

  --category-1: #6E9BD8;
  --category-2: #52C8B0;
  --category-3: #C79A56;
  --category-4: #A683C9;
  --category-5: #82AE6C;
  --category-6: #C57C9F;

  --danger: #E0776D;
  --danger-hover: #EC9289;
  --danger-quiet: #2A1917;
  --on-danger: #0B0D14;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.45);
}

/* ===========================================================================
   Legacy aliases.

   styles.css still carries the landing page, which keeps its own darker,
   more cinematic look and is deliberately NOT part of the Phase 1 refactor.
   These names are what it reads. They are defined in terms of the tokens
   above so the two never drift apart, and the lint rule treats them as the
   only permitted legacy surface.
   =========================================================================== */
:root {
  --panel: var(--surface);
  --panel-2: var(--surface-2);
  --line: var(--border);
  --muted: var(--text-muted);
  --radius: var(--radius-lg);
  --shadow: var(--shadow-md);

  /* The landing keeps a second decorative hue. It must never appear inside
     the app shell — the lint rule enforces that. */
  --accent-2: #8A6BC9;

  /* Difficulty, under their old names, so existing markup keeps working
     while screens migrate one at a time. */
  --hard: var(--difficulty-3);
  --medium: var(--difficulty-2);
  --easy: var(--difficulty-1);
}

/* ===========================================================================
   Motion preference. One global rule rather than per-component opt-ins, so a
   new animation can't quietly skip it.
   =========================================================================== */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
