/*
 * NightBuilds shared theme tokens - consumed by every Backoffice/API admin surface via
 * _content/NightBuilds.Branding/tokens/theme.css. Consolidates what used to be two
 * separate, conflicting per-repo files (themes.css + global.css) into one canonical set.
 *
 * Layers, in cascade order:
 *   1. raw color/font primitives (inlined below - source of truth is palette.css in this
 *      same folder; kept as a separate file for palette-extraction tooling/docs, but its
 *      values are duplicated here rather than @import-ed, since @import is unreliable
 *      across browsers/loading contexts for RCL-served static assets - a real, reproduced
 *      failure: the @import rule (and the following rule) silently vanished from the
 *      parsed stylesheet in testing, with no failed network request and no console error.
 *      If you edit a --nb-* value, update palette.css too so they don't drift.
 *   2. light/dark/high-contrast base - sets every token consumers reference
 *   3. brand-swatch axis (data-brand-theme) - independent of light/dark, overrides --primary-*
 *   4. per-service hook (data-service) - extension point, empty today (see CLAUDE.md)
 *
 * Consuming apps should NOT redefine the --primary- / --bg- / --text- / --border- /
 * --shadow- token families locally - only add genuinely page/component-specific rules in
 * their own CSS.
 *
 * NEVER write a star glob immediately followed by a slash anywhere in a comment in this
 * file - those two characters are the comment terminator. The line above used to spell the
 * token families as globs ("--primary-" star slash "--bg-" star slash ...), which ended this
 * comment several lines early and left the rest of its own text to be parsed as a selector,
 * one that then swallowed the whole next rule. That is the real reason the "first rule of
 * this file always disappears" behaviour existed; see the note below.
 */

/* The ":where(.nb-theme-css-parse-sentinel)" sacrificial rule that used to sit here is GONE
   (2026-08-21), and so is the behaviour it existed to absorb.

   Its comment recorded that "whatever rule is physically first in this file is dropped from
   the parsed CSSOM", root cause unidentified, reproduced in both headless and real Chrome.
   The observation was accurate; the diagnosis was not. Nothing was being dropped by the
   browser. The header comment above used to contain a token glob ending in a star, followed
   immediately by a slash ("--primary-" star, then slash, then "--bg-"). Those two characters
   ARE the comment terminator, so the comment ended there and the remainder of its own text
   was parsed as a SELECTOR - and a selector consumes input until its block, swallowing
   whichever rule came next. It reproduced everywhere because it is correct CSS parsing, not
   a quirk. The sentinel worked only by donating its own empty block for that garbage selector
   to eat.

   With the comment fixed, the first real rule below parses normally. If a rule here ever
   seems to "disappear" again, look for a "*" immediately before a "/" in a comment above it
   before suspecting the browser. */

:root, [data-theme="light"] {
  /* Tells the browser which native palette to render its own widget chrome in - select
     arrows, <input type="time">/<input type="date"> picker icons and spinners, the
     autofill highlight, scrollbars - none of which app CSS can otherwise reach. Without
     this, the browser guesses from the OS preference regardless of which theme is
     actually active, so on a device with a dark OS preference every native control
     rendered dark chrome (near-invisible icons/text) even while the light theme's own
     white background was showing - and the reverse happened for dark theme's native
     <select> value text staying UA-default-dark on our dark background. */
  color-scheme: light;

  /* Raw color/font primitives - source of truth is palette.css in this same folder; kept
     as a separate file for palette-extraction tooling/docs, but its values are duplicated
     here (merged into this rule rather than a standalone leading rule/@import - both have
     been observed to silently drop in some browsers/loading contexts for RCL-served static
     assets, with no failed network request and no console error). If you edit a --nb-*
     value, update palette.css too so they don't drift. --nb-* is unconditional (applies
     regardless of theme) since :root always matches <html> here, same as a separate block. */
  --nb-bg-midnight: #0E131B;
  --nb-bg-space: #181F29;
  --nb-surface-light: #F5F7FA;
  --nb-neutral-300: #C4C8CD;
  --nb-neutral-400: #A3A9B1;
  --nb-neutral-500: #6B727C;

  --nb-blue-500: #669EBF;
  --nb-blue-600: #527E99;
  --nb-blue-700: #3D5F73;

  --nb-orange-500: #D0721A;
  --nb-orange-600: #A65B15;
  --nb-orange-700: #7D4410;

  --nb-metal-500: #9E9E9D;
  --nb-metal-600: #7E7E7E;
  --nb-metal-700: #5F5F5E;

  --nb-success: #2FBF74;
  --nb-warning: #FFB547;
  --nb-error: #FF4D4F;
  --nb-info: #2DD5FF;

  --nb-font-primary: "Montserrat", "Inter", "Plus Jakarta Sans", "DM Sans", "Segoe UI", system-ui, sans-serif;

  /* Brand */
  --primary-color: var(--nb-blue-500);
  --primary-hover: var(--nb-blue-600);
  --primary-active: var(--nb-blue-700);
  --secondary-color: var(--nb-metal-500);
  --secondary-hover: var(--nb-metal-600);
  --secondary-active: var(--nb-metal-700);

  /* ----- Text and surfaces that sit ON the brand accent -----------------------------
     --text-inverse is NOT the token for this and never was. It means "the opposite of the
     PAGE background" - white on a light page - whereas this means "readable against
     --primary-color". Using the former put #ffffff on #669EBF: a 2.91:1 primary button on
     every host in every light theme, measured 2026-08-21.

     All three brand accents are LIGHT at their -500 shade (blue #669EBF, orange #D0721A,
     grey #9E9E9D), so the readable ink on all three is the dark one - 6.39 / 5.41 / 6.94,
     against 2.91 / 3.44 / 2.68 for white. ONE value covers every accent AND both modes,
     because the brand-axis blocks below set --primary-color to the same -500 regardless of
     light or dark. High contrast overrides it: that mode's #0000ff needs white (8.59).

     --primary-tint is the direction that INCREASES contrast with --text-on-primary, so the
     two surfaces below get MORE readable on hover, not less. Deliberately NOT
     --primary-hover/--primary-active: those darken the accent, which drops a dark-ink
     button to 4.26 hovered and 2.73 pressed. (--text-link-hover used to be --primary-hover
     for the same "darker on hover" instinct and had the same problem from the other side -
     see the --text-link note further down.) */
  --text-on-primary: var(--nb-bg-midnight);
  --primary-tint: #ffffff;
  --primary-surface-hover: color-mix(in srgb, var(--primary-color) 86%, var(--primary-tint));
  --primary-surface-active: color-mix(in srgb, var(--primary-color) 74%, var(--primary-tint));

  /* Semantic */
  --success-color: var(--nb-success);
  --danger-color: var(--nb-error);
  --warning-color: var(--nb-warning);
  --info-color: var(--nb-info);

  /* Backgrounds */
  --bg-primary: #ffffff;
  --bg-secondary: var(--nb-surface-light);
  --bg-tertiary: #eef1f4;
  --bg-sidebar: var(--nb-surface-light);
  --bg-card: #ffffff;
  --bg-overlay: rgba(14, 19, 27, 0.5);

  /* Text */
  --text-primary: #1A1F26;
  --text-secondary: var(--nb-neutral-500);
  --text-muted: var(--nb-neutral-400);
  --text-inverse: #ffffff;
  /* ----- The accent used as TEXT, on the page's own background ----------------------
     The mirror image of --text-on-primary. --primary-color is the -500 shade, which is
     LIGHT in all three accents - fine as a surface under dark ink, and 2.91:1 as text on
     a white page. So on a light background the accent has to drop to its -700 shade:
     blue #3D5F73 6.81, orange #7D4410 7.76, grey #5F5F5E 6.39. --primary-active already
     IS that shade per accent, so this is a reference, not a fourth palette.

     Hover DEEPENS rather than lightening - the opposite direction from
     --primary-surface-hover, because here the accent is the text and the page is the
     surface, so contrast rises by moving away from the page. --primary-hover would go to
     the -600 shade, which is 4.37 on white for blue and 4.06 for grey: both below AA,
     which is how the link hover state ended up worse than the resting one. */
  --text-link: var(--primary-active);
  --text-link-hover: color-mix(in srgb, var(--primary-active) 78%, #000000);

  /* Borders */
  --border-color: #DCE0E4;
  --border-light: #EEF1F4;
  --border-dark: var(--nb-neutral-400);

  /* Focus */
  --focus-color: var(--primary-color);
  --focus-ring-width: 0.25rem;
  --focus-ring-color: rgba(102, 158, 191, 0.35);
  --focus-ring-box-shadow: 0 0 0 var(--focus-ring-width) var(--focus-ring-color);
}

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

  --primary-color: var(--nb-blue-500);
  --primary-hover: #7FB2D1;
  --primary-active: #9AC3DC;
  --secondary-color: var(--nb-metal-500);
  --secondary-hover: var(--nb-metal-600);
  --secondary-active: var(--nb-metal-700);

  --success-color: var(--nb-success);
  --danger-color: var(--nb-error);
  --warning-color: var(--nb-warning);
  --info-color: var(--nb-info);

  --bg-primary: var(--nb-bg-midnight);
  --bg-secondary: var(--nb-bg-space);
  --bg-tertiary: #212A36;
  --bg-sidebar: var(--nb-bg-space);
  --bg-card: var(--nb-bg-space);
  --bg-overlay: rgba(0, 0, 0, 0.7);

  --text-primary: var(--nb-surface-light);
  --text-secondary: var(--nb-neutral-300);
  --text-muted: var(--nb-neutral-400);
  --text-inverse: var(--nb-bg-midnight);
  /* Dark page: the -500 accent is already the readable one (#669EBF on #0E131B is 6.39),
     so unlike the light block above this keeps --primary-color. Hover LIGHTENS, which is
     again "away from the page background" - the same rule, opposite direction. */
  --text-link: var(--primary-color);
  --text-link-hover: color-mix(in srgb, var(--primary-color) 78%, #ffffff);

  --border-color: #2A3441;
  --border-light: #212A36;
  --border-dark: var(--nb-neutral-500);

  --focus-color: var(--primary-color);
  --focus-ring-color: rgba(102, 158, 191, 0.55);
}

/* High Contrast - accessibility mode, deliberately not brand-tinted */
[data-theme="high-contrast"] {
  /* Pure white background/black text (below), so native chrome should render light too. */
  color-scheme: light;

  --primary-color: #0000ff;
  /* Inverted against every other theme: #0000ff is DARK, so white is the readable ink
     (8.59) and the hover/active surfaces must darken, not lighten. */
  --text-on-primary: #ffffff;
  --primary-tint: #000000;
  --secondary-color: #000000;
  --success-color: #008000;
  --danger-color: #ff0000;
  --warning-color: #ff8c00;
  --info-color: #008080;

  --bg-primary: #ffffff;
  --bg-secondary: #ffffff;
  --bg-tertiary: #ffffff;
  --bg-sidebar: #ffffff;
  --bg-card: #ffffff;
  --bg-overlay: rgba(0, 0, 0, 0.85);

  --text-primary: #000000;
  --text-secondary: #000000;
  --text-muted: #000000;
  --text-inverse: #ffffff;
  /* The brand-axis blocks all carry :not([data-theme="high-contrast"]), so --primary-active
     here is still the base blue -700 (6.81 on white) rather than this mode's #0000ff (8.59).
     Set both explicitly so high contrast keeps the higher number. */
  --text-link: var(--primary-color);
  --text-link-hover: color-mix(in srgb, var(--primary-color) 78%, #000000);

  --border-color: #000000;
  --border-light: #000000;
  --border-dark: #000000;

  --focus-color: #ff0000;
  --focus-ring-width: 0.375rem;
  --focus-ring-color: #ff0000;
}

/* ===== Brand-swatch axis - independent of light/dark, so any combination works
   (e.g. Orange + Dark). Skipped under high-contrast: that mode's colors are
   accessibility-driven and shouldn't be overridden by a decorative accent choice.
   Values come from the real logo assets - see branding/palette-extraction.md. ===== */
:root[data-brand-theme="blue"]:not([data-theme="high-contrast"]) {
  --primary-color: var(--nb-blue-500);
  --primary-hover: var(--nb-blue-600);
  --primary-active: var(--nb-blue-700);
}

:root[data-brand-theme="orange"]:not([data-theme="high-contrast"]) {
  --primary-color: var(--nb-orange-500);
  --primary-hover: var(--nb-orange-600);
  --primary-active: var(--nb-orange-700);
}

:root[data-brand-theme="default"]:not([data-theme="high-contrast"]) {
  --primary-color: var(--nb-metal-500);
  --primary-hover: var(--nb-metal-600);
  --primary-active: var(--nb-metal-700);
}

/* ===== Per-service hook - extension point only, intentionally empty today.
   All three services (ids/ns/cpl) currently share one logo treatment with no real
   per-service hue difference in the source assets - do not invent one here. ===== */
[data-service="ids"], [data-service="ns"], [data-service="cpl"] {
}

/* ===== Shape / motion / layout tokens - shared across all consumers ===== */
:root {
  --font-family-sans-serif: var(--nb-font-primary);
  --font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
  --font-size-xs: 0.75rem;
  --font-size-sm: 0.875rem;
  --font-size-base: 1rem;
  --font-size-lg: 1.125rem;
  --font-size-xl: 1.25rem;
  --font-size-2xl: 1.5rem;
  --font-size-3xl: 1.875rem;
  --font-size-4xl: 2.25rem;
  /* Hero scale - deliberately above the body ramp, used by landing.css's .home-hero h1.
     Named rather than left as a literal so the one place the platform renders type larger
     than --font-size-4xl is discoverable and cannot be re-invented at a slightly different
     size by the next landing page. */
  --font-size-5xl: 2.75rem;
  --line-height-base: 1.5;
  --line-height-tight: 1.25;
  --line-height-normal: 1.5;
  --line-height-relaxed: 1.75;

  --font-weight-normal: 400;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;

  --spacer: 1rem;
  --spacing-xs: 0.25rem;
  --spacing-sm: 0.5rem;
  --spacing-md: 1rem;
  --spacing-lg: 1.5rem;
  --spacing-xl: 2rem;
  --spacing-2xl: 3rem;
  --spacing-3xl: 4rem;

  --border-radius: 0.375rem;
  --border-radius-sm: 0.25rem;
  /* Alias of --border-radius. Both names are in use across the platform's hosts and neither
     is worth a sweeping rename; they must never hold different values. */
  --border-radius-md: 0.375rem;
  --border-radius-lg: 0.5rem;
  --border-radius-xl: 0.75rem;
  --border-radius-pill: 50rem;

  --shadow-sm: 0 1px 2px 0 rgba(14, 19, 27, 0.06);
  --shadow-md: 0 0.5rem 1rem rgba(14, 19, 27, 0.1);
  --shadow: var(--shadow-md);
  --shadow-lg: 0 10px 15px -3px rgba(14, 19, 27, 0.12), 0 4px 6px -2px rgba(14, 19, 27, 0.06);

  --navbar-height: 4.5rem;
  --sidebar-width: 16rem;
  --form-control-height: 2.375rem;

  --transition-base: all 0.15s ease-in-out;
  --transition-fade: opacity 0.15s linear;
  --transition-collapse: height 0.35s ease;
  /* Duration-only, for a rule that names its own property list. --transition-base is the
     whole shorthand and applies to `all`; these three do not. */
  --transition-fast: 150ms ease;
  --transition-normal: 250ms ease;
  --transition-slow: 350ms ease;
}

/* Respect reduced-motion globally */
@media (prefers-reduced-motion: reduce) {
  :root {
    --transition-base: none;
    --transition-fade: none;
    --transition-collapse: none;
  }
}

/* Color-scheme preference fallback, before JS/localStorage has set data-theme */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    color-scheme: dark;
    --bg-primary: var(--nb-bg-midnight);
    --bg-secondary: var(--nb-bg-space);
    --bg-tertiary: #212A36;
    --bg-sidebar: var(--nb-bg-space);
    --bg-card: var(--nb-bg-space);
    --text-primary: var(--nb-surface-light);
    --text-secondary: var(--nb-neutral-300);
    --text-muted: var(--nb-neutral-400);
    --border-color: #2A3441;
  }
}
