/* ============================================================
   FOCPL DESIGN TOKENS
   ------------------------------------------------------------
   The single source of truth for colour, type scale, spacing,
   radius, shadow and motion. Loaded in EVERY context that
   renders theme markup: the public site (before style.css), the
   board portal, wp-admin (list-table columns, settings screens)
   and the branded login page. Nothing else may declare :root
   tokens — before this file existed the admin screens used
   var(--success) with no :root behind it and rendered nothing.

   History: base block from style.css (2026-03), the v1.3 polish
   layer's :root (2026-04, font stacks + eases + hairline) and
   the round-2 design audit additions (2026-08: small-text ramp,
   space scale, warning/info, on-dark accents) merged into one.
   Palette matched to orangecountync.gov/Library.
   ============================================================ */
:root {
  /* ── Library brand palette ─────────────────────────────────── */
  --ocpl-navy:        #0a2342;
  --ocpl-blue:        #005685;
  --ocpl-blue-dark:   #003f63;
  --ocpl-blue-mid:    #007cc1;
  --ocpl-blue-light:  #e8f3f9;
  --ocpl-blue-pale:   #f0f8fc;
  --ocpl-orange:      #b56016;
  --ocpl-orange-hover:#c96b1a;
  --ocpl-orange-dark: #8f4a10;
  --ocpl-orange-light:#fdf1ea;
  --ocpl-green:       #B4CD95;
  --ocpl-green-dark:  #5a8a2e;

  /* ── Semantic status families ──────────────────────────────── */
  /* Positive / success — a real semantic the brand greens don't cover.
     #2e7d32 passes WCAG AA at small sizes; --ocpl-green-dark does not. */
  --success:          #2e7d32;
  --success-dark:     #1b5e20;
  --success-soft:     #f0f7f1;
  --success-border:   #cde3d0;

  /* Danger / decline — parallels --success; the book-sales "can't accept"
     side needed it and the palette had no red. */
  --danger:           #c62828;
  --danger-dark:      #b71c1c;
  --danger-soft:      #fff5f5;
  --danger-border:    #ffcdd2;

  /* Warning — the portal had invented six ambers (#e65100, #b45309,
     #e0a030, #f0a500, #fff8e1 …) for one meaning. #e65100 is 3.5:1 on
     white and fails AA at badge sizes; #b45309 is 5.2:1 and was already
     in use in inc/admin-columns.php, so it wins on both counts. */
  --warning:          #b45309;
  --warning-dark:     #8a3f07;
  --warning-soft:     #fff8e1;
  --warning-border:   #f3dca0;

  /* Info — replaces the raw #1565c0 the portal badges carried. */
  --info:             #1565c0;
  --info-dark:        #0d47a1;
  --info-soft:        #e3f2fd;
  --info-border:      #bbdefb;

  /* Highlight — emphasis, which is a different semantic from warning even
     though the two share a background (#fff8e1). An emphasis callout and a
     warning badge never sit together, so the shared soft is deliberate; the
     families differ in border and text. Consumers: .fg-breakdown-callout,
     .drive-match-badge. Gold is only ever a FILL (--highlight-fill) or
     text on dark (--highlight-on-dark, the same value) — never text on
     light: it is 2.2:1 on white. */
  --highlight-soft:    #fff8e1;
  --highlight-border:  #f0d060;
  --highlight-text:    #7a5c00;   /* 6.4:1 on --highlight-soft */
  --highlight-fill:    #f5b942;   /* the ONE decorative amber: featured ribbons, callout accent
                                     bars, and (as text) the explorer's stat numbers on dark.
                                     2.2:1 under white — never white text on it; dark text is 10:1 */
  --highlight-on-dark: var(--highlight-fill);

  /* Membership tier palette — the member map's markers and legend. Leaflet
     draws SVG attributes and cannot read var(), so map.php mirrors these
     values as literals from ONE PHP array (commented "= --tier-*"). The
     purple is the system's only purple: keep it here, not scattered. */
  --tier-individual: var(--ocpl-blue);
  --tier-family:     var(--success);
  --tier-lifetime:   var(--accent-purple);

  /* The system's one purple: a category accent on the support / persona
     icon chips, and (by alias) the Lifetime tier. 5.6:1 on its soft. */
  --accent-purple:      #7c4daa;
  --accent-purple-soft: #f0eaf7;

  /* Chart palette — the categorical ramp every Chart.js config already
     uses (round-1 C4), now named so CSS bars, legend swatches and card
     accents draw from the same steps. Canvas cannot read var(): JS arrays
     mirror these values with "= --chart-N" comments. Fills only — none of
     the lighter steps is text-safe on white; numbers beside a coloured bar
     take --ocpl-blue / --success / --text-mid and let the bar carry the hue. */
  --chart-1:   var(--ocpl-blue);        /* #005685 */
  --chart-2:   var(--ocpl-blue-mid);    /* #007cc1 */
  --chart-3:   var(--ocpl-green-dark);  /* #5a8a2e */
  --chart-4:   var(--ocpl-orange);      /* #b56016 */
  --chart-5:   var(--ocpl-green);       /* #B4CD95 */
  --chart-dim: var(--mid-gray);         /* #bcc9d7 — "other", "everything else", de-emphasised peers */

  /* ── Neutrals ──────────────────────────────────────────────── */
  --white:      #ffffff;
  --off-white:  #f7f8f9;
  --light-gray: #eef0f2;
  --mid-gray:   #bcc9d7;   /* decorative only — 1.9:1 on white, never for text */
  --text:       #383838;
  --text-mid:   #686868;   /* 5.0:1 on white */
  --text-light: #6b7785;   /* 4.6:1 on WHITE only — the floor for text at any
                              size (darkened from #96a3b1, which failed AA).
                              On --off-white / --light-gray it drops to ~4.3:1,
                              so muted text on tinted surfaces (table headers,
                              card footers) uses --text-mid instead. */
  --heading:    #171717;
  --border:     #dde3e9;

  /* On-dark text — three levels for copy on --ocpl-blue / --ocpl-navy.
     --text-on-dark-subtle (~2.9:1) is decorative/large only. */
  --text-on-dark:        rgba(255,255,255,0.92);
  --text-on-dark-muted:  rgba(255,255,255,0.68);
  --text-on-dark-subtle: rgba(255,255,255,0.50);

  /* On-dark accents — a positive and a negative that read on the dark
     blue bands (annual-impact trends, history bars). The brand greens
     and oranges are too dark against --ocpl-blue; these were invented
     inline on the third page to need them, so they became tokens. */
  --success-on-dark: #9ede9e;
  --action-on-dark:  #ffc9a8;

  /* ── Semantic aliases ──────────────────────────────────────── */
  --accent:      var(--ocpl-blue);
  --accent-dark: var(--ocpl-blue-dark);
  --accent-soft: var(--ocpl-blue-light);
  --action:      var(--ocpl-orange);
  --action-soft: var(--ocpl-orange-light);

  /* ── Surfaces ──────────────────────────────────────────────── */
  --bg:        var(--white);
  --surface:   var(--off-white);
  --surface-2: #f2f5f7;
  --muted:     var(--text-mid);

  /* ── Shadows ───────────────────────────────────────────────── */
  --shadow-xs:  0 1px 3px rgba(0,0,0,0.07);
  --shadow-sm:  0 2px 8px rgba(0,0,0,0.08);
  --shadow:     0 4px 16px rgba(0,0,0,0.09);
  --shadow-lg:  0 8px 32px rgba(0,0,0,0.12);
  --shadow-xl:  0 16px 48px rgba(0,0,0,0.15);
  --shadow-nav: 0 3px 12px rgba(0,0,0,0.12);

  /* ── Focus ─────────────────────────────────────────────────── */
  --focus-ring:       0 0 0 3px rgba(0,86,133,0.35);
  --focus-ring-inset: inset 0 0 0 2px var(--ocpl-blue);
  --hairline:         1px solid color-mix(in srgb, var(--ocpl-blue) 14%, transparent);

  /* ── Layout ────────────────────────────────────────────────── */
  --max:         1220px;
  --max-mid:     860px;
  --gutter:      24px;
  --section-pad: clamp(48px, 7vw, 80px);

  /* Radius scale. There is deliberately no 6px step: the portal used
     one 64 times and it was snapped to --radius. */
  --radius-sm:   4px;
  --radius:      8px;
  --radius-md:   10px;
  --radius-lg:   14px;
  --radius-xl:   20px;
  --radius-pill: 999px;

  /* Space scale — multiples of 4, no odd values, for the hand-set
     margins the portal used to carry (margin-top:20px ×26, 16px ×17,
     10px ×17). Public-page section rhythm still uses --section-pad. */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;

  /* ── Small-text ramp ───────────────────────────────────────── */
  /* Three sizes replace the ten that had accumulated (.68–.92rem).
     --fs-xs is the FLOOR: no UI text smaller than 12px anywhere,
     including badges, table headers and chart labels. Public-page
     body copy stays at 1rem and headings keep their clamp() ramp. */
  --fs-xs: .75rem;   /* 12px   — badges, eyebrows, table th, chart labels */
  --fs-sm: .82rem;   /* 13.1px — muted text, meta, table cells, helper text */
  --fs-md: .9rem;    /* 14.4px — small body, form inputs, nav items */

  /* ── Motion ────────────────────────────────────────────────── */
  /* Rules of use:
       --transition-fast   colour/border/opacity feedback on small controls
       --transition        hover states on buttons and cards
       --transition-slow   panels, drawers, position changes
       --ease-out          anything ENTERING (reveals): fast start, gentle settle
       --ease-in-out       anything MOVING while visible
     Durations never exceed 0.6s except the stat count-up (1.2s). Animate
     transform/opacity; never width/height/margin. */
  --transition-fast: 0.14s ease;
  --transition:      0.2s ease-in-out;
  --transition-slow: 0.32s ease-in-out;
  --ease-out:        cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-in-out:     cubic-bezier(0.65, 0, 0.35, 1);

  /* ── Typography ────────────────────────────────────────────── */
  --font-sans:    'Open Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  --font-heading: 'Open Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  --font-serif:   'Libre Baskerville', Georgia, 'Times New Roman', serif;
}

/* ── High-contrast mode ──────────────────────────────────────────
   This :root is a CONDITIONAL OVERRIDE, not the default cascade: it
   deliberately swaps the neutrals for harder greys when the OS asks
   for more contrast. Any tool that scrapes tokens from this file must
   read only the top-level block above — the first tokenising script
   run against the theme took these values as the defaults and would
   have mapped #666 to --mid-gray. Lives here rather than in style.css
   so the override follows the tokens into every context. */
@media (prefers-contrast: more) {
  :root { --border: #999; --mid-gray: #666; --text-mid: #333; }
}
