/**
 * HES semantic color system - maps raw color tokens (tokens.css) onto
 * meaning. Nothing here introduces a new raw value; every declaration
 * below is a var() reference to a token defined in tokens.css.
 *
 * Two independent dark mechanisms coexist here, deliberately:
 * - `.hes-dark` (scoped class) - always-dark sections regardless of site
 *   theme (the homepage hero, the footer). Unaffected by the toggle.
 * - `[data-theme="dark"]` (root attribute, set by the site-wide toggle -
 *   see components/base/theme-toggle/ and html.html.twig) - the whole
 *   page goes dark. Its background/surface/text/border values are
 *   identical to `.hes-dark`'s on purpose: when the toggle is on, the
 *   hero/footer's local `.hes-dark` becomes a no-op instead of a visible
 *   seam of "extra-dark on already-dark".
 *
 * WCAG AA contrast (verified, see 02-color-system.md for the full table):
 * - text-primary / text-secondary pass 4.5:1 on both background and
 *   surface, in both the light and dark variants.
 * - --hes-color-primary is gold-400 (a fill-only variant, ~2% lighter than
 *   gold-500), specifically so navy-900 text on it clears normal-text AA
 *   (4.91:1) with no large-text dependency. It is a FILL color (buttons,
 *   badges) - never text/link color; white text on it still fails (2.95:1)
 *   regardless of shade, so --hes-color-text-on-primary (navy-900) is the
 *   only approved text-on-primary combination.
 * - --hes-color-primary-large-text is gold-500 - the original, slightly
 *   darker shade, kept for the existing case-study stat-number pattern
 *   (large display numerals). It passes AA's large-text threshold
 *   (3.25:1, needs 3:1) but fails normal-text - only ever use it at or
 *   above 18pt/2.25rem, matching current production usage. Never use it
 *   for links or body-sized text; use --hes-color-secondary or
 *   --hes-color-warning instead.
 * - --hes-color-warning (gold-700) is a distinct, darker gold from both
 *   primary variants specifically so a warning badge never looks like a
 *   CTA button. It passes AA as text on white (5.16:1) and as white-on-
 *   fill (5.16:1).
 * - --hes-color-link / --hes-color-link-hover exist separately from
 *   --hes-color-secondary because they serve different roles: secondary
 *   is a FILL color (button backgrounds) always paired with
 *   --hes-color-text-on-secondary, so its own contrast against the page
 *   background is irrelevant - it never sits directly on it. link/
 *   link-hover ARE used as plain text/outline color directly on the page
 *   background (nav items, in-content links, focus rings), so unlike
 *   secondary they must change value when the page background itself
 *   goes dark. Light mode reuses secondary's navy-700 (10.37:1 on white)
 *   for both by default; the dark override below repoints them at
 *   gold-400/gold-500 instead of trying to find one navy shade that
 *   works as text on both a white and a navy-900 page.
 */

:root {
  /* Core roles */
  --hes-color-primary: var(--hes-color-gold-400);
  --hes-color-primary-large-text: var(--hes-color-gold-500);
  --hes-color-text-on-primary: var(--hes-color-navy-900);
  --hes-color-secondary: var(--hes-color-navy-700);
  --hes-color-text-on-secondary: var(--hes-color-white);

  /* Text/outline-on-background accent - see file header note on why this
     is separate from --hes-color-secondary. */
  --hes-color-link: var(--hes-color-secondary);
  --hes-color-link-hover: var(--hes-color-navy-800);

  /* Backgrounds and surfaces */
  --hes-color-background: var(--hes-color-white);
  --hes-color-background-dark: var(--hes-color-navy-900);
  --hes-color-surface: var(--hes-color-navy-050);

  /* Text */
  --hes-color-text-primary: var(--hes-color-navy-900);
  --hes-color-text-secondary: var(--hes-color-gray-600);

  /* Structure */
  --hes-color-border: var(--hes-color-gray-100);

  /* Status */
  --hes-color-success: var(--hes-color-green-700);
  --hes-color-success-icon: var(--hes-color-green-600);
  --hes-color-warning: var(--hes-color-gold-700);
  --hes-color-text-on-warning: var(--hes-color-white);
  --hes-color-error: var(--hes-color-red-600);
}

/* Dark scope - apply `.hes-dark` to an always-dark section wrapper
   (currently the homepage hero and the site footer). See file header. */
.hes-dark {
  --hes-color-background: var(--hes-color-background-dark);
  --hes-color-surface: var(--hes-color-navy-800);
  --hes-color-text-primary: var(--hes-color-white);
  --hes-color-text-secondary: var(--hes-color-navy-100);
  --hes-color-border: var(--hes-color-navy-100);
  --hes-color-link: var(--hes-color-primary);
  --hes-color-link-hover: var(--hes-color-white);
}

/*
 * Site-wide dark theme - set by the real, visitor-facing toggle
 * (components/base/theme-toggle/), which stamps `data-theme="dark"` on
 * <html>. Same background/surface/text/border values as `.hes-dark`
 * above, by design (see file header). Additionally re-themes status
 * colors (error/success/warning), which the `.hes-dark` scope never
 * needed to since it's only ever applied to the hero/footer, neither of
 * which uses status colors.
 *
 * WCAG AA re-verified for this mode specifically, not assumed from the
 * light-mode numbers (computed via the standard relative-luminance
 * formula against the actual backgrounds each color renders on):
 * - text-primary (white) / text-secondary (navy-100) on background
 *   (navy-900) or surface (navy-800): 14.5:1 / 10.7:1 - same numbers as
 *   `.hes-dark`, already verified.
 * - link (gold-400) on background: 4.91:1 - passes normal-text AA. This
 *   is the same gold-400/navy-900 pair already verified for
 *   text-on-primary buttons, just with the roles reversed (contrast is
 *   symmetric), so no new pairing was introduced.
 * - link-hover (white) on background: 14.5:1.
 * - error (red-300) / success (green-300) / warning (gold-300) on
 *   background: 7.23:1 / 7.86:1 / 9.06:1 - all comfortably clear 4.5:1.
 *   These three feed both form-field.css's on-background error text and
 *   badge.css's dark-mode tint text (see that file's own override block
 *   for the composited-background numbers, which differ from these
 *   flat-background ones).
 */
:root[data-theme="dark"] {
  --hes-color-background: var(--hes-color-background-dark);
  --hes-color-surface: var(--hes-color-navy-800);
  --hes-color-text-primary: var(--hes-color-white);
  --hes-color-text-secondary: var(--hes-color-navy-100);
  --hes-color-border: var(--hes-color-navy-100);
  --hes-color-link: var(--hes-color-primary);
  --hes-color-link-hover: var(--hes-color-white);
  --hes-color-error: var(--hes-color-red-300);
  --hes-color-success: var(--hes-color-green-300);
  --hes-color-warning: var(--hes-color-gold-300);

  /*
   * Olivero itself, not hes_theme - fixes every core-rendered surface
   * this theme doesn't have its own template/component for (login,
   * password reset, user profile, comments, tables, admin-facing
   * pages...). Found via /user/login: Olivero's own component CSS
   * (text-content.css, form.css, form-text.css, table.css, etc. -
   * dozens of files) sets `color` directly using THESE variables, not
   * hes_theme's tokens - typography.css's html-body/h1-h6/a overrides
   * only reach plain tags, not Olivero's many class-scoped rules
   * (confirmed the hard way: block-hes-theme-address's text was still
   * invisible after those fixes, traced to `.text-content, .cke_editable
   * { color: var(--color-text-neutral-medium) }` in Olivero's own
   * text-content.css). Patching every such Olivero class individually
   * is a losing game - redefining the variables they all read from
   * fixes the whole set at once, current and future.
   *
   * Olivero's own gray scale (variables.css) is a symmetric 10-stop
   * ramp built from one hue/saturation at 10 lightness stops that
   * mirror around the middle (5%<->97%, 11%<->93%, 20%<->88%, 44%<->72%,
   * 57%<->63%) - i.e. Olivero already designed it to be invertible, this
   * just does that inversion. --color--gray-hue/-saturation are left
   * alone (only lightness flips), so hue/tone stays consistent with
   * light mode. --color--black/--color--white/--color--red are NOT
   * remapped - those are fixed contrast-on-colored-fill values (e.g.
   * white text on a blue button), not page-background-relative, and
   * stay correct as-is in both modes.
   */
  --color--gray-5: hsl(var(--color--gray-hue), var(--color--gray-saturation), 97%);
  --color--gray-10: hsl(var(--color--gray-hue), var(--color--gray-saturation), 93%);
  --color--gray-20: hsl(var(--color--gray-hue), var(--color--gray-saturation), 88%);
  --color--gray-45: hsl(var(--color--gray-hue), var(--color--gray-saturation), 72%);
  --color--gray-60: hsl(var(--color--gray-hue), var(--color--gray-saturation), 63%);
  --color--gray-65: hsl(var(--color--gray-hue), var(--color--gray-saturation), 57%);
  --color--gray-70: hsl(var(--color--gray-hue), var(--color--gray-saturation), 44%);
  --color--gray-90: hsl(var(--color--gray-hue), var(--color--gray-saturation), 20%);
  --color--gray-95: hsl(var(--color--gray-hue), var(--color--gray-saturation), 11%);
  --color--gray-100: hsl(var(--color--gray-hue), var(--color--gray-saturation), 5%);

  /* Olivero's link-ish accent text (node teaser titles, search result
     links, feed links...) reads --color-text-primary-medium/-loud, not
     --color-text-neutral-*, so the gray-scale inversion above doesn't
     touch it - repoint it at hes_theme's own dark-mode link colors
     (already WCAG-AA-verified above) instead of Olivero's static blue,
     for the same reason html a already does for plain anchors. */
  --color-text-primary-medium: var(--hes-color-link);
  --color-text-primary-loud: var(--hes-color-link-hover);
}

/*
 * Native form controls - a gap the gray-scale inversion above doesn't
 * cover. Olivero's form-text.css/form-select.css set `color:
 * var(--color-text-neutral-loud)` (correctly inverted to near-white by
 * the gray-scale remap above) but pair it with a hardcoded `background-
 * color: var(--color--white)` - not part of the gray scale, deliberately
 * left unremapped there since it's also used for legitimate fixed-white-
 * on-colored-fill cases (e.g. button text). Result: white text on a
 * white input background, functionally invisible - confirmed via a real
 * contact-form field (computed color rgb(246,248,248) on background
 * rgb(255,255,255)), reported directly against the live dark-mode site.
 * Selector list matches Olivero's form-text.css exactly (specificity
 * 0,2,0 vs its 0,1,0, so this wins regardless of stylesheet order);
 * `select` isn't in that list but gets the same fix for consistency,
 * from form-select.css's identical pattern.
 */
[data-theme="dark"] [type="color"],
[data-theme="dark"] [type="date"],
[data-theme="dark"] [type="datetime-local"],
[data-theme="dark"] [type="email"],
[data-theme="dark"] [type="month"],
[data-theme="dark"] [type="number"],
[data-theme="dark"] [type="password"],
[data-theme="dark"] [type="search"],
[data-theme="dark"] [type="tel"],
[data-theme="dark"] [type="text"],
[data-theme="dark"] [type="time"],
[data-theme="dark"] [type="url"],
[data-theme="dark"] [type="week"],
[data-theme="dark"] textarea,
[data-theme="dark"] select {
  background-color: var(--hes-color-surface);
  color: var(--hes-color-text-primary);
}

/*
 * `.messages` (status/error/warning banners) and `.skip-link` are both
 * an intentionally *always-dark* badge in Olivero, regardless of page
 * theme - `color: var(--color--white)` paired with `background-color:
 * var(--color--gray-5)`. The gray-scale inversion above is exactly
 * right for gray-5's OTHER job as inherited neutral text (confirmed
 * working via the Case Studies heading fix), but this pairing uses it
 * as a fixed dark background instead - inverting it to ~97% lightness
 * turned "white text on a dark bar" into "white text on a near-white
 * bar", reported directly against a real TFA login warning message
 * (illegible). Same bug, not yet reported, in skip-link.css's identical
 * pattern - fixed proactively rather than waiting for it to surface.
 * Fix targets the two components directly with a real fixed-dark value
 * instead of trying to make gray-5 serve both jobs at once. */
[data-theme="dark"] .messages,
[data-theme="dark"] .skip-link {
  background-color: var(--hes-color-navy-900);
}

/*
 * Deliberately no `@media (prefers-color-scheme: dark)` default here.
 * An earlier version of this file auto-applied the dark overrides from
 * the OS-level preference whenever the visitor hadn't made an explicit
 * choice yet. Policy changed: a first-time visitor (nothing in
 * localStorage) now always gets light mode regardless of OS preference
 * - js/theme-init.js stamps `data-theme="light"` explicitly in that
 * case, so the base `:root` block above (already the light-mode values)
 * is what applies until the visitor clicks the toggle themselves; only
 * an explicit `data-theme="dark"` ever triggers the dark block below.
 */
