/**
 * NXT theme — the portal wearing Austin's NXT design language.
 *
 * One of the themes registered in PortalThemeService::THEMES. Like matrix and
 * sport it rides Bootstrap's own dark component CSS (data-bs-theme stays
 * "dark") and gets its whole look from this sheet, keyed off
 * `html[data-portal-theme="nxt"]`, which base.twig stamps unconditionally.
 * Adding a theme = one THEMES entry + one stylesheet like this + one entry in
 * portal-theme.js's PORTAL_THEMES.
 *
 * SELF-CONTAINED ON PURPOSE. NXT is built on the same BrettZone tokens as the
 * sport theme, but this sheet copies everything it needs — tokens, faces
 * (public/fonts/nxt/), the Bootstrap mapping — rather than reading sport's.
 * Every theme in the kit stands alone, so a product can take, drop or change
 * one without the others moving.
 *
 * ── SOURCE OF TRUTH ──────────────────────────────────────────────────────
 *
 *   1. havocManager docs/NXT_DESIGN.md (Austin, October 2026) — the NXT
 *      priorities: "Recognizably NHRL", read at a glance, motion explains a
 *      change, design every state.
 *   2. havocManager app/brettzone/v2/assets/css/bz-tokens.css + bz-fonts.css
 *      — the palette and the faces. NXT_DESIGN.md names these as its base.
 *   3. havocManager app/mi/css/cageManagerNXT.css — the NXT OPERATOR tool,
 *      and so the closest analogue to an app page: "function and legibility
 *      take priority over decorative brand motifs." Buttons, borders, radii
 *      and the focus ring below trace to it.
 *   4. The NXT audience displays (app/mi/displays/assets/*NXT*.css) for the
 *      identity pieces an app can use: pink/teal corners, the top-right cut,
 *      Joyride on the event hero.
 *
 * tests/Contract/BrettZoneThemeTokenDriftTest holds every --bz-* declared in
 * §2 equal to public/css/brettzone/brettzone-kit.css (the in-repo port of
 * bz-tokens.css), so a palette re-sync that misses this sheet goes red.
 *
 * ── NXT, IN ONE SENTENCE ─────────────────────────────────────────────────
 *
 * Flat purple-cast surfaces with crisp strong keylines; magenta and cyan
 * corners; DIN Next everywhere, Berkeley Mono for numbers, Joyride only on
 * the event hero; operator-sized controls (44px floor, 2px borders, 8px
 * corners) and a thick, offset blue focus ring; no glow, no pills, no glass.
 *
 * ── HOW IT DIFFERS FROM SPORT (both are BrettZone) ───────────────────────
 *
 *   - Corners are MAGENTA AND CYAN (NXT_DESIGN.md: "Corner identity: Magenta
 *     and cyan"). Sport moves the second corner to brand blue because teal
 *     is the 3lb weight colour; NXT deliberately keeps teal for the corner,
 *     as every NXT display does.
 *   - Controls are the referee terminal's: 8px corners, 2px borders, a 44px
 *     floor, labels in sentence case. Sport is 2px corners and DIN caps.
 *   - The page title stands upright. NXT keeps the page name secondary; the
 *     lean belongs to robot names, and Joyride to the event hero.
 *   - Focus is a 3px ring offset from the control (Cage Manager NXT's
 *     `outline: 3px solid --bz-focus; outline-offset: 3px`).
 *
 * ── TRAPS, SAME AS EVERY THEME SHEET ─────────────────────────────────────
 *
 * 1. §2 is declared on `.portal-theme-scope[data-portal-theme="nxt"]` too,
 *    or the Appearance swatch is handed dark's tokens (kit 3.8.1).
 * 2. --bs-* lives in §2b with its own selector: .portal-page-themed carries
 *    data-bs-theme on <main> and would shadow a body-level --bs-*.
 * 3. !important in §2: the glass degrade gates at the end of
 *    portal-components.css are (0,3,0) and would otherwise win.
 * 4. No color-mix() — tests/Contract/ParseFloorTwinsTest would demand
 *    literal twins for it. BrettZone's palette is literal anyway.
 * 5. clip-path only on .btn-primary, a leaf: on a card it would eat outer
 *    focus rings and clip dropdowns that position out of it.
 * 6. Empty box-shadow tokens are `0 0 #0000`, never `none` — the kit
 *    composes them in comma lists, where `none` invalidates the whole
 *    declaration (and with it every input's focus ring).
 */


/* ═══ 1. Faces ═══════════════════════════════════════════════════════════
 * Joyride (event hero), DIN Next LT Pro (everything else) and Berkeley Mono
 * (numbers), copied from havocManager's bz fonts into public/fonts/nxt/. A
 * declared face costs nothing until an nxt document renders in it.
 *
 * The weight ranges are deliberate: there is no 600 cut of DIN Next, and
 * without the range a page asking for 600 gets a synthesised bold.
 * ═══════════════════════════════════════════════════════════════════════ */

@font-face {
    font-family: 'NXT Joyride';
    src: url('/fonts/nxt/JoyrideSTD.woff2') format('woff2');
    font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
    font-family: 'NXT Joyride Outline';
    src: url('/fonts/nxt/JoyrideSTDOutline.woff2') format('woff2');
    font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
    font-family: 'NXT DIN Next';
    src: url('/fonts/nxt/DINNextLTPro-Regular.woff2') format('woff2');
    font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
    font-family: 'NXT DIN Next';
    src: url('/fonts/nxt/DINNextLTPro-Italic.woff2') format('woff2');
    font-weight: 400; font-style: italic; font-display: swap;
}
@font-face {
    font-family: 'NXT DIN Next';
    src: url('/fonts/nxt/DINNextLTPro-Medium.woff2') format('woff2');
    font-weight: 500 600; font-style: normal; font-display: swap;
}
@font-face {
    font-family: 'NXT DIN Next';
    src: url('/fonts/nxt/DINNextLTPro-Bold.woff2') format('woff2');
    font-weight: 700; font-style: normal; font-display: swap;
}
@font-face {
    font-family: 'NXT DIN Next';
    src: url('/fonts/nxt/DINNextLTPro-Heavy.woff2') format('woff2');
    font-weight: 800 900; font-style: normal; font-display: swap;
}
@font-face {
    font-family: 'NXT DIN Next';
    src: url('/fonts/nxt/DINNextLTPro-HeavyItalic.woff2') format('woff2');
    font-weight: 800 900; font-style: italic; font-display: swap;
}
@font-face {
    font-family: 'NXT Berkeley Mono';
    src: url('/fonts/nxt/BerkeleyMono-Regular.woff2') format('woff2');
    font-weight: 400 500; font-style: normal; font-display: swap;
}
@font-face {
    font-family: 'NXT Berkeley Mono';
    src: url('/fonts/nxt/BerkeleyMono-Italic.woff2') format('woff2');
    font-weight: 400 500; font-style: italic; font-display: swap;
}
@font-face {
    font-family: 'NXT Berkeley Mono';
    src: url('/fonts/nxt/BerkeleyMono-Bold.woff2') format('woff2');
    font-weight: 600 900; font-style: normal; font-display: swap;
}


/* ═══ 2. Tokens ══════════════════════════════════════════════════════════
 * The --bz-* half is bz-tokens.css verbatim (held by the drift test). The
 * --nxt-* half is portal-side derivations — hover brights and text inks
 * BrettZone does not need — declared once, never under --bz-*.
 * ═══════════════════════════════════════════════════════════════════════ */

html[data-portal-theme="nxt"] body,
.portal-theme-scope[data-portal-theme="nxt"] {

    /* ── BrettZone's own tokens, verbatim from bz-tokens.css ──────────── */
    --bz-brand-purple:   #291c5e;
    --bz-brand-offwhite: #f4f4f4;
    --bz-brand-teal:     #00dad8;
    --bz-brand-pink:     #cf23ca;
    --bz-brand-blue:     #666fe5;
    --bz-brand-lilac:    #c9ccf0;

    --bz-bg:            #0b0a16;
    --bz-surface-1:     #141126;
    --bz-surface-2:     #1b1734;
    --bz-surface-3:     #241e42;
    --bz-border:        #2d2750;
    --bz-border-strong: #3f3770;
    --bz-overlay:       rgba(10, 8, 20, 0.72);

    --bz-text:       #f0eff6;
    --bz-text-dim:   #bcb9cd;
    --bz-text-muted: #7e7a94;
    --bz-text-faint: #57536e;

    --bz-accent:        #cf23ca;
    --bz-accent-strong: #ea5ce6;
    --bz-accent-dim:    #6d1a6b;
    --bz-accent-bg:     rgba(207, 35, 202, 0.14);

    --bz-focus:    #666fe5;
    --bz-focus-bg: rgba(102, 111, 229, 0.14);

    --bz-w3:   #00dad8;
    --bz-w12:  #f2a01c;
    --bz-w30:  #e8433f;
    --bz-w-fs: #9edd2c;

    /* --bz-live is strictly on-air; --bz-win is an official outcome. NXT
       always pairs both with words. */
    --bz-live: #ff2e3d;
    --bz-win:  #10b981;
    --bz-warn: #f2a01c;

    --bz-r-xs:   2px;
    --bz-r-sm:   4px;
    --bz-r-md:   6px;
    --bz-r-lg:   10px;
    --bz-r-hero: 8px;

    --bz-d-fast: 120ms;
    --bz-d-base: 220ms;

    --bz-touch-min: 44px;

    /* ── Portal-side derivations — NOT upstream tokens ──────────────────── */
    --nxt-win-bright:  #2fd39b;   /* --bz-win lifted for hover + text on dark  */
    --nxt-w30-bright:  #ff7a76;   /* --bz-w30 lifted for text on dark          */
    --nxt-w30-hover:   #f05a56;   /* --bz-w30 hover                            */
    --nxt-warn-hover:  #ffb43c;   /* --bz-warn hover                           */
    --nxt-focus-ink:   #9aa0ef;   /* --bz-focus lifted for text on dark        */
    --nxt-muted-ink:   #9d9ab1;   /* text-dim/text-muted midpoint: AA on surface-2 */

    /* ── Surfaces: flat, opaque, purple-cast ───────────────────────────── */
    --portal-c-surface:               var(--bz-surface-1) !important;
    --portal-c-surface-opaque:        var(--bz-surface-1) !important;
    --portal-c-surface-seethrough:    var(--bz-surface-1) !important;
    --portal-c-surface-sunken:        var(--bz-bg) !important;
    --portal-c-surface-sunken-opaque: var(--bz-bg) !important;
    --portal-c-surface-raised:        var(--bz-surface-2) !important;
    --portal-c-surface-raised-opaque: var(--bz-surface-2) !important;
    --portal-c-surface-lift:          rgba(240, 239, 246, 0.045) !important;
    /* Not transparent: this token also paints the login field, input-group
       addons and sheet lists. The real headers go transparent by name in §4. */
    --portal-c-surface-header:        var(--bz-surface-2) !important;

    /* ── Edges: no bevel, no glow (NXT_DESIGN.md: "Avoid glow") ─────────── */
    --portal-c-specular:            transparent !important;
    --portal-c-specular-strong:     transparent !important;
    --portal-c-specular-raised:     transparent !important;
    --portal-c-specular-pressed:    transparent !important;
    --portal-c-specular-pointer:    transparent !important;
    --portal-c-edge-shade:          transparent !important;
    --portal-c-edge-shade-raised:   transparent !important;
    --portal-c-edge-bloom:          transparent !important;
    --portal-c-btn-specular:        transparent !important;
    --portal-c-edge-card:           0 0 #0000 !important;
    --portal-c-edge-card-raised:    0 0 #0000 !important;
    --portal-c-edge-card-pressed:   0 0 #0000 !important;
    --portal-c-edge-chip:           0 0 #0000 !important;
    --portal-c-edge-dialog:         0 0 #0000 !important;
    --portal-c-edge-hero:           0 0 #0000 !important;
    --portal-c-surface-sheen:       none !important;

    /* ── Keylines. "Crisp borders": controls take the STRONG rung, as every
       Cage Manager NXT button and panel does. ── */
    --portal-c-border:                var(--bz-border) !important;
    --portal-c-border-subtle:         var(--bz-surface-3) !important;
    --portal-c-edge-control:          var(--bz-border-strong) !important;
    --portal-c-edge-control-subtle:   var(--bz-border) !important;

    /* ── Text. Muted is the dim/muted midpoint: bz-text-muted fails AA on
       surface-2 (4.18:1); this measures 6.31:1 there. ── */
    --portal-c-text:       var(--bz-text) !important;
    --portal-c-text-muted: var(--nxt-muted-ink) !important;

    /* ── Shadows: flat, except genuine overlays ─────────────────────────── */
    --portal-c-shadow:         0 0 #0000 !important;
    --portal-c-shadow-raised:  0 0 #0000 !important;
    --portal-c-shadow-pressed: 0 0 #0000 !important;
    --portal-c-elev-overlay:   0 8px 24px rgba(0, 0, 0, 0.45) !important;
    --portal-c-elev-menu:      0 8px 24px rgba(0, 0, 0, 0.45) !important;
    --portal-c-elev-hero:      0 8px 24px rgba(0, 0, 0, 0.45) !important;

    /* ── Brand + accent. Interactive is brand pink, as Cage Manager NXT's
       primary is; accent-STRONG for text, because raw #cf23ca is 3.9:1. ── */
    --portal-c-brand:          var(--bz-brand-purple) !important;
    --portal-c-brand-offwhite: var(--bz-brand-offwhite) !important;
    --portal-accent-teal:      var(--bz-brand-teal) !important;
    --portal-c-accent:         var(--bz-accent-strong) !important;
    --portal-c-accent-muted:   var(--bz-accent-bg) !important;
    --portal-c-accent-border:  rgba(207, 35, 202, 0.45) !important;
    --portal-c-on-accent:      var(--bz-bg) !important;

    /* The focus ring is blue and THICK, offset from the control by a band of
       canvas — Cage Manager NXT's `outline: 3px solid --bz-focus;
       outline-offset: 3px`, in the kit's box-shadow shape so every consumer
       of the token keeps working. */
    --portal-c-focus-ring: 0 0 0 2px var(--bz-bg),
                           0 0 0 5px var(--bz-focus) !important;

    /* ── The two fight corners: MAGENTA AND CYAN ────────────────────────── */
    --portal-c-corner-pink:        var(--bz-accent) !important;
    --portal-c-corner-blue:        var(--bz-brand-teal) !important;
    --portal-c-corner-pink-ink:    var(--bz-accent-strong) !important;
    --portal-c-corner-blue-ink:    var(--bz-brand-teal) !important;
    --portal-c-corner-pink-soft:   rgba(207, 35, 202, 0.14) !important;
    --portal-c-corner-blue-soft:   rgba(0, 218, 216, 0.14) !important;
    --portal-c-corner-pink-border: rgba(207, 35, 202, 0.45) !important;
    --portal-c-corner-blue-border: rgba(0, 218, 216, 0.45) !important;

    /* ── Tabs: tint plus a 3px underline, never a raised plate ─────────── */
    --portal-c-tab-track:          var(--bz-bg) !important;
    --portal-c-tab-track-inset:    0 0 #0000 !important;
    --portal-c-tab-hover:          rgba(240, 239, 246, 0.05) !important;
    --portal-c-tab-active-bg:      var(--bz-surface-2) !important;
    --portal-c-tab-active-border:  var(--bz-border-strong) !important;
    --portal-c-tab-active-shadow:  inset 0 -3px 0 var(--bz-accent) !important;
    --portal-c-tab-active-color:   var(--bz-text) !important;
    --portal-c-tab-inactive-color: var(--bz-text-muted) !important;

    /* ── Primary: flat pink with dark ink. Cage Manager NXT uses light ink at
       20px, which is large text; at the portal's 13-14px labels that pairing
       is 4.4:1 and fails AA, so this takes accent-strong + dark ink (6.7:1). */
    --portal-c-btn-primary-bg:            var(--bz-accent-strong) !important;
    --portal-c-btn-primary-bg-hover:      var(--bz-accent-strong) !important;
    --portal-c-btn-primary-bg-active:     var(--bz-accent-strong) !important;
    --portal-c-btn-primary-border:        var(--bz-accent-strong) !important;
    --portal-c-btn-primary-border-hover:  var(--bz-text) !important;
    --portal-c-btn-primary-shadow:        0 0 #0000 !important;
    --portal-c-btn-primary-shadow-hover:  0 0 #0000 !important;
    --portal-c-btn-primary-grad:          none !important;
    --portal-c-btn-primary-grad-hover:    none !important;

    /* ── Weight class: BrettZone's coding, the same 12% washes ─────────── */
    --portal-c-w3-bg:     rgba(0, 218, 216, 0.12) !important;
    --portal-c-w3-color:  var(--bz-w3) !important;
    --portal-c-w12-bg:    rgba(242, 160, 28, 0.12) !important;
    --portal-c-w12-color: var(--bz-w12) !important;
    --portal-c-w30-bg:    rgba(232, 67, 63, 0.12) !important;
    --portal-c-w30-color: var(--bz-w30) !important;
    --portal-c-wfs-bg:    rgba(158, 221, 44, 0.12) !important;
    --portal-c-wfs-color: var(--bz-w-fs) !important;
    --portal-c-w-stripe:  var(--bz-border) !important;

    /* ── Danger / success / warning. Danger is w30, never on-air red. ──── */
    --portal-c-btn-danger-bg:            var(--bz-w30) !important;
    --portal-c-btn-danger-bg-hover:      var(--nxt-w30-hover) !important;
    --portal-c-btn-danger-border:        var(--bz-w30) !important;
    --portal-c-btn-danger-border-hover:  var(--nxt-w30-hover) !important;
    --portal-c-btn-danger-shadow:        0 0 #0000 !important;
    --portal-c-btn-danger-shadow-hover:  0 0 #0000 !important;
    --portal-c-btn-danger-disabled-bg:   rgba(232, 67, 63, 0.35) !important;
    --portal-c-btn-danger-grad:          none !important;
    --portal-c-btn-danger-grad-hover:    none !important;

    --portal-c-btn-success-bg:           var(--bz-win) !important;
    --portal-c-btn-success-bg-hover:     var(--nxt-win-bright) !important;
    --portal-c-btn-success-border:       var(--bz-win) !important;
    --portal-c-btn-success-border-hover: var(--nxt-win-bright) !important;
    --portal-c-btn-success-grad:         none !important;
    --portal-c-btn-success-grad-hover:   none !important;

    --portal-c-btn-warning-bg:           var(--bz-warn) !important;
    --portal-c-btn-warning-bg-hover:     var(--nxt-warn-hover) !important;
    --portal-c-btn-warning-border:       var(--bz-warn) !important;
    --portal-c-btn-warning-border-hover: var(--nxt-warn-hover) !important;
    --portal-c-btn-warning-grad:         none !important;
    --portal-c-btn-warning-grad-hover:   none !important;

    /* ── Outline buttons are the terminal's keys: surface-3, strong rim ── */
    --portal-c-btn-outline-border:       var(--bz-border-strong) !important;
    --portal-c-btn-outline-bg:           var(--bz-surface-3) !important;
    --portal-c-btn-outline-color:        var(--bz-text) !important;
    --portal-c-btn-outline-hover-bg:     var(--bz-surface-3) !important;
    --portal-c-btn-outline-hover-color:  var(--bz-text) !important;
    --portal-c-btn-outline-hover-border: var(--bz-text-dim) !important;

    /* ── Badges: no hairline, the tint carries it ──────────────────────── */
    --portal-c-badge-inset:         0 0 #0000 !important;
    --portal-c-badge-brand-bg:      var(--bz-brand-purple) !important;
    --portal-c-badge-brand-border:  transparent !important;
    /* On-air red on an opaque plum ground: 4.78:1 wherever it lands. */
    --portal-c-badge-live-bg:       #2d0f1b !important;
    --portal-c-badge-live-color:    var(--bz-live) !important;
    --portal-c-badge-muted-bg:      var(--bz-surface-2) !important;
    --portal-c-badge-muted-color:   var(--bz-text-dim) !important;
    --portal-c-badge-running-bg:    rgba(207, 35, 202, 0.16) !important;
    --portal-c-badge-running-color: var(--bz-accent-strong) !important;
    --portal-c-badge-success-bg:    rgba(16, 185, 129, 0.16) !important;
    --portal-c-badge-success-color: var(--nxt-win-bright) !important;
    --portal-c-badge-warning-bg:    rgba(242, 160, 28, 0.16) !important;
    --portal-c-badge-warning-color: var(--bz-warn) !important;
    --portal-c-badge-danger-bg:     rgba(232, 67, 63, 0.16) !important;
    --portal-c-badge-danger-color:  var(--nxt-w30-bright) !important;
    --portal-c-badge-info-bg:       var(--bz-focus-bg) !important;
    --portal-c-badge-info-color:    var(--nxt-focus-ink) !important;

    /* ── Form controls: canvas ground, strong rim, no inset well ───────── */
    --portal-c-input-bg:          var(--bz-bg) !important;
    --portal-c-input-bg-focus:    var(--bz-bg) !important;
    --portal-c-input-inset:       0 0 #0000 !important;
    --portal-c-input-placeholder: var(--bz-text-muted) !important;

    --portal-c-input-border-invalid: rgba(232, 67, 63, 0.55) !important;
    --portal-c-input-ring-invalid:   0 0 0 2px var(--bz-bg),
                                     0 0 0 5px rgba(232, 67, 63, 0.7) !important;
    --portal-c-input-glyph-invalid:  url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23ff7a76'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23ff7a76' stroke='none'/%3e%3c/svg%3e") !important;
    --portal-c-input-border-valid:   rgba(16, 185, 129, 0.55) !important;
    --portal-c-input-ring-valid:     0 0 0 2px var(--bz-bg),
                                     0 0 0 5px rgba(16, 185, 129, 0.7) !important;
    --portal-c-input-glyph-valid:    url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8' width='8' height='8'%3e%3cpath fill='%232fd39b' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") !important;

    /* ── Rows, progress, skeletons ──────────────────────────────────────── */
    --portal-c-row-hover:           rgba(240, 239, 246, 0.045) !important;
    --portal-c-row-selected:        rgba(207, 35, 202, 0.14) !important;
    --portal-c-status-idle:         var(--bz-text-muted) !important;
    --portal-c-progress-bg:         var(--bz-surface-2) !important;
    --portal-c-progress-bar-bg:     var(--bz-accent) !important;
    --portal-c-progress-bar-stripe: rgba(10, 8, 20, 0.25) !important;
    --portal-c-skeleton-bg:         var(--bz-surface-2) !important;
    --portal-c-skeleton-sheen:      rgba(240, 239, 246, 0.05) !important;

    /* ── Overlays + chrome. Scrims are purple-cast, never rgba(0,0,0). ─── */
    --portal-c-overlay:        var(--bz-surface-1) !important;
    --portal-c-overlay-opaque: var(--bz-surface-1) !important;
    --portal-c-scrim:          var(--bz-overlay) !important;
    --portal-c-kbd:            var(--bz-text-muted) !important;
    --portal-c-chrome-hover:   rgba(240, 239, 246, 0.06) !important;
    --portal-c-chrome-surface: var(--bz-bg) !important;

    --portal-c-impersonation-bg:  #b45309 !important;
    --portal-c-impersonation-ink: var(--bz-brand-offwhite) !important;

    /* ── No glass: every rung is an opaque hex. Emptying the blur tokens
       turns off every backdrop-filter in the kit at once. ── */
    --portal-blur-chrome:    none !important;
    --portal-blur-dim:       none !important;
    --portal-blur-overlay:   none !important;
    --portal-chrome-opacity: 1 !important;

    /* ── Type. DIN Next for everything a person reads, Berkeley Mono for
       clocks, ranks, scores and IDs, Joyride for the event hero only. ── */
    --portal-font-body:    'NXT DIN Next', 'Inter', 'Inter Fallback', system-ui, -apple-system, sans-serif !important;
    --portal-font-mono:    'NXT Berkeley Mono', ui-monospace, 'SF Mono', Menlo, monospace !important;
    --portal-font-display: 'NXT Joyride', 'NXT DIN Next', 'Arial Black', sans-serif !important;

    --portal-weight-body:   400 !important;
    --portal-weight-medium: 500 !important;
    --portal-weight-label:  700 !important;
    --portal-weight-strong: 800 !important;

    /* Cage Manager NXT's eyebrow tracking. */
    --portal-tracking-caps:  0.055em !important;
    --portal-label-tracking: 0.055em !important;

    --portal-dur-1: var(--bz-d-fast) !important;
    --portal-dur-2: 200ms !important;
    --portal-dur-3: var(--bz-d-base) !important;
}


/* ═══ 2b. Bootstrap's own tokens ═════════════════════════════════════════
 * Second selector because .portal-page-themed re-declares --bs-* on <main>.
 * The two :not()s keep it off the Appearance swatches and the style guide's
 * side-by-side panes, which are painting other themes on purpose.
 * ═══════════════════════════════════════════════════════════════════════ */

html[data-portal-theme="nxt"] body,
html[data-portal-theme="nxt"] [data-bs-theme]:not([data-portal-theme]):not(.portal-theme-scope),
.portal-theme-scope[data-portal-theme="nxt"] {
    --bs-success:      var(--bz-win) !important;
    --bs-success-rgb:  16, 185, 129 !important;
    --bs-warning:      var(--bz-warn) !important;
    --bs-warning-rgb:  242, 160, 28 !important;
    --bs-danger:       var(--bz-w30) !important;
    --bs-danger-rgb:   232, 67, 63 !important;
    --bs-info:         var(--bz-focus) !important;
    --bs-info-rgb:     102, 111, 229 !important;
    --bs-primary:      var(--bz-accent) !important;
    --bs-primary-rgb:  207, 35, 202 !important;
    --bs-success-text-emphasis: var(--nxt-win-bright) !important;
    --bs-warning-text-emphasis: var(--bz-warn) !important;
    --bs-danger-text-emphasis:  var(--nxt-w30-bright) !important;
    --bs-info-text-emphasis:    var(--nxt-focus-ink) !important;
    --bs-secondary-color: var(--bz-text-dim) !important;
    --bs-secondary-bg:    var(--bz-surface-2) !important;
    --bs-border-color:    var(--bz-border) !important;
    --bs-body-color:      var(--bz-text) !important;
    --bs-body-bg:         var(--bz-bg) !important;
    --bs-emphasis-color:  var(--bz-text) !important;
    --bs-link-color:            var(--bz-accent-strong) !important;
    --bs-link-hover-color:      var(--bz-text) !important;
    --bs-link-color-rgb:        234, 92, 230 !important;
    --bs-link-hover-color-rgb:  240, 239, 246 !important;

    /* ── Geometry: the referee terminal's. 8px controls, 10px panels
       (cageManagerNXT.css: buttons 8px, .arena 10px). Capped at 10. ── */
    --bs-border-radius:     var(--bz-r-hero) !important;
    --bs-border-radius-sm:  var(--bz-r-md) !important;
    --bs-border-radius-lg:  var(--bz-r-lg) !important;
    --bs-border-radius-xl:  var(--bz-r-lg) !important;
    --bs-border-radius-xxl: var(--bz-r-lg) !important;
}


/* ═══ 3. Canvas ══════════════════════════════════════════════════════════
 * Flat --bz-bg, no aurora. The background-color must stay a LITERAL on this
 * selector: tests/Rendering/ThemeColorSingleSourceTest reads it as the
 * source for _kit-head's pre-paint style, head-meta's theme-color and
 * portal-theme.js's PORTAL_THEME_COLORS.
 * ═══════════════════════════════════════════════════════════════════════ */

html[data-portal-theme="nxt"] body {
    background-color: #0b0a16 !important;
    background-image: none !important;
    /* portal-page-theme.css sets body ink as a literal, so answer literally. */
    color: var(--bz-text) !important;
}

html[data-portal-theme="nxt"] body::before,
html[data-portal-theme="nxt"] body::after {
    background-image: none !important;
}

html[data-portal-theme="nxt"] ::selection {
    /* The portal-wide dark token (portal-theme.css): --bz-accent-bg is a
       14% tint and selected text vanished into the input well. */
    background: var(--portal-selection-bg);
    color: var(--portal-selection-color);
}


/* ═══ 4. Surfaces ════════════════════════════════════════════════════════ */

/* Panels have crisp STRONG keylines and do not move. Cage Manager NXT's
   .arena: `border: 1px solid --bz-border-strong; border-radius: 10px`. Hover
   is the keyline brightening, never a lift. */
html[data-portal-theme="nxt"] .portal-hoverable:hover,
html[data-portal-theme="nxt"] .portal-hoverable:focus-within,
html[data-portal-theme="nxt"] .portal-page-themed .card:hover,
html[data-portal-theme="nxt"] .portal-tile:hover,
html[data-portal-theme="nxt"] .portal-tile:has(.stretched-link:hover),
html[data-portal-theme="nxt"] .portal-tile:has(.stretched-link:focus-visible) {
    transform: none !important;
}

html[data-portal-theme="nxt"] .portal-hoverable,
html[data-portal-theme="nxt"] .portal-page-themed .card,
html[data-portal-theme="nxt"] .portal-tile {
    transition: border-color var(--bz-d-base) var(--portal-ease-out),
                background-color var(--bz-d-base) var(--portal-ease-out),
                color var(--bz-d-base) var(--portal-ease-out);
}

html[data-portal-theme="nxt"] .portal-page-themed .card,
html[data-portal-theme="nxt"] .portal-tile {
    border-color: var(--bz-border-strong);
}

html[data-portal-theme="nxt"] .portal-page-themed .card:hover,
html[data-portal-theme="nxt"] .portal-tile:hover {
    border-color: var(--bz-text-muted);
}

/* Headers: transparent with a plain divider (.arena-top). */
html[data-portal-theme="nxt"] .portal-page-themed .card-header {
    background-color: transparent;
    border-bottom: 1px solid var(--bz-border);
}

html[data-portal-theme="nxt"] .modal .modal-header {
    background-color: transparent !important;
    border-bottom: 1px solid var(--bz-border) !important;
}

/* A sticky table head cannot be transparent — rows scroll under it. */
html[data-portal-theme="nxt"] .portal-page-themed .table > thead th,
html[data-portal-theme="nxt"] .portal-page-themed .table-responsive thead th,
html[data-portal-theme="nxt"] .portal-page-themed .portal-table-sticky thead th {
    background-color: var(--bz-bg);
    border-bottom-color: var(--bz-border);
    color: var(--bz-text-dim);
}

/* Dividers are plain lines. */
html[data-portal-theme="nxt"] .portal-page-themed hr,
html[data-portal-theme="nxt"] .dropdown-divider {
    background-image: none !important;
    background-color: var(--bz-border) !important;
    border: 0;
    opacity: 1;
}

/* Active in a vertical list is a tint plus a left wedge. */
html[data-portal-theme="nxt"] .portal-page-themed .list-group-item.active {
    background-color: var(--bz-surface-2);
    border-color: var(--bz-border-strong);
    box-shadow: inset 3px 0 0 var(--bz-accent);
    color: var(--bz-text);
}

/* No pills (NXT_DESIGN.md: "Avoid … rounded pills"). Per component, NOT by
   remapping --bs-border-radius-pill: that also rounds the switch track and
   the count dot, which stay round. */
html[data-portal-theme="nxt"] .portal-chip,
html[data-portal-theme="nxt"] .portal-ios-status,
html[data-portal-theme="nxt"] .portal-page-themed .badge {
    border-radius: var(--bz-r-xs);
    border-color: transparent;
}

/* Status dots are squares with softened corners — Cage Manager NXT's
   connection mark (10px, radius 3px) — and lose the glow halo. */
html[data-portal-theme="nxt"] .portal-live-dot {
    border-radius: var(--bz-r-xs);
    box-shadow: none;
}

/* Empty is dashed, loaded is solid — the distinction stays. */
html[data-portal-theme="nxt"] .portal-page-themed .portal-dropzone {
    border-radius: var(--bz-r-lg);
    border-color: var(--bz-border-strong);
}


/* ── The board: Cage Manager NXT's arena, in the kit's vocabulary ───────── */
html[data-portal-theme="nxt"] .portal-board-filter {
    border-radius: var(--bz-r-hero);
    color: var(--bz-text-dim);
    font-weight: 700;
}

html[data-portal-theme="nxt"] .portal-board-filter[aria-pressed="true"] {
    background: var(--bz-surface-2);
    border-color: var(--bz-border-strong);
    box-shadow: inset 3px 0 0 var(--bz-accent);
    color: var(--bz-text);
}

html[data-portal-theme="nxt"] .portal-board-card {
    border-color: var(--bz-border-strong);
    border-radius: var(--bz-r-lg);
    background: var(--bz-surface-1);
    box-shadow: inset 0 4px 0 var(--portal-board-cap);
}

html[data-portal-theme="nxt"] .portal-board-card.is-dormant {
    border-style: dashed;
    background: transparent;
}

html[data-portal-theme="nxt"] .portal-board-card-head {
    border-bottom-color: var(--bz-border);
}

html[data-portal-theme="nxt"] .portal-board-card-title {
    font-weight: 700;
    letter-spacing: 0.055em;
    text-transform: uppercase;
}

html[data-portal-theme="nxt"] .portal-board-card-num {
    font-weight: 700;
}

html[data-portal-theme="nxt"] .portal-board-card-foot {
    border-top-color: var(--bz-border);
}


/* ═══ 5. Type, controls and the one corner cut ═══════════════════════════ */

/* The page title stands upright in DIN Heavy: "Keep the page name
   secondary" — it labels the tool, it is not the show. */
html[data-portal-theme="nxt"] .portal-page-title,
html[data-portal-theme="nxt"] .portal-page-themed h1 {
    font-weight: 800;
    letter-spacing: -0.01em;
}

/* THE EVENT HERO is the one place Joyride goes: "Event hero — Joyride,
   uppercase". The hero page header is opt-in per page, so this is spent
   only where a page asked for a hero. */
html[data-portal-theme="nxt"] .portal-page-header--hero .portal-page-title {
    font-family: var(--portal-font-display);
    font-weight: 400;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

/* Eyebrow labels: DIN Bold caps in dim ink (Cage Manager NXT's .eyebrow). */
html[data-portal-theme="nxt"] .portal-page-themed .portal-label {
    font-weight: 700;
    letter-spacing: 0.055em;
    color: var(--bz-text-dim);
}

/* Numbers in Berkeley Mono: "Clocks, ranks, scores, IDs". */
html[data-portal-theme="nxt"] .portal-page-themed :is(.portal-stat-value, .portal-mono, code, kbd, samp) {
    font-family: var(--portal-font-mono);
}

/* Robot names: DIN Next Heavy Italic — the lean NXT spends on identity. */
html[data-portal-theme="nxt"] .portal-page-themed .portal-tape thead th {
    font-weight: 800;
    font-style: italic;
}

/* Buttons are the referee terminal's keys: bold, sentence case, a 2px rim
   and the 44px touch floor (NXT_DESIGN.md: "touch targets of at least
   44px"). Small buttons keep their size — dense tables need them — but
   still get the rim. */
html[data-portal-theme="nxt"] .portal-page-themed .btn {
    font-weight: 700;
    letter-spacing: 0;
    text-transform: none;
    border-width: 2px;
}

html[data-portal-theme="nxt"] .portal-page-themed .btn:not(.btn-sm):not(.btn-link):not(.btn-close) {
    min-height: var(--bz-touch-min);
}

/* Solid fills take a dark label — the kit hardcodes #fff, which fails AA
   on this palette's bright fills. */
html[data-portal-theme="nxt"] .portal-page-themed :is(.btn-primary, .btn-danger, .btn-success, .btn-warning),
html[data-portal-theme="nxt"] .portal-page-themed :is(.btn-primary, .btn-danger, .btn-success, .btn-warning):hover,
html[data-portal-theme="nxt"] .portal-page-themed :is(.btn-primary, .btn-danger, .btn-success, .btn-warning):focus,
html[data-portal-theme="nxt"] .portal-page-themed :is(.btn-primary, .btn-danger, .btn-success, .btn-warning):active {
    color: var(--bz-bg);
}

html[data-portal-theme="nxt"] :is(.portal-bar-dock-count, .portal-notif-badge, .portal-notif-count-badge),
html[data-portal-theme="nxt"] .portal-page-themed .badge.text-bg-danger {
    color: var(--bz-bg) !important;
}

/* The signature top-right cut, on the primary action only: a button is a
   leaf, so the clip amputates nothing. clip-path also clips the outer focus
   ring, so the ring goes inset — dark band then blue, both visible on pink. */
html[data-portal-theme="nxt"] .portal-page-themed .btn-primary {
    border-radius: 0;
    clip-path: polygon(0 0, calc(100% - 10px) 0, 100% 10px, 100% 100%, 0 100%);
}

html[data-portal-theme="nxt"] .portal-page-themed .btn-primary:focus-visible {
    box-shadow: inset 0 0 0 2px var(--bz-bg),
                inset 0 0 0 5px var(--bz-focus);
    outline: none;
}


/* ═══ 6. Chrome ══════════════════════════════════════════════════════════
 * The bars paint from :root --portal-chrome-* primitives, outside `body`,
 * so §2 never reaches them.
 * ═══════════════════════════════════════════════════════════════════════ */

html[data-portal-theme="nxt"] #site-sidebar,
html[data-portal-theme="nxt"] #site-footer,
html[data-portal-theme="nxt"] #portal-tab-bar {
    background-color: var(--bz-surface-1) !important;
    background-image: none !important;
    box-shadow: none !important;
    color: var(--bz-text) !important;
    /* All four sides: the floated chrome shows every edge. */
    border-color: var(--bz-border) !important;
}

html[data-portal-theme="nxt"] #site-footer,
html[data-portal-theme="nxt"] #portal-tab-bar {
    border-top: 1px solid var(--bz-border) !important;
}

html[data-portal-theme="nxt"] #site-sidebar {
    border-right: 1px solid var(--bz-border) !important;
}

html[data-portal-theme="nxt"] #site-footer .portal-bar-breadcrumb,
html[data-portal-theme="nxt"] #site-footer .portal-launcher-btn,
html[data-portal-theme="nxt"] #site-footer .portal-bar-user-btn,
html[data-portal-theme="nxt"] #site-sidebar .portal-sidebar-link {
    color: var(--bz-text-dim) !important;
}

/* Tab bar states written out: a blanket !important colour would flatten
   the active tab into its neighbours. */
html[data-portal-theme="nxt"] #portal-tab-bar .portal-tab-link {
    color: var(--bz-text-muted) !important;
}

html[data-portal-theme="nxt"] #portal-tab-bar .portal-tab-link.is-active,
html[data-portal-theme="nxt"] #portal-tab-bar .portal-tab-link[aria-current] {
    color: var(--bz-accent-strong) !important;
}

html[data-portal-theme="nxt"] #site-sidebar .portal-sidebar-link i {
    color: var(--bz-text-muted) !important;
}

html[data-portal-theme="nxt"] #site-sidebar .portal-sidebar-link.active i,
html[data-portal-theme="nxt"] #site-sidebar .portal-sidebar-link[aria-current] i {
    color: var(--bz-accent-strong) !important;
}

html[data-portal-theme="nxt"] #site-sidebar .portal-sidebar-link:hover,
html[data-portal-theme="nxt"] #portal-tab-bar .portal-tab-link:hover {
    background-color: var(--bz-surface-2) !important;
    color: var(--bz-text) !important;
}

html[data-portal-theme="nxt"] #site-sidebar .portal-sidebar-link.active,
html[data-portal-theme="nxt"] #site-sidebar .portal-sidebar-link[aria-current] {
    background-color: var(--bz-surface-2) !important;
    box-shadow: inset 3px 0 0 var(--bz-accent) !important;
    color: var(--bz-text) !important;
}

html[data-portal-theme="nxt"] .portal-notif-btn,
html[data-portal-theme="nxt"] .portal-launcher-btn,
html[data-portal-theme="nxt"] .portal-bar-user-btn {
    background-color: transparent !important;
    border-color: var(--bz-border-strong) !important;
    box-shadow: none !important;
}

html[data-portal-theme="nxt"] .portal-notif-btn:hover,
html[data-portal-theme="nxt"] .portal-launcher-btn:hover,
html[data-portal-theme="nxt"] .portal-bar-user-btn:hover {
    background-color: var(--bz-surface-2) !important;
}

html[data-portal-theme="nxt"] .portal-icon-badge {
    box-shadow: none !important;
}

/* Menus are genuine overlays: opaque, keylined, one shadow. */
html[data-portal-theme="nxt"] .dropdown-menu {
    background-color: var(--bz-surface-1) !important;
    background-image: none !important;
    border: 1px solid var(--bz-border-strong) !important;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45) !important;
}

html[data-portal-theme="nxt"] .dropdown-menu .dropdown-header {
    color: var(--bz-text-muted) !important;
    letter-spacing: 0.055em;
    text-transform: uppercase;
}

html[data-portal-theme="nxt"] .dropdown-menu .dropdown-item {
    color: var(--bz-text-dim) !important;
}

html[data-portal-theme="nxt"] .dropdown-menu .dropdown-item:hover,
html[data-portal-theme="nxt"] .dropdown-menu .dropdown-item:focus {
    background-color: var(--bz-surface-2) !important;
    color: var(--bz-text) !important;
}

html[data-portal-theme="nxt"] .dropdown-menu .dropdown-item.active {
    background-color: var(--bz-surface-2) !important;
    box-shadow: inset 3px 0 0 var(--bz-accent) !important;
    color: var(--bz-text) !important;
}

html[data-portal-theme="nxt"] ::-webkit-scrollbar-track {
    background: var(--bz-bg);
}

html[data-portal-theme="nxt"] ::-webkit-scrollbar-thumb {
    background: var(--bz-surface-3);
    border-radius: 0;
}

html[data-portal-theme="nxt"] ::-webkit-scrollbar-thumb:hover {
    background: var(--bz-border-strong);
}


/* ═══ 7. Sliders — one rule per engine, never a shared list ══════════════ */

html[data-portal-theme="nxt"] .form-range::-webkit-slider-thumb {
    background: var(--bz-accent);
    box-shadow: none;
}

html[data-portal-theme="nxt"] .form-range::-webkit-slider-runnable-track {
    background: var(--bz-surface-2);
}

html[data-portal-theme="nxt"] .form-range::-moz-range-thumb {
    background: var(--bz-accent);
    box-shadow: none;
}

html[data-portal-theme="nxt"] .form-range::-moz-range-track {
    background: var(--bz-surface-2);
}

html[data-portal-theme="nxt"] .form-range:focus::-webkit-slider-thumb {
    box-shadow: var(--portal-c-focus-ring);
}

html[data-portal-theme="nxt"] .form-range:focus::-moz-range-thumb {
    box-shadow: var(--portal-c-focus-ring);
}


/* ═══ 8. The swatch ══════════════════════════════════════════════════════
 * NXT's surfaces are BrettZone's, so a swatch painted from them would be
 * pixel-identical to sport's — two rows in Appearance you cannot tell apart
 * (tests/visual/appearance.spec.js asserts every ground and every accent is
 * unique). What NXT actually looks like is the open canvas with the two
 * corners on it, so that is what its swatch shows: --bz-bg ground, and the
 * wedge split magenta | cyan. Under the split, the wedge's background-COLOR
 * is RAW brand pink (#cf23ca): cyan alone is dark's accent and accent-strong
 * is sport's, and the gate compares that colour, not the gradient.
 * ═══════════════════════════════════════════════════════════════════════ */

.portal-appearance-swatch.portal-theme-scope[data-portal-theme="nxt"],
.settings-theme-swatch.portal-theme-scope[data-portal-theme="nxt"] {
    background-color: var(--bz-bg);
    border-color: var(--bz-border-strong);
}

.portal-appearance-swatch.portal-theme-scope[data-portal-theme="nxt"]::after {
    background-color: var(--bz-accent);
    background-image: linear-gradient(90deg, var(--bz-accent) 50%, var(--bz-brand-teal) 50%);
}
