/* ==========================================================================
   Design Tokens — Gigahost ControlCenter v2.0
   ==========================================================================

   Canonical palette for the ControlCenter. Loaded first in the cascade
   (before Bootstrap and layout.css) so every other stylesheet can consume
   semantic tokens via var(--name).

   Design identity: clean, utility-focused, professional. Brand accent is the
   Gigahost light-blue (--accent). Dense authenticated surfaces (dashboard,
   tables, forms) stay flat and quiet by default.

   Deliberate evolution (2026-07-26, founder decision — not drift):
   the identity now PERMITS a subtle, deliberate glow and a z-plane depth
   hierarchy (card floating over an elevated background, frosted bar) on SPARSE
   marquee surfaces — e.g. the logged-out login page — used consciously and
   sparingly, opt-in per surface rather than by default. It STILL rejects:
   garish AI-gradient washes (indigo→violet→pink), sparkle iconography, and
   over-glow / decorative texture on DENSE authenticated pages. Decorative
   treatments are sparse and opt-in only. See the palette obligation for details.

   Token layers
   ------------
   1. Baseline semantic — required by the obligation. Code outside this file
      should prefer these names (--bg, --surface, --accent, --text, ...).
   2. Brand / extended — system-specific palette. Used widely in legacy CSS;
      retained for backwards compatibility.
   3. Component-specific overrides (radii, shadows, spacing) — non-colour
      design tokens collocated for convenience.

   IBM Plex Sans + IBM Plex Mono are the typography pair; their @font-face
   declarations live in /lib/fonts/ibm-plex-{sans,mono}.css.
   ========================================================================== */

/* `[data-bs-theme="light"]` is a SELECTOR ALIAS on this same declaration list,
   not a copy of it — there is exactly one definition of every light value, and
   it is the one below. (cortex-rpgiyqd)

   Why it is needed: wrapper.php leaves the attribute unset for light, so light
   lived only in :root and was therefore the one theme that could not be scoped
   to a subtree. Dark could (`[data-bs-theme="dark"]` matches any element), light
   could not, which made a side-by-side light/dark specimen impossible to build
   without duplicating the ramp — a second source of truth, which the components
   gallery exists to prevent. Aliasing costs nothing and makes the two themes
   symmetric.

   This is Bootstrap's own convention: bootstrap.css declares
   `:root, [data-bs-theme=light]` for exactly the same reason, so a nested light
   scope resets Bootstrap's variables alongside ours.

   No production markup changes behaviour: nothing in the app emits
   data-bs-theme="light" except the dev-menu theme toggle, which today gets
   these values by :root fallback and now gets the identical ones by match. */
:root,
[data-bs-theme="light"] {
    /* Logo visibility is inherited from the nearest theme carrier. Unlike a
       dark-descendant selector, this remains correct for light > dark and
       dark > light > dark nesting on the pre-auth surface. */
    --login-brand-logo-light-display: block;
    --login-brand-logo-dark-display: none;

    /* -----------------------------------------------------------------
       Baseline semantic tokens, and the extended tokens grouped with them

       Obligation cortex-nuq33jb requires exactly TEN of the tokens in this
       block, and constrains no others:

           --bg  --surface  --text  --text-dim  --border
           --accent  --success  --warning  --danger  --info

       Removing one of those ten is a breaking change. Everything else here
       (--surface-alt, --text-strong, --text-faint, --border-strong,
       --accent-fg/-dark/-deep/-ramp/-muted/-focus-ring, --success-dark,
       --info-dark, --dev-*) is EXTENDED palette: the obligation lists it as
       such, does not require it, and does not fix its value.

       This heading previously read "required by the palette obligation" over
       the whole block, which claimed obligation status for 18 tokens that do
       not have it. That misreading is not hypothetical — it is why
       cortex-904rg24 was filed believing --accent-muted could not be changed
       without amending the obligation. It can. (cortex-904rg24)
       ----------------------------------------------------------------- */

    /* Surfaces */
    --bg: #c9c9c9;                 /* Page ground — the BENCH. Evident study v16 --canvas
                                      (study/index.html:1026, "neutral graphite bench").
                                      Retoned from #eee by the canonical-demo reconcile: the
                                      bench is machined stock, not paper. See --color-rule and
                                      --color-grey-100 below for the two consumers that used
                                      this token as a light TINT rather than as the ground. */
    --surface: #fff;               /* Cards, panels, modals */
    --surface-alt: #f5f5f5;        /* Alt surface (table stripes, code blocks) */
    --border: #ddd;                /* Default borders, dividers */
    --border-strong: #ccc;         /* Emphasised borders */

    /* Text */
    --text: #444;                  /* Body text */
    --text-strong: #222;           /* Headings, emphasised body */
    --text-dim: #4e4e4e;           /* Muted/secondary text — AA on the bench and every face.
                                      The LAST text rung: nothing dimmer paints prose. */
    /* --text-faint is NON-TEXT. It is the icon/divider rung, not a third text weight.
       Bound by WCAG 1.4.11 (3:1), not 1.4.3 (4.5:1); do not paint prose with it.

       Adopted from Evident, which hit this exact defect on the identical rung and
       resolved it the same way: --ev-ink-faint is labelled NON-TEXT (cortex-g2j0rmv)
       after measuring the ink ladder as arithmetically TWO rungs deep, not three —
       there is not enough headroom between the bench and the brightest face to carry
       three AA-clearing text weights. CC carried a third anyway, and in the dark
       blocks it read below AA on --surface-alt. The seven prose consumers moved to
       --text-dim; the icon/divider consumers kept the rung, which is its job.
       (cortex-httytej) */
    --text-faint: #545454;         /* Icon/divider rung — see NON-TEXT note above */

    /* Brand accent */
    --accent: #2bb3f3;             /* Gigahost light-blue */
    --accent-fg: #fff;             /* Text on accent surfaces */
    --accent-dark: #042d4a;        /* Dark brand variant (headings, hovers) */
    --accent-deep: #0f2233;        /* Deep accent surface */
    --accent-ramp: #1a9cd9;        /* Gradient companion */
    --accent-muted: rgba(43, 179, 243, 0.08);  /* Tinted accent (hover bg) */
    --accent-focus-ring: rgba(43, 179, 243, 0.35);

    /* Status / severity */
    --success: #5a9a5c;
    --success-dark: #4a8a4c;
    --warning: #c9a227;
    --danger:  #c45a5a;
    --info:    #5a9bcf;
    --info-dark: #4a8bbf;

    /* Dark-scheme severity ramps — the ink / face / border trio that
       layout-theme.css feeds into Bootstrap's --bs-*-text-emphasis,
       --bs-*-bg-subtle and --bs-*-border-subtle inside the three-theme
       :is(dark, darker, very-dark) selector. Bootstrap's stock dark values,
       moved here verbatim; nothing was retoned. (cortex-8zl5kte)

       DECLARED HERE, IN :root, NOT in the three dark blocks below. The values
       are identical across dark/darker/very-dark — the consuming selector
       covers all three at once — so a per-theme declaration would be the same
       hex written three times, and the semantic family above (--success,
       --warning, --danger, --info) is already :root-only for the same reason.
       The -on-dark suffix, not the block they sit in, is what scopes them.

       Do NOT read -on-dark as "the darker variant of". --success-dark is a
       darker green for the LIGHT bench; --success-ink-on-dark is a LIGHTER
       green that only ever paints on a dark one. Different axis, and the two
       are not interchangeable. */

    /* ink — severity text that reads on the dark bench */
    --secondary-ink-on-dark:   #a7acb1;
    --success-ink-on-dark:     #75b798;
    --info-ink-on-dark:        #6edff6;
    --warning-ink-on-dark:     #ffda6a;
    --danger-ink-on-dark:      #ea868f;
    /* The two neutral rungs are Bootstrap's `light` and `dark` emphasis
       members. Named by rung, not by those colour-names: in a dark scheme both
       are bright, so "--dark-ink-on-dark" would have said the opposite of what
       it holds. Ordering is Bootstrap's own (dark <= light). */
    --neutral-ink-on-dark:     #f8f9fa;  /* Bootstrap `light` member */
    --neutral-ink-dim-on-dark: #dee2e6;  /* Bootstrap `dark` member  */

    /* face — tinted severity fill. Deliberately darker than Bootstrap's stock
       for the near-black bench; see the layout-theme.css note. (cortex-mz7eidz) */
    --primary-face-on-dark:   #021024;
    --success-face-on-dark:   #03120b;
    --info-face-on-dark:      #021b20;
    --warning-face-on-dark:   #221a01;
    --danger-face-on-dark:    #1d0709;

    /* border — severity edge */
    --primary-border-on-dark: #084298;
    --success-border-on-dark: #0f5132;
    --info-border-on-dark:    #087990;
    --warning-border-on-dark: #997404;
    --danger-border-on-dark:  #842029;

    /* Dark-scheme one-offs, outside the severity grid */
    --highlight-face-on-dark: #664d03;  /* <mark> fill */
    --card-face-on-dark:      #212529;  /* .rounded-white molded plane */

    /* Development-only surfaces */
    --dev-accent: #6f42c1;
    --dev-accent-fg: #fff;
    --dev-accent-soft: #b48ee0;
    --dev-bg: #1a1a1a;
    --dev-link: #8bb9fe;
    --dev-link-hover: #afd0ff;

    /* -----------------------------------------------------------------
       Brand / extended palette (legacy aliases retained for back-compat)
       ----------------------------------------------------------------- */

    --color-primary:       var(--accent);
    --color-primary-dark:  var(--accent-dark);
    --color-primary-light: var(--accent-muted);

    --color-white:    var(--surface);
    --color-grey-50:  var(--surface-alt);
    /* PINNED, deliberately not var(--bg). The grey ramp is a UI tint scale, not a
       material face, and it must stay monotonic: 50 (#f5f5f5) -> 100 -> 200 (#ddd)
       -> 300 (#ccc). Once --bg became the #c9c9c9 bench, tracking it would have put
       rung 100 BELOW rung 300 and turned eight subtle panel fills and hairlines into
       distinctly grey blocks. #eee is this rung's own value, previously borrowed
       from --bg only because the two happened to coincide. */
    --color-grey-100: #eee;
    --color-grey-200: var(--border);
    --color-grey-300: var(--border-strong);
    --color-grey-400: var(--text-faint);
    --color-grey-500: var(--text-dim);
    --color-grey-600: var(--text-dim);
    --color-grey-700: #555;
    --color-grey-800: #333;
    --color-grey-900: var(--text-strong);

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

    --color-bg:        var(--bg);
    /* Legacy table hairline. Split out of --color-bg by the bench retone: the
       old table rules that drew separators in "the page background colour"
       are drawn ON WHITE CARDS, so they were using --color-bg as a faint tint,
       not as the ground. Tracking the bench would have turned every table rule
       into a visible #c9c9c9 line. Value = this token's own resolved value
       before the split. */
    --color-rule:      #eee;
    --color-bg-dark:   #2a2a2a;
    --color-bg-darker: var(--text-strong);
    --color-text:        var(--text);
    --color-text-muted:  var(--text-dim);
    /* MISNAMED, kept for back-compat: despite "text" it has no prose consumers.
       Its one remaining consumer is non-text — the dark breadcrumb separator
       (layout-theme.css). It therefore correctly tracks the NON-TEXT --text-faint
       rung and was deliberately NOT repointed to --text-dim by the demotion. Do
       not paint prose with it. (cortex-httytej; the second consumer, the .copy-btn
       clipboard glyph, went with the legacy copy seam in cortex-9bfk1se) */
    --color-text-light:  var(--text-faint);

    /* --color-hover-bg was here, aliasing --accent-muted. Its only consumer was
       the retired legacy-table row-hover face, which is now Evident's achromatic
       --ev-wash: the accent is not licensed as a material face (Invariant 7),
       and a token named for a hover face is an invitation to paint one.
       Removed rather than left dangling in four scopes. (cortex-cf4v7nn) */

    /* --color-focus-ring was here, aliasing --accent-focus-ring. Its only
       consumer was the bare .form-control/.form-select/.form-check-input
       :focus halo in layout-base.css, which overrode the Evident adapter's
       carve-stack focus and reinstated the bloom Invariant L4 forbids. With
       that rule deleted the alias had zero consumers, so it is removed rather
       than left dangling. --accent-focus-ring itself stays: the accordion
       button focus shadow (layout-base.css) still consumes it. (cortex-ovnfxcx) */

    /* -----------------------------------------------------------------
       Non-colour design tokens (shadows, radii, spacing, transitions)
       ----------------------------------------------------------------- */

    /* Shadows — symmetric axial light (Evident Invariant 6).
       Zero x AND y offset on every shadow: light is axial, not directional.
       Blur and spread are the ONLY depth channels.

       These are not the old values with the offset deleted. Removing a y-offset
       redistributes the same shadow "ink" around all four sides, so a naive
       `0 3px 8px` -> `0 0 8px` reads markedly flatter. Measured on rendered
       pixels (peak darkness in the falloff band directly below a card):

         sm  light  old 0 3px 8px /.04  peak 7   ->  naive 0 0 8px  peak 4  (-43%)
         md  light  old 0 4px 12px/.08  peak 13  ->  naive          peak 9  (-31%)
         sm  dark   old 0 3px 8px /.20  ink  8   ->  naive          ink  1  (-87%)

       Blur, spread and alpha below are compensated so each token's peak
       darkness and total falloff area match or exceed its offset predecessor,
       while now reading equally from every direction. Verified light + dark.
       (cortex-1r37qcl) */
    --shadow-sm: 0 0 12px 1px rgba(0, 0, 0, 0.06);
    --shadow-md: 0 0 18px 2px rgba(0, 0, 0, 0.10);
    --shadow-lg: 0 0 20px 2px rgba(0, 0, 0, 0.13);

    /* -----------------------------------------------------------------
       CONTROL CENTER BENCH TEXTURE  (cortex-90uap2b)
       -----------------------------------------------------------------
       What used to be here: 72 hand-ported `--ev-*` material tokens
       (cortex-vnt3p6m), written before Evident was a packaged library.
       cortex-5j0mik0 vendored the real one to src/lib/evident/, which
       head.php:101 loads AFTER this file at equal specificity — so every
       one of those names was already resolving to Evident's value, not to
       the copy here. Measured before deletion: light 0 of 72 differed,
       dark 3 of 72 (--ev-fillet-light/-2/-3, where Evident's weaker values
       already won). The port was unreachable, so it is gone.

       src/lib/evident/evident.css is now the ONLY definition of the --ev-*
       material language. Do not re-add a material token here: change it at
       source in cortex/evident and re-sync (CLAUDE.md, "Styling"). A token
       redefined here would silently shadow the library for this consumer
       only, which is the drift the vendoring exists to prevent.

       FORWARDING POINTERS for prose that lived here and had no equivalent in
       the library. evident.css still says "see CC tokens.css" for the second:
         - the rim-is-the-trap rule (a rim is legal only where material was
           removed; re-check it on every RE-PARENT) ->
           .claude/skills/design/SKILL.md, Invariant 4.
         - the --ev-accent-ink-hover per-theme contrast table (cortex-ieyciac)
           -> .claude/skills/design/SKILL.md, Invariant 7.
       Everything else was condensed into evident.css itself, with the
       originating bead IDs (cortex-e6pvq66, cortex-9sl5z3t, cortex-mn5hkp8)
       preserved there.

       The three below are the exception — Control Center's own bench
       texture, which Evident does not define at all. Evident's full-bleed
       page carries its own single-layer grain (--ev-noise-alpha); ours is a
       finer two-layer pinstripe plus tooth. They are therefore CC-owned and
       carry the --cc- prefix, so a future Evident release that adds a
       canvas token cannot take our bench over from under us.

       The canvas is the ENVIRONMENT: the un-worked bench that both
       fabrication processes act upon. Its tone is --bg; these are the
       texture layers over it. Paint order, top first:
         1. ambient swoop   (--ev-amb-hi/-lo — Evident's, pure luminance)
         2. material tooth  (--cc-canvas-tooth, irregular ~180px field)
         3. ink pinstripe   (--cc-canvas-stripe, 1px on a 3px pitch)
         4. lit companion   (--cc-canvas-lite, half-pitch offset -> milled)

       The tooth is two orders of magnitude coarser than the pinstripe and
       is aperiodic, so the two cannot form a beat pattern — that scale gap
       is load-bearing, not incidental. The study quieted the pinstripe
       (0.022 -> 0.014) to make room for the tooth; if they ever fight
       again, quiet the stripe rather than drop the tooth.

       Carve FLOORS stay perfectly smooth — grain belongs to the bench
       only. layout-surfaces.css:122-140 already encodes that half. */
    --cc-canvas-stripe: rgba(28, 28, 28, 0.014);
    --cc-canvas-lite:   rgba(250, 250, 250, 0.11);
    --cc-canvas-tooth:  0.030;

    /* Radius scale — four rungs. Hardcoded values that exactly restated a rung
       (8px, 12px, 100px, 6px) were collapsed onto these tokens app-wide, along
       with the pill-equivalent one-offs (9999px, 50px, 20px on named `*-pill`
       / chip elements) whose radius already exceeded the element height and so
       rendered identically to --radius-pill. (cortex-1r37qcl)

       DELIBERATELY NOT COLLAPSED — each is load-bearing, not a stray duplicate:

       - 4px (18x), 3px (5x): finer than --radius-sm (6px). These are the
         nested-cut rungs — chip close-buttons, inner badges, small inline
         marks. Under Evident Invariant 2 ornament gets FINER with nesting
         depth, so a sub-6px rung is a real need, not drift. It wants its own
         token (--radius-xs), which is a scale decision, not a mechanical
         substitution — left for the surface ports.
       - 10px (4x): sits between --radius-md (8) and --radius-lg (12) with no
         clear nearest rung. Folding either way visibly changes the SMS
         composer and file-manager surfaces being ported separately.
       - 50%, 0, inherit: not scale values at all (circles, resets).
       - 70px / 50px in development/pages/development_mode.php: half the
         element height on a 140px- and 100px-tall toggle track. Derived
         geometry — it must track the height, not a global token.
       - 50rem / var(--bs-border-radius*): Bootstrap's own scale, reached
         through vendored component CSS. Out of scope; overriding Bootstrap
         internals belongs with the component ports.
       - 0.25/0.375/0.5/0.625/0.75rem: rem-authored values in inline <style>
         blocks, which are un-tokenised generally and explicitly out of scope
         for this bead. */
    --radius-sm: 6px;
    --radius-md: 8px;
    --radius-lg: 12px;
    --radius-pill: 100px;

    /* -----------------------------------------------------------------
       Button size scale — five steps, ratio 1.125 (9:8, major second)
       -----------------------------------------------------------------
       1.125 is the LARGEST ratio that keeps the xs step above the hit-target
       floor: 1.2 puts xs at 27px and 1.25 at 25px, both crowding the ~24px
       minimum. Height is pinned explicitly (with line-height: 1) rather than
       left to emerge from `line-height: normal` font metrics — those do not
       scale linearly, so an implicit scale drifts off ratio at the ends. The
       39px default was originally an accident of exactly that; pinning it is
       what makes the scale actually hold.

       Radius is held at a constant 0.359 of height at every step, so the
       corner reads identically proportioned at all five sizes.

         step      height  font    padding (y/x)   radius
         xs        31px    10.5    9.5 / 16        11
         sm        35px    12      10.5 / 18       12.5
         default   39px    13.5    12 / 20         14
         lg        44px    15      13.5 / 22.5     16
         xl        49px    17      15 / 25.5       17.5

       Consumed by the .btn rules in layout.css, which map them onto the
       Bootstrap --bs-btn-* custom properties. That mapping is what keeps size
       ORTHOGONAL to colour: a size modifier sets only geometry, a variant
       (.btn-primary, .btn-outline-*) sets only colour, and they compose
       without either redefining the other.

       Corners are plain circular border-radius. Superellipse / `corner-shape`
       was considered and explicitly deferred (founder ruling, cortex-pzg8v81).
       (cortex-1r37qcl) */

    --btn-height-xs: 1.9375rem;   /* 31px */
    --btn-height-sm: 2.1875rem;   /* 35px */
    --btn-height-md: 2.4375rem;   /* 39px — default */
    --btn-height-lg: 2.75rem;     /* 44px */
    --btn-height-xl: 3.0625rem;   /* 49px */

    --btn-font-xs: 0.65625rem;    /* 10.5px */
    --btn-font-sm: 0.75rem;       /* 12px */
    --btn-font-md: 0.84375rem;    /* 13.5px */
    --btn-font-lg: 0.9375rem;     /* 15px */
    --btn-font-xl: 1.0625rem;     /* 17px */

    --btn-pad-y-xs: 0.59375rem;   /* 9.5px */
    --btn-pad-y-sm: 0.65625rem;   /* 10.5px */
    --btn-pad-y-md: 0.75rem;      /* 12px */
    --btn-pad-y-lg: 0.84375rem;   /* 13.5px */
    --btn-pad-y-xl: 0.9375rem;    /* 15px */

    --btn-pad-x-xs: 1rem;         /* 16px */
    --btn-pad-x-sm: 1.125rem;     /* 18px */
    --btn-pad-x-md: 1.25rem;      /* 20px */
    --btn-pad-x-lg: 1.40625rem;   /* 22.5px */
    --btn-pad-x-xl: 1.59375rem;   /* 25.5px */

    --btn-radius-xs: 0.6875rem;   /* 11px */
    --btn-radius-sm: 0.78125rem;  /* 12.5px */
    --btn-radius-md: 0.875rem;    /* 14px */
    --btn-radius-lg: 1rem;        /* 16px */
    --btn-radius-xl: 1.09375rem;  /* 17.5px */

    --space-xs:  0.25rem;
    --space-sm:  0.5rem;
    --space-md:  1rem;
    --space-lg:  1.5rem;
    --space-xl:  2rem;
    --space-2xl: 3rem;
    --space-3xl: 5rem;

    --table-cell-padding: 0.75rem 1rem;
    --transition-fast: 0.2s ease;

    /* Bootstrap overrides */
    --bs-font-monospace: 'IBM Plex Mono', monospace;
}

/* ==========================================================================
   Developer-only content indicators (reusable, always loaded)
   ==========================================================================
   Mark UI that is only ever rendered in dev/sandbox (behind
   DevelopmentHelper::isDevEnvironment()) so it reads as clearly non-production.
   These mirror the purple dev-bar palette (--dev-accent, #6f42c1) so every
   dev-only surface across the app is visually consistent with the dev bar.

   Living here (rather than in development.css) is deliberate: development.css
   is gated behind isDevelopmentMode() (dev host + dev-mode cookie), but some
   dev-only surfaces — e.g. the login page's "Log in as Cortex user" shortcut —
   render under the broader isDevEnvironment() check (dev host, no cookie).
   tokens.css is loaded first on every page, so these classes always apply.
   (cortex-5ja41ye)

     .dev-only        — boxed content, purple dashed border + "DEV" corner label
     .dev-only-inline — inline chip with a subtle purple outline + 🔧 prefix
   -------------------------------------------------------------------------- */
.dev-only {
    border: 2px dashed var(--dev-accent);
    border-radius: var(--radius-sm);
    background-color: color-mix(in srgb, var(--dev-accent) 13%, transparent);
    padding: 12px;
    position: relative;
    margin-top: 14px;
}

.dev-only::before {
    content: "DEV";
    position: absolute;
    top: -14px;
    left: 8px;
    background: var(--dev-accent);
    color: var(--dev-accent-fg);
    font-size: 10px;
    font-weight: bold;
    padding: 2px 6px;
    border-radius: 3px;
    letter-spacing: 0.5px;
}

.dev-only-inline {
    border: 1px dashed var(--dev-accent);
    border-radius: var(--radius-sm);
    padding: 2px 8px;
    color: var(--dev-accent);
}

.dev-only-inline::before {
    content: "🔧 ";
}

/* ==========================================================================
   Dark theme family — Dark / Darker / Lights Out
   ==========================================================================
   Each level remaps the same semantic tokens to a progressively deeper surface
   ramp, so the whole app (dashboard, file manager, code editor, panels) follows
   the chosen theme through the [data-bs-theme] attribute:

     [data-bs-theme="dark"]      — the standard balanced dark scheme. LIVE.
     [data-bs-theme="darker"]    — a deeper, lower-glare dark for night work.
                                   DORMANT — never selectable.
     [data-bs-theme="very-dark"] — "Lights Out", a near-pure-black playful mode.
                                   DORMANT — retired in cortex-ciljwa7.

   DORMANT scopes are unreachable through user preference: 'darker' and
   'very-dark' are both absent from UserPreferenceHelper::THEME_MODES and both
   normalize to 'dark' on read. The token definitions are deliberately retained
   (founder decision 2026-07-26: "we scrap very-dark for now / just disable it")
   so re-enabling a mode is a preference-list change, not a re-derivation of the
   ramp. Light and dark are the only modes the machined design system is
   validated against.

   The Gigahost light-blue accent (#2bb3f3) is preserved across every level.
   Text ramps are tuned to keep AA contrast against each deeper background.
   Light remains the default and is never overridden here.
   ========================================================================== */
[data-bs-theme="dark"] {
    /* THE canonical dark bench. Evident study v16 --canvas
       (study/index.html:1570, "neutral tar, not pure black"). Retoned from
       #1a1d21, which was R26 G29 B33 — R < G < B, a blue-tinted material
       face. The study insists on neutral twice and Invariant 7 forbids
       chroma in the stock, so this is now strictly R = G = B. */
    --bg:           #0e0e0e;
    /* Material faces, neutralised (cortex-dk1b528). Invariant 7 forbids chroma
       in material: colour is for ink and indicators, never for the stock. These
       four were R < G < B — a blue tint carried since before the Evident port.

       Each was replaced by the grey of its OWN Rec.709 luminance
       (Y = 0.2126R + 0.7152G + 0.0722B), not by a hand-picked grey. That is what
       makes this safe to apply app-wide: no face got lighter or darker, so every
       contrast ratio against it survives unchanged — only the blue left. Largest
       shift across all four is +0.49 of one luminance level.

       These feed the dark grey ramp below (50 <- surface, 100 <- surface-alt,
       200 <- border-strong), which is what actually paints panels; the ramp must
       stay monotonic and in dark it ASCENDS, unlike light. It still does: 33 -> 49 -> 63.
       Was: #1e2127 / #2d3139 / #2d3139 / #3a3f47.

       This and the bench retone above are two halves of one criterion, not
       rival edits: the bench port took --bg and deliberately left the faces,
       cortex-dk1b528 took the faces. The ramp now rises off a 14 bench rather
       than a 29 one, so it still ascends and gained headroom at the bottom. */
    --surface:      #212121;
    --surface-alt:  #313131;
    --border:       #313131;
    --border-strong:#3f3f3f;
    /* Ink, achromatic. Evident L4: "every neutral is a true grey, R=G=B" — which
       binds ink, not just material faces: Evident applied it to its own INK token
       --ev-ink-faint, retoning the very same Tailwind slate #6b7280 (cortex-yzjllwa).
       CC's light block was already on the achromatic ramp (#444 == Evident's
       --ev-lightland-ink); these three dark blocks were the unfinished half.
       Was: #e5e7eb / #f3f4f6 / #9ca3af — Tailwind-family greys carrying a cool cast
       (spread 6 / 3 / 19). Each replacement is the LOWEST true grey whose contrast
       against this block's --bg, --surface AND --surface-alt is >= the old value, so
       no ratio decreased anywhere: 15.59->15.61, 17.54->17.55, 7.60->7.65 on --bg.
       Do not "restore" the originals — they are the defect. (cortex-sypmf31) */
    --text:         #e7e7e7;
    --text-strong:  #f4f4f4;
    --text-dim:     #a3a3a3;
    --text-faint:   #909090;   /* NON-TEXT icon/divider rung (see the light block). Reads
                                  4.08 on --surface-alt — under AA 4.5, over 1.4.11's 3:1,
                                  which is the floor that now binds it. (cortex-httytej) */
    --accent:       #2bb3f3;
    --accent-fg:    #0d0f10;
    --accent-muted: rgba(43, 179, 243, 0.12);

    --color-white: var(--bg);
    --color-grey-50: var(--surface);
    --color-grey-100: var(--surface-alt);
    --color-grey-200: var(--border-strong);
    --color-grey-300: var(--text-faint);
    --color-grey-400: var(--text-dim);
    --color-grey-500: var(--text-dim);
    --color-grey-600: var(--text-dim);
    --color-grey-700: var(--text);
    --color-grey-800: var(--text-strong);
    --color-grey-900: var(--text-strong);
    --color-text: var(--text);
    --color-text-muted: var(--text-dim);
    --color-text-light: var(--text-faint);
    --color-primary-dark: #8ed8f8;
    --color-primary-light: var(--accent-muted);
    --color-bg: var(--bg);
    --color-rule: #1c1c1c;   /* table hairline; see the light block. Neutralised
                                from the old #1a1d21 bench value it inherited. */
    --color-bg-dark: #131313;   /* neutralised from #111315 (R17 G19 B21); same Y, cortex-dk1b528 */
    --color-bg-darker: var(--accent-fg);

    /* ---- THE BENCH, dark (study/index.html:1570-1584) ----------------
       Not the light values inverted. On dark the tooth is carried by
       LIGHT, not shadow — a dark bench cannot get much darker, so the
       noise reads as a faint sheen of scattered highlight rather than
       speckled black, and its alpha drops 0.030 -> 0.026. The pinstripe
       moves the other way (0.014 -> 0.24): near-black ink needs far more
       alpha to register against tar than against graphite.

       The dark half of the hand-ported Evident layer stood here too and is
       gone for the same reason as the light one — see the :root block. Only
       the CC-owned bench texture remains; --ev-amb-hi/-lo now come from
       src/lib/evident/evident.css, whose dark scope
       :is([data-ev-theme="dark"], [data-bs-theme="dark"]) matches this same
       attribute at equal specificity and later in the cascade. */
    --cc-canvas-stripe: rgba(0, 0, 0, 0.24);
    --cc-canvas-lite:   rgba(245, 245, 245, 0.011);
    --cc-canvas-tooth:  0.026;
}

/* --------------------------------------------------------------------------
   DORMANT (cortex-ciljwa7) — not selectable; 'darker' normalizes to 'dark'.
   Darker — a deeper dark than Dark for low-light, low-glare sessions.
   Backgrounds drop roughly one ramp below Dark; text is nudged slightly
   brighter so body/heading contrast stays at AA against the darker surfaces.
   -------------------------------------------------------------------------- */
[data-bs-theme="darker"] {
    /* Below the canonical bench, and strictly neutral. Retoned from #0e1014
       (R14 G16 B20 — blue-tinted, and already at the study bench's luminance,
       so it had no room left under the new dark #0e0e0e). The study has ONE
       dark bench; this rung is a documented CC extension beyond it, so it
       keeps its low-glare intent and gives up only its chroma. */
    --bg:           #070707;
    /* Neutralised, same Rec.709-luminance method as the dark block (cortex-dk1b528).
       Restated here rather than inherited: darker is a SIBLING selector of
       [data-bs-theme="dark"], not a descendant, so nothing above reaches it.
       Ramp stays ascending: 22 -> 32 -> 53, and off the retoned 7 bench above it
       still clears dark's own 14 bench, so the two rungs stay ordered.
       Was: #13161b / #1c2026 / #23272f / #30353e — all R < G < B. */
    --surface:      #161616;
    --surface-alt:  #202020;
    --border:       #272727;
    --border-strong:#353535;
    /* Ink, achromatic — same L4 pass as dark above (cortex-sypmf31).
       Was: #e8eaee / #f6f7f9 / #a3a9b3 / #71777f, spread 6 / 3 / 16 / 14 — the
       whole rung was cool-cast here, --text-dim worst of the twelve. Lowest true
       grey holding every ratio against --bg / --surface / --surface-alt:
       16.72->16.74, 18.79->18.80, 8.52->8.57, and --text-faint 4.458->4.498 on --bg.
       NOTE --text-faint remains BELOW the AA 4.5 floor here (4.498 on --bg, 4.04 on
       --surface, 3.64 on --surface-alt) and was already below it before this pass —
       neutralising the cast does not fix that, and deliberately did not try to.
       RESOLVED by demotion, not by re-toning: the rung is now NON-TEXT (see the light
       block), so AA 4.5 no longer binds it — WCAG 1.4.11's 3:1 does, and 3.64 clears
       that. The prose that used to sit here is on --text-dim. (cortex-httytej) */
    --text:         #eaeaea;
    --text-strong:  #f7f7f7;
    --text-dim:     #a9a9a9;
    --text-faint:   #777777;  /* NON-TEXT icon/divider rung — see the light block (cortex-httytej) */
    --accent:       #2bb3f3;
    --accent-fg:    #0a0c0f;
    --accent-muted: rgba(43, 179, 243, 0.12);

    --color-white: var(--bg);
    --color-grey-50: var(--surface);
    --color-grey-100: var(--surface-alt);
    --color-grey-200: var(--border-strong);
    --color-grey-300: var(--text-faint);
    --color-grey-400: var(--text-dim);
    --color-grey-500: var(--text-dim);
    --color-grey-600: var(--text-dim);
    --color-grey-700: var(--text);
    --color-grey-800: var(--text-strong);
    --color-grey-900: var(--text-strong);
    --color-text: var(--text);
    --color-text-muted: var(--text-dim);
    --color-text-light: var(--text-faint);
    --color-primary-dark: #8ed8f8;
    /* Pale hover face (#9bd8f6 measured) => dark ink, as in 'dark'. This block
       carries no --ev-acc-* overrides, so without this line it would inherit
       :root's LIGHT hover ink and render at 1.55:1. Dormant theme, so the
       defect would be latent rather than live — set it anyway. (cortex-ieyciac) */
    --ev-accent-ink-hover: var(--ev-accent-ink);
    --color-primary-light: var(--accent-muted);
    --color-bg: var(--bg);
    --color-rule: #101010;   /* table hairline; see the light block. Neutralised
                                from the old #0e1014 bench value it inherited. */
    --color-bg-dark: #0b0b0b;   /* neutralised from #090b0e (R9 G11 B14); same Y, cortex-dk1b528 */
    --color-bg-darker: var(--accent-fg);

    /* Bench texture, same treatment as [data-bs-theme="dark"]. These blocks do
       not inherit that block's --ev-* overrides (sibling selectors, not
       ancestors), so the bench is restated rather than assumed. */
    --cc-canvas-stripe: rgba(0, 0, 0, 0.24);
    --cc-canvas-lite:   rgba(245, 245, 245, 0.011);
    --cc-canvas-tooth:  0.026;
    --ev-amb-hi:        rgba(245, 245, 245, 0.050);
    --ev-amb-lo:        rgba(0, 0, 0, 0.30);
}

/* --------------------------------------------------------------------------
   DORMANT (cortex-ciljwa7) — retired as a selectable mode; 'very-dark'
   normalizes to 'dark'. Kept so the mode can be re-enabled without redesigning
   the ramp.
   Very Dark ("Lights Out") — the whimsical, near-pure-black option.
   A true black page with barely-lifted surfaces, for the full lights-out look.
   Surfaces stay just above pure black so cards remain distinguishable; text is
   the brightest of the family to hold AA contrast against #000.
   -------------------------------------------------------------------------- */
[data-bs-theme="very-dark"] {
    --bg:           #000000;
    /* Neutralised, same method (cortex-dk1b528). --surface was already R=G=B and
       is left alone; the other three carried a last trace of blue. Restated here
       for the same sibling-selector reason as darker. Ramp: 7 -> 16 -> 42.
       Was: #101012 / #1c1c1f / #2a2a2e. */
    --surface:      #070707;
    --surface-alt:  #101010;
    --border:       #1c1c1c;
    --border-strong:#2a2a2a;
    /* Ink, achromatic — same L4 pass as dark/darker above (cortex-sypmf31).
       Was: #ededee / #a8a8ad / #74747a, spread 1 / 5 / 6 — the mildest cast of the
       three blocks, but a cast. Lowest true grey holding every ratio against
       --bg / --surface / --surface-alt: 17.95->18.10, 8.87->8.94, 4.52->4.56. */
    --text:         #eeeeee;
    --text-strong:  #ffffff;   /* already achromatic — untouched */
    --text-dim:     #a9a9a9;
    --text-faint:   #757575;  /* NON-TEXT icon/divider rung — see the light block (cortex-httytej) */
    --accent:       #2bb3f3;
    --accent-fg:    #000000;
    --accent-muted: rgba(43, 179, 243, 0.14);

    --color-white: var(--bg);
    --color-grey-50: var(--surface);
    --color-grey-100: var(--surface-alt);
    --color-grey-200: var(--border-strong);
    --color-grey-300: var(--text-faint);
    --color-grey-400: var(--text-dim);
    --color-grey-500: var(--text-dim);
    --color-grey-600: var(--text-dim);
    --color-grey-700: var(--text);
    --color-grey-800: var(--text-strong);
    --color-grey-900: var(--text-strong);
    --color-text: var(--text);
    --color-text-muted: var(--text-dim);
    --color-text-light: var(--text-faint);
    --color-primary-dark: #8ed8f8;
    /* Pale hover face (#a0ddfa measured) => dark ink. Same inheritance trap as
       'darker' above; also dormant. (cortex-ieyciac) */
    --ev-accent-ink-hover: var(--ev-accent-ink);
    --color-primary-light: var(--accent-muted);
    --color-bg: var(--bg);
    --color-rule: #0a0a0a;   /* table hairline; see the light block. */
    --color-bg-dark: #000000;
    --color-bg-darker: var(--accent-fg);

    /* Bench texture, same treatment as [data-bs-theme="dark"] (see the darker
       block for why it is restated). --bg stays #000000: this mode's entire
       purpose is the black extreme, and the study's "not pure black" applies
       to its ONE canonical bench, not to a deliberate extension past it. */
    --cc-canvas-stripe: rgba(0, 0, 0, 0.24);
    --cc-canvas-lite:   rgba(245, 245, 245, 0.011);
    --cc-canvas-tooth:  0.026;
    --ev-amb-hi:        rgba(245, 245, 245, 0.050);
    --ev-amb-lo:        rgba(0, 0, 0, 0.30);
}
