/*
 * SUCEDRA DESIGN TOKENS: the single source of truth.
 *
 * No hex value may appear anywhere outside this file. Tailwind reads these
 * custom properties (tailwind.config.ts); components use Tailwind classes.
 * See DESIGN.md for the reasoning behind every value.
 *
 * Three layers:
 *   1. Primitives: raw scales (--azulejo-800, --space-4). Never used by
 *      components directly.
 *   2. Semantic: purpose names (--color-ink, --color-primary). Components
 *      use these. Dark mode, if it ever ships, remaps ONLY this layer.
 *   3. Component: per-component decisions (--control-h-md, --radius-card).
 *
 * Contrast ratios in comments are WCAG 2.x, measured by src/lib/color.ts
 * (the same code behind `npm run check:contrast`). "g / s / k" = against
 * ground #FAF8F4 / surface #FFFFFF / sunken #F2EFE9. "w" = white text on it.
 * Light theme only. Dark mode is deliberately not shipped (DESIGN.md).
 */

:root {
  /* ===================================================================
   * 1. PRIMITIVES — colour
   * Generated by scripts/generate-scales.ts: one shared OKLCH lightness
   * ladder for every hue; client anchors sit exactly at their nearest step.
   * =================================================================== */

  /* Paper and ink: client anchors */
  --paper-ground: #faf8f4; /* page: warm off-white, reads as paper */
  --paper-surface: #ffffff; /* cards and panels */
  --paper-sunken: #f2efe9; /* wells, table headers, inputs at rest */
  --ink-900: #1a1c19; /* body text: g 16.17 · s 17.16 · k 14.95 */

  /* Stone: warm neutral, ground's hue (84.6°), OKLCH C 0.009 */
  --stone-100: #eeebe5; /* skeleton blocks (non-text) */
  --stone-200: #dcd9d3; /* quiet borders (non-text, decorative) */
  --stone-500: #8c8983; /* control boundaries: g 3.29 · s 3.49 · k 3.04 (UI 3:1) */
  --stone-700: #5c5954; /* muted text: g 6.57 · s 6.97 · k 6.08 */

  /* Azulejo: primary, deep blue-green. Anchor #17505F = 800 */
  --azulejo-50: #eff7fa; /* info badge bg: azulejo-800 on it 8.24 */
  --azulejo-100: #e3edf1; /* text selection: ink on it 14.42 */
  --azulejo-200: #cddce1;
  --azulejo-300: #b0c5cc; /* info badge border (non-text) */
  --azulejo-400: #8faab3;
  --azulejo-500: #6e909a;
  --azulejo-600: #4f7784; /* focus ring: g 4.60 · s 4.88 · k 4.25 (UI 3:1) */
  --azulejo-700: #31616f; /* text: g 6.45 · s 6.84 · k 5.96 · w 6.84 */
  --azulejo-800: #17505f; /* ANCHOR. text: g 8.43 · s 8.94 · k 7.79 · w 8.94 */
  --azulejo-900: #013440; /* hover: w 13.41 */
  --azulejo-950: #00232c; /* pressed: w 16.45 */

  /* Brick: overdue / destructive. Anchor #9B2C2C = 700 */
  --brick-50: #fff3f1; /* overdue badge bg: brick-700 on it 6.93 */
  --brick-100: #ffe4e1;
  --brick-200: #f5cfcb;
  --brick-300: #e7b2ad; /* overdue badge border (non-text) */
  --brick-400: #d4908a;
  --brick-500: #c16e68;
  --brick-600: #ae4e49; /* text: g 4.97 · s 5.27 · k 4.59 · w 5.27 */
  --brick-700: #9b2c2c; /* ANCHOR. text: g 7.10 · s 7.53 · k 6.56 · w 7.53 */
  --brick-800: #800d16; /* destructive hover: w 10.57 */
  --brick-900: #5c0009; /* destructive pressed: w 14.39 */
  --brick-950: #400004;

  /* Ochre: due soon. Anchor #8A5A14 = 600 */
  --ochre-50: #fdf4eb; /* due-soon badge bg: ochre-600 on it 5.44 */
  --ochre-100: #f5e9dc;
  --ochre-200: #e7d6c3;
  --ochre-300: #d4bca2; /* due-soon badge border (non-text) */
  --ochre-400: #be9e7a;
  --ochre-500: #a88152;
  --ochre-600: #8a5a14; /* ANCHOR. text: g 5.57 · s 5.91 · k 5.15 · w 5.91 */
  --ochre-700: #7c4e02; /* text: g 6.72 · s 7.12 · k 6.21 · w 7.12 */
  --ochre-800: #5f3b01; /* text: w 9.94 */
  --ochre-900: #422700;
  --ochre-950: #2d1900;

  /* Forest: compliant. Anchor #2D5F3F = 700 */
  --forest-50: #f0f8f2; /* compliant badge bg: forest-700 on it 6.88 */
  --forest-100: #e4eee6;
  --forest-200: #cfded3;
  --forest-300: #b2c7b8; /* compliant badge border (non-text) */
  --forest-400: #91ad99;
  --forest-500: #70937b;
  --forest-600: #527b5f; /* text: g 4.54 · s 4.82 · k 4.20 (fails on sunken: not for text there) */
  --forest-700: #2d5f3f; /* ANCHOR. text: g 7.02 · s 7.45 · k 6.49 · w 7.45 */
  --forest-800: #1c4f30; /* text: w 9.50 */
  --forest-900: #01381b;
  --forest-950: #002610;

  /* ===================================================================
   * 2. SEMANTIC — colour. Components use only these.
   * =================================================================== */

  --color-ground: var(--paper-ground);
  --color-surface: var(--paper-surface);
  --color-surface-sunken: var(--paper-sunken);

  --color-ink: var(--ink-900);
  --color-ink-muted: var(--stone-700);

  --color-border: var(--stone-200); /* separates surfaces; decorative */
  --color-border-strong: var(--stone-500); /* bounds interactive controls; 3:1 */

  --color-primary: var(--azulejo-800);
  --color-primary-hover: var(--azulejo-900);
  --color-primary-active: var(--azulejo-950);
  --color-on-primary: var(--paper-surface);

  --color-destructive: var(--brick-700);
  --color-destructive-hover: var(--brick-800);
  --color-destructive-active: var(--brick-900);
  --color-on-destructive: var(--paper-surface);

  --color-focus: var(--azulejo-600);
  --color-selection: var(--azulejo-100);
  --color-skeleton: var(--stone-100);

  --color-disabled-bg: var(--paper-sunken);
  --color-disabled-fg: var(--stone-700);
  --color-disabled-border: var(--stone-200);

  /* Compliance status. NEVER conveyed by colour alone: every use carries
     an icon AND a text label (StatusBadge enforces this). */
  --color-overdue-fg: var(--brick-700);
  --color-overdue-bg: var(--brick-50);
  --color-overdue-border: var(--brick-300);
  --color-due-soon-fg: var(--ochre-600);
  --color-due-soon-bg: var(--ochre-50);
  --color-due-soon-border: var(--ochre-300);
  --color-compliant-fg: var(--forest-700);
  --color-compliant-bg: var(--forest-50);
  --color-compliant-border: var(--forest-300);
  /* Upcoming: a scheduled obligation that is not near yet. Deliberately
     calm: warm grey, no hue, so it reads as "in the diary", not as a note
     (info, blue) and not as a warning (due soon, ochre). */
  /* Ink, not stone-700: grey text on a grey tint is the disabled style, and
     an obligation with a date is not disabled. */
  --color-upcoming-fg: var(--ink-900); /* on its bg: 14.42 */
  --color-upcoming-bg: var(--stone-100);
  --color-upcoming-border: var(--stone-200);
  --color-info-fg: var(--azulejo-800);
  --color-info-bg: var(--azulejo-50);
  --color-info-border: var(--azulejo-300);

  /* Dialog backdrop: flat ink at 48%. No blur, ever. */
  --color-scrim: rgb(26 28 25 / 0.48);

  /* ===================================================================
   * TYPOGRAPHY
   * Faces are self-hosted (src/styles/fonts.css), each with metric-matched
   * local fallbacks. system-ui is deliberately absent.
   * =================================================================== */

  /* Each real face is followed by metric-matched fallbacks (fonts.css), so
     text painted before the webfont arrives occupies the same space. */
  --font-display: 'Source Serif 4', 'Source Serif Fallback', 'Source Serif Fallback Android', serif;
  --font-sans: 'IBM Plex Sans', 'Plex Sans Fallback', 'Plex Sans Fallback Android', sans-serif;
  --font-mono: 'IBM Plex Mono', 'Plex Mono Fallback', monospace;

  --weight-regular: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  /* Headings use semibold (600): Source Serif 4 ships at 600 only (font budget, DESIGN.md). */

  /* Mandatory wherever numbers sit in a column: money, dates, %, counts. */
  --numeric-tabular: tabular-nums lining-nums;

  /* Two scales, both modular at 1.200. Not the same scale reflowed: mobile
     is built on a 16px base and tops out lower; desktop is a denser 15px
     base with one more step of heading range. */
  --type-m-n1: 0.8333rem; /* 13.33px */
  --type-m-0: 1rem; /* 16px: body never below this on mobile */
  --type-m-1: 1.2rem; /* 19.2px */
  --type-m-2: 1.44rem; /* 23.04px */
  --type-m-3: 1.728rem; /* 27.65px */
  --type-m-4: 2.0736rem; /* 33.18px */

  --type-d-n1: 0.78125rem; /* 12.5px */
  --type-d-0: 0.9375rem; /* 15px */
  --type-d-1: 1.125rem; /* 18px */
  --type-d-2: 1.35rem; /* 21.6px */
  --type-d-3: 1.62rem; /* 25.92px */
  --type-d-4: 1.944rem; /* 31.1px */
  --type-d-5: 2.3328rem; /* 37.32px */

  /* Semantic type roles: mobile mapping (desktop remaps below) */
  --text-caption: var(--type-m-n1);
  --text-body: var(--type-m-0);
  --text-lead: var(--type-m-1);
  --text-h4: var(--type-m-0);
  --text-h3: var(--type-m-1);
  --text-h2: var(--type-m-2);
  --text-h1: var(--type-m-3);
  --text-display: var(--type-m-4);
  /* Form controls are 16px at every size: iOS Safari zooms on focus below it. */
  --text-control: 1rem;

  --leading-tight: 1.2;
  --leading-snug: 1.35;
  --leading-body: 1.5;

  --tracking-display: -0.01em;
  --tracking-caps: 0.04em;

  /* ===================================================================
   * SPACING: 4px base, 0 to 96px
   * =================================================================== */

  --space-0: 0px;
  --space-px: 1px;
  --space-0_5: 2px;
  --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;
  --space-20: 80px;
  --space-24: 96px;

  /* ===================================================================
   * 3. COMPONENT TOKENS: sizes, density, radii, elevation, motion
   * =================================================================== */

  /* Layout geometry: also hard-coded in index.html's static shell, which
     must match exactly. Change both together. */
  --size-sidebar: 256px;
  --size-bottombar: 64px;
  --size-safe-bottom: env(safe-area-inset-bottom, 0px);
  --size-bottombar-total: calc(var(--size-bottombar) + var(--size-safe-bottom));
  --size-touch: 44px; /* minimum touch target */
  --size-loader: 12rem; /* centred session-check placeholder (static shell too) */
  --size-icon-sm: 16px;
  --size-icon: 20px;
  --size-icon-lg: 32px;
  --size-content: 72rem;
  --size-prose: 40rem;
  --size-dialog: 32rem;
  --size-table-max-h: 32rem;
  --size-dialog-max-h: calc(100dvh - 2 * var(--space-4));
  --size-menu-min: 12rem;

  /* Density: mobile is roomy and touch-first */
  --control-h-sm: 44px;
  --control-h-md: 48px;
  --control-h-lg: 52px;
  --row-h: 52px;
  --cell-x: var(--space-3);
  --cell-y: var(--space-3);

  /* Radii: nothing above 8px, ever */
  --radius-badge: 2px;
  --radius-control: 4px;
  --radius-card: 6px;
  --radius-max: 8px;

  /* Elevation: exactly two levels, only for things that genuinely float.
     Surfaces separate by border and background, never by shadow. */
  --shadow-float: 0 1px 2px rgb(26 28 25 / 0.06), 0 4px 12px rgb(26 28 25 / 0.08);
  --shadow-overlay: 0 2px 4px rgb(26 28 25 / 0.08), 0 16px 40px rgb(26 28 25 / 0.14);

  /* Motion: ease-out only; no spring, no bounce */
  --duration-state: 120ms; /* hover, press, focus, toggle */
  --duration-enter: 180ms; /* dialogs, menus, toasts appearing */
  --ease-out: cubic-bezier(0, 0, 0.2, 1);
}

/* Desktop (Tailwind md, 768px): denser type and controls. Keep this
   breakpoint in step with tailwind.config.ts screens.md. */
@media (min-width: 768px) {
  :root {
    --text-caption: var(--type-d-n1);
    --text-body: var(--type-d-0);
    --text-lead: var(--type-d-1);
    --text-h4: var(--type-d-1);
    --text-h3: var(--type-d-2);
    --text-h2: var(--type-d-3);
    --text-h1: var(--type-d-4);
    --text-display: var(--type-d-5);

    --control-h-sm: 32px;
    --control-h-md: 36px;
    --control-h-lg: 44px;
    --row-h: 40px;
    --cell-y: var(--space-2);
  }
}

/* Reduced motion: every duration collapses to zero, and a global guard
   catches anything that animates outside the tokens. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --duration-state: 0ms;
    --duration-enter: 0ms;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
