/* Industrial Precision — surface tokens (issue #80).
   ═══════════════════════════════════════════════════
   Semantic names for "the surface a component sits on", so a component is written once and
   the surface decides its colours.

   Why this file exists:
    * Industrial Precision is a LIGHT design language. Styles/theme/_sodium.scss defines the
      palette and Styles/modules/_industrial.scss sets the baseline — `--bs-body-bg: var(--offwhite)`,
      `body { background: var(--offwhite); color: var(--ink) }`. Navy is for CHROME: the nav bar,
      hero bands, the footer, code blocks. Every customer-facing page follows that: a navy hero
      band, then white cards on the off-white canvas.
    * The admin screens did not. `.admin-panel` — the content container on 45 views — was
      `background: var(--navy)`, so admin put its content on the darkest token in the palette.
      That is why admin looked darker than the rest of the app, and it was inherited rather than
      designed: the rule predates issue #80, which shipped admin-industrial.css to define the
      classes the views referenced and fixed contrast INSIDE the dark choice without
      re-evaluating the surface.
    * Half of admin-industrial.css then existed to undo Bootstrap's white-page assumptions
      (`text-muted`, `form-label`, `btn-outline-*`, `badge bg-secondary`, `.table`). 42 admin
      views use `text-muted`, 21 use `badge bg-secondary`, 11 use `<code>` — the markup was
      already written for a light surface. So the surface moved to match the markup, and those
      corrections were re-scoped to the chrome that is still dark.

   The pairs matter. --muted/--rule are LIGHT-surface tokens (mid-grey text, navy-tinted
   hairline); --steel/--rule-dark are their dark-surface counterparts. Putting one on the other's
   surface is the whole of issue #80: --muted #526880 on --navy #001428 is ~2.5:1, and --steel
   #c0d8ee on white is 1.47:1. Reference the semantic names below and the question does not arise.

   Plain CSS on purpose, like admin-nav.css and admin-industrial.css: it must not depend on the
   Dart Sass build step, which is unavailable without Node — and it cannot live in _sodium.scss,
   because that compiles into wwwroot/css/customerportal.min.css, a committed artifact that is
   several SCSS commits stale and never regenerates here. Loaded immediately after that bundle so
   this :root wins.

   Dark mode (issue #111): this file is the seam. The `[data-bs-theme="dark"]` block at the bottom
   flips --surface-* and every component written against these names follows, with no
   per-component dark rules. That is the whole of the admin chrome, because admin-industrial.css
   was written against these names rather than against --navy/--white/--muted directly.

   Components that hard-code a light value in the compiled bundle — .card, the docs and Vis-U
   hubs, chat, CDP, partners — cannot follow a token they never referenced. Those are handled in
   theme-dark.css, per area. */

:root {
    /* ── Content surfaces ───────────────────────────────────────────────────── */
    /* --surface-1 is a panel/card body; --surface-2 is the page canvas and the wells,
       table headers and callouts that sit one step back from it. */
    --surface-1:        var(--white);
    --surface-2:        var(--offwhite);
    --surface-ink:      var(--ink);
    --surface-muted:    var(--muted);
    --surface-rule:     var(--rule);

    /* Row hover and opt-in banding, as alphas so they work over either fill. */
    --surface-hover:    rgba(61, 184, 245, 0.07);
    --surface-zebra:    rgba(0, 55, 120, 0.025);

    /* The page lead card (issue #145). Light mode is navy on white -- prominence from DEPTH.
       Dark mode cannot go darker, so it is the mirror: prominence from LIFT. --blue #003d70 over
       --surface-1 --navy2 #001f3f is a genuine step up, and it is the same token --chrome-fill
       resolves to in dark mode, so the lead card reads as chrome rather than as a stray colour.

       A token rather than a per-component rule, for the reason this whole file exists: the
       component is written once and the surface decides. */
    --surface-lead:      var(--navy);
    --surface-lead-rule: var(--navy);

    /* Links on a content surface. --accent is 2.24:1 on white and must never be text
       there; --mid is 7.48:1. */
    --surface-link:       var(--mid);
    --surface-link-hover: var(--blue);

    /* Inline <code>. Bootstrap's CDN sets code { color: #d63384 } and the compiled bundle
       overrides only its background, so keys and route names render pink everywhere. */
    --code-ink:         var(--mid);

    /* ── Chrome ─────────────────────────────────────────────────────────────── */
    /* Bands that stay dark in BOTH themes: the hero, the panel header strip, the modal
       header, and the sticky admin toolbar over article pages. In dark mode --surface-1
       becomes --navy while chrome stays --navy2, so the header is still a shade apart
       from the body it caps. */
    --chrome-fill:      var(--navy2);
    --chrome-ink:       var(--white);
    --chrome-muted:     var(--steel);
    --chrome-rule:      rgba(61, 184, 245, 0.18);
    --chrome-link:      var(--accent);

    /* Ghost controls on chrome: Bootstrap's grey outline is mud on navy. */
    --chrome-control-ink:          rgba(255, 255, 255, 0.75);
    --chrome-control-border:       rgba(255, 255, 255, 0.25);
    --chrome-control-hover-bg:     rgba(255, 255, 255, 0.08);
    --chrome-control-hover-border: rgba(255, 255, 255, 0.4);

    /* ── Status ─────────────────────────────────────────────────────────────── */
    /* Solid fills, so a badge reads on a light body, a navy header and a hero alike.
       The outline #ff8095 this replaced was 2.39:1 on white. */
    --status-danger-fill: #dc3545;
    --status-danger-ink:  var(--white);

    /* Danger as TEXT on a content surface, which is a different job from the pair above.
       --status-danger-ink is the ink that goes ON the fill — white — so reaching for it to
       colour an error message paints white on white. ticket-wizard-admin.css and
       ticket-wizard.css did exactly that in a dozen rules, which is why the flow check had no
       visible errors and the customer wizard had no visible validation message (issue #221).
       #b42318 is 6.5:1 on --surface-1; there was no token for this, which is why the wrong
       one was reached for. */
    --surface-danger:     #b42318;
    /* Destructive links on dark chrome only, where #dc3545 is illegible. */
    --chrome-danger-ink:  #ff8095;

    /* Success and caution as TEXT on a content surface: the same job --surface-danger does,
       and the other two thirds of a set that was only ever built for danger. Because there was
       no token, the two hues needing one were written as literals instead: #1c6b45 in both
       _cdp.scss and chat.css, #b4531f twice in _cdp.scss. Each is a dark ink chosen for a white
       card, so each disappears on navy, and a literal cannot follow a theme.
       #1c6b45 is 5.6:1 on the pale green badge fill it is used with; #b4531f is 5.0:1 on
       --surface-1. */
    --surface-success:    #1c6b45;
    --surface-warning:    #b4531f;
}


/* ═══════════════════════════════════════════════════════════════════════════════════════════
   DARK (issue #111)

   The palette is the navy admin look that #80 took off content surfaces — promoted to an
   opt-in whole-app theme rather than discarded. Nothing new is invented: every value below is
   already in _sodium.scss.

   Three steps of elevation, mirroring what light mode does in the other direction. Light puts
   the darkest tone on the chrome and the lightest on the card; dark puts the darkest on the
   page and the lightest on the chrome, so "raised" still reads as "closer to the light".

       page canvas   --navy   #001428      light mode: --offwhite
       card / panel  --navy2  #001f3f      light mode: --white
       chrome band   --blue   #003d70      light mode: --navy2

   Chrome has to move too. In light mode it is --navy2 and the card is white, so the header
   strip is obviously a strip. If chrome stayed --navy2 while the card became --navy2, a panel
   header would vanish into the panel it caps.

   Contrast on the card (#001f3f): --offwhite ~15:1, --steel ~11.3:1, --accent ~8.3:1. The
   light-surface tokens are absent by construction — --muted #526880 on navy is ~2.5:1, which
   is the failure mode issue #80 was about, in the opposite direction. */

[data-bs-theme="dark"] {
    /* ── Five raw tokens, re-pointed ─────────────────────────────────────────────
       This is the part that carries the app rather than just the admin chrome.

       About 160 rules in the compiled bundle, chat.css and capabilities.css were written
       years before --surface-* existed and reference no semantic token at all. Overriding
       them one selector at a time would be 160 rules of theme-dark.css. Instead: across
       every stylesheet the app actually loads, each of these five is used in exactly ONE
       role, measured rather than assumed —

           --ink        29 uses, all text
           --muted      41 text + 4 hairline
           --rule       57 hairline (+2 hairline-ish fills)
           --offwhite   10 fills
           --mid        18 links + 1 hairline

       — so re-pointing them here is unambiguous, and every one of those rules follows.
       The five inline uses in views agree: --offwhite is a fill, --muted an icon colour,
       --rule a border.

       LITERALS ON PURPOSE. `--ink: var(--offwhite)` would resolve --offwhite against this
       same block, where it is now navy, and ink would come out navy on navy. Custom
       properties resolve per element, and :root and this selector are both <html>.

       NOT re-pointed: --white (18 text / 12 fills), --navy (45/11), --navy2 (33/13),
       --steel (11/1) and --accent (72/16) are each used in two roles, so moving one would
       fix the fills and destroy the text. The dozen --white FILLS are named individually
       in theme-dark.css. */
    --ink:       #f2f5f9;                    /* the old --offwhite: pale text on navy */
    --muted:     #c0d8ee;                    /* --steel */
    --rule:      rgba(255, 255, 255, 0.07);  /* --rule-dark */
    --offwhite:  #001428;                    /* --navy: the page canvas */
    --mid:       #3db8f5;                    /* --accent: the link colour that reads on navy */

    /* ── Surfaces ────────────────────────────────────────────────────────────────
       Most of :root's --surface-* definitions are now correct without restating them,
       because they were written as var() over the tokens above: --surface-2 is
       var(--offwhite) so it becomes the navy canvas, --surface-ink is var(--ink),
       --surface-muted is var(--muted), --surface-rule is var(--rule), and --surface-link
       and --code-ink are both var(--mid) so they become accent. Only the ones built on a
       token that must NOT move need saying again. */
    --surface-1:          var(--navy2);   /* :root has var(--white), which stays white */
    --surface-link-hover: var(--accent2); /* :root has var(--blue): too dark to hover on navy */

    /* #b42318 is 2.3:1 on --navy2. The dark-chrome danger ink already exists and is 7.5:1
       there, so the two agree rather than inventing a third red. */
    --surface-danger:     var(--chrome-danger-ink);

    /* Lift, not darken, exactly as for danger above: #1c6b45 is 2.6:1 on --navy2 and #b4531f
       is 3.3:1, so both fail AA on the surface they now land on. These two read at 7.0:1 and
       8.3:1 respectively. */
    --surface-success:    #5cc99a;
    --surface-warning:    #f0a868;

    /* Alphas of navy over a pale fill do nothing over a navy fill. Same idea, inverted:
       lift rather than darken. */
    --surface-hover:      rgba(61, 184, 245, 0.10);
    --surface-zebra:      rgba(255, 255, 255, 0.03);

    /* Lift, not darken -- see the --surface-lead note above. The accent rule is what marks the
       card as raised once the fill alone can no longer carry it. */
    --surface-lead:       var(--blue);
    --surface-lead-rule:  var(--accent);

    --chrome-fill:        var(--blue);
    /* --chrome-ink/-muted/-rule and the ghost-control alphas are unchanged: they were always
       dark-surface values, which is the point of having named them separately. --chrome-ink
       is var(--white), and --white is one of the tokens deliberately left alone. */

    /* ── Bootstrap's own dark theme ──────────────────────────────────────────── */
    /* 5.3 themes text-muted, .table, .form-control, .modal, .btn-outline-* and .card from
       these, but its dark palette is neutral grey (#212529) and ours is navy. Left alone, a
       Bootstrap component would sit as a grey rectangle on a navy page. */
    --bs-body-bg:          var(--surface-2);
    --bs-body-color:       var(--surface-ink);
    --bs-body-bg-rgb:      0, 20, 40;
    --bs-body-color-rgb:   242, 245, 249;

    --bs-emphasis-color:   var(--surface-ink);
    --bs-secondary-color:  var(--surface-muted);   /* drives .text-muted in 5.3 */
    --bs-tertiary-color:   var(--surface-muted);

    --bs-secondary-bg:     var(--surface-1);
    --bs-tertiary-bg:      var(--chrome-fill);
    --bs-border-color:     var(--surface-rule);

    --bs-link-color:       var(--surface-link);
    --bs-link-hover-color: var(--surface-link-hover);
    --bs-link-color-rgb:   61, 184, 245;
}

/* _industrial.scss:23 sets `body { background-color: var(--offwhite); color: var(--ink) }` as a
   literal element rule, so overriding --bs-body-bg above is not enough to move the page. This
   wins on specificity (0,1,1 against 0,0,1) rather than on load order, which matters because the
   rule it beats lives in the compiled bundle. */
[data-bs-theme="dark"] body {
    background-color: var(--surface-2);
    color: var(--surface-ink);
}
