/* ---------------------------------------------------------------------------
   SHARED FIFTEEN light/dark theme — module core-feature standard.
   Served from _content/Fifteen.Web.Shared/. ONE definition inherited by Nexus,
   Hub and Comms (and any future module for free).

   This file carries:
     1. The topbar TOGGLE control styling (sun/moon glyph swap on data-theme).
     2. The LIGHT-mode overrides for the Metronic hosts' (Nexus / Hub) BESPOKE
        surfaces — the explicit dark hexes in their site.css that were authored
        to defeat Metronic's dark-mode gray inversion. Metronic itself re-themes
        its own chrome off data-bs-theme="light"; these rules re-theme the few
        bespoke surfaces our own CSS hardcoded, so the WHOLE UI re-themes — not
        just the body.

   Dark is the default; light is the opt-in via the toggle, persisted in
   localStorage ("fifteen-theme") and applied pre-paint by each layout's <head>
   snippet so there is no dark→light flash. The Metronic light palette below
   matches Operonn (commit 627930d) for cross-module uniformity: Keen #f5f8fa
   app background, near-black #181C32 ink, #E4E6EF borders.

   Comms is a non-Metronic custom layout with its own --comms-* variable system;
   its light remap lives in comms.css (Operonn-style token override) rather than
   here, because it has no Metronic chrome to lean on.
   --------------------------------------------------------------------------- */

/* ---------- Mobile horizontal-overflow backstop (house rule) ----------
   The page body must NEVER scroll horizontally; wide content scrolls inside its
   own overflow-x:auto box. This is the shell-wide backstop: at phone widths pin
   the root to the device width and clip any accidental horizontal overflow. It
   also keeps the mobile *layout viewport* from expanding to a wider document —
   which is what pins `position:fixed` chrome (the bottom-right assistant orb) to
   an off-screen document edge instead of the visible viewport. Mobile-scoped so
   desktop layout is untouched; fixed drawers/sidebar (own stacking context) are
   not clipped by root overflow. The actual crowded-header overflow is fixed at
   source (brand wordmark + demo toggle collapse below lg); this is insurance.

   overflow-x: CLIP, not HIDDEN (fix, 2026-07-17). `overflow-x: hidden` on the
   ROOT <html> makes it a scroll container and — per the CSS combination rule —
   forces the paired `overflow-y` to compute to `auto`. Inside the persistent
   app-shell iframe (body is sized to the iframe's viewport height), that turned
   <html> into a non-scrolling box clamped to the viewport: its scrollHeight
   collapsed to the viewport height and everything below the fold (e.g. the Save
   button on a long Edit form) became unreachable — the reported "Save can't be
   clicked" bug on mobile. `overflow-x: clip` clips the horizontal axis exactly
   the same (document can't widen → the fixed orb still anchors to the viewport)
   WITHOUT establishing a scroll container and WITHOUT forcing overflow-y to
   auto, so vertical scrolling keeps working and the whole form is reachable.
   clip + the default visible-y is an allowed combination (no forced auto). */
@media (max-width: 991.98px) {
    html, body { max-width: 100%; overflow-x: clip; }

    /* Header icon cluster must never be squeezed. The wrapper is flex-shrink:1
       by default, so under width pressure it shrinks — but its inner icons are
       flex-shrink:0, so they SPILL OUT of the shrunk wrapper and off the right
       edge (the reported "header icons cut off on the right" bug), while the
       brand block's flex-grow-1 grabs the freed space. Pinning the wrapper to
       flex-shrink:0 keeps it aligned with its non-shrinking content, so the
       cluster stays intact and the brand only grows into genuine free space. */
    #kt_app_header_wrapper { flex-shrink: 0; }

    /* The header brand block carries flex-grow-1 on mobile (flex-lg-grow-0 only
       kicks in at lg+), so it swallows the row's free space and shoves the icon
       cluster hard against — and past — the right edge, eating the container's
       own right padding. Pin the brand to its own content width (flex:0 0 auto)
       on mobile so it sits at its natural size top-left and justify-content:
       space-between parks the icon cluster at the right with the container
       padding preserved. Scoped to the header so no other flex-grow-1 is
       affected; id specificity + !important beat Bootstrap's flex utilities. */
    #kt_app_header_container > .flex-grow-1 { flex: 0 0 auto !important; }

    /* Trim the header's side padding on phones (Metronic ships 20px each side)
       so the crowded core-feature icon cluster has breathing room within the
       viewport. */
    #kt_app_header_container { padding-left: 12px; padding-right: 12px; }

    /* Persistent-shell CURRENT-MODULE name (Brad, 2026-07: the header names which
       MODULE the user is in, not the page). This whole block is already inside the
       max-width:991.98px query, and since 2026-08-13 that is the ONLY width the
       label appears at: at lg+ the sidebar's workspace switcher names the module
       and fifteen-shell.css hides this label as the duplicate it became. On phones
       the brand wordmark is already collapsed to its glyph, freeing the space, so
       the module name shows here — but kept COMPACT (capped width + ellipsis, no
       wrap) so it can never reintroduce the horizontal overflow the earlier phone
       fix guarded against. Empty on the shell owner (see :empty). */
    .app-shell-module-name {
        display: inline-block;
        max-width: 40vw;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        vertical-align: middle;
    }
    .app-shell-module-name:empty { display: none; }
}

/* ---------- Topbar toggle control ----------
   Sits in the host navbar. The Metronic hosts give it btn-icon chrome already;
   these rules only own the glyph swap + a graceful look on the plain Comms
   header. moon shown in dark (tap → light), sun shown in light (tap → dark). */
.fifteen-theme-toggle { cursor: pointer; }
.fifteen-theme-toggle .fifteen-theme-icon-light { display: none; }
.fifteen-theme-toggle .fifteen-theme-icon-dark { display: inline-block; }
html[data-theme="light"] .fifteen-theme-toggle .fifteen-theme-icon-light { display: inline-block; }
html[data-theme="light"] .fifteen-theme-toggle .fifteen-theme-icon-dark { display: none; }

/* =====================================================================
   METRONIC HOSTS — LIGHT THEME bespoke-surface overrides (Nexus + Hub).
   Scoped to html[data-theme="light"] so they are completely inert in dark
   (the default). Metronic's own bundle handles the body/card/sidebar chrome
   off data-bs-theme="light"; the rules below cover the explicit dark hexes
   our site.css set to defeat Metronic's dark-mode inversion.
   ===================================================================== */

/* App background — site.css hardcodes html/body to #15171c (dark). Now token-
   driven via --fx-body-bg (fallback = the original light value) so a theme can
   set its own light body colour; the Default theme's light value is #f4f6fa so
   this is pixel-identical. */
html[data-theme="light"] body,
html[data-theme="light"] {
    background-color: var(--fx-body-bg, #f4f6fa);
}

/* Page-header card — SHARED base (dark). Every NEXUSS/FIFTEEN module inherits
   the same shared _PageHeader card chrome, so the base panel styling lives here
   (Fifteen.Web.Shared) rather than only in the Nexus/Comms host CSS — Pulse,
   Reach, Site and any future module get it for free. Explicit hex values (not
   --kt-gray-*) so Metronic's dark-mode gray inversion can't flip the card to
   white. Nexus site.css / Comms comms.css keep an identical local copy;
   loaded-after-site.css means this shared rule wins with the same values. */
.page-header-card {
    background-color: #1e1e2d;
    border: 1px solid #2B2B40;
}
.page-header-card .page-header-actions .btn {
    margin: 0;
}

/* Page-header card — site.css pins #1e1e2d panel + #2B2B40 border (dark). Now
   token-driven via --fx-card-* (fallbacks = original light values). */
html[data-theme="light"] .page-header-card {
    background-color: var(--fx-card-bg, #ffffff);
    border-color: var(--fx-card-border, #e4e6ef);
}

/* Header bar STAYS DARK in light mode (NEX-39 — Brad hard requirement).
   The top header/brand bar must remain a DARK brand bar even when the app is in
   LIGHT theme. Metronic's light palette otherwise repaints .app-header white
   (--kt-app-header-base-bg-color: #ffffff), which is the WRONG behaviour: Brad's
   confirmed requirement is a dark header in BOTH themes. Re-pin the header
   background + its Metronic header tokens to the DARK values, scoped to
   .app-header under html[data-theme="light"] so dark mode is untouched, and
   keep the header foreground (wordmark, nav icons, user menu) light so
   everything stays legible on the dark bar. Shared file → every Metronic module
   (Nexus/Hub/Pulse/Reach/Site) inherits the dark header. */
/* NOW TOKEN-DRIVEN (NEX-39 preserved via the Default theme). The header colour
   is --fx-header-bg; the Default theme keeps the light value = #1e1e2d, so the
   header STAYS DARK in light mode exactly as before. A theme CAN now set a light
   header by giving --fx-header-bg a light value in its light map. Fallbacks equal
   the original dark re-pin, so an unthemed light render is pixel-identical. */
html[data-theme="light"] #kt_app_header.app-header,
html[data-theme="light"] .app-header {
    --kt-app-header-base-bg-color: var(--fx-header-bg, #1e1e2d);
    --kt-app-header-base-bg-color-mobile: var(--fx-header-bg, #1e1e2d);
    --kt-app-header-base-menu-link-bg-color-active: var(--fx-header-active-bg, #2A2A3C);
    --kt-app-header-light-separator-color: var(--fx-header-border, #2B2B40);
    background-color: var(--fx-header-bg, #1e1e2d) !important;
    border-bottom: 1px solid var(--fx-header-border, #2B2B40);
}
/* Brand wordmark + any header text: WHITE on the dark bar. This undoes the old
   51e24e98 near-black re-ink (which only made sense while the header wrongly
   went white); the header is dark again, so white is the correct, legible ink.
   The atom glyph keeps its own text-primary blue. Higher specificity than
   Bootstrap's `.text-white{color:#fff!important}` so it wins deterministically. */
html[data-theme="light"] .app-header .text-white {
    color: var(--fx-header-text, #ffffff) !important;
}
/* Header icon buttons — muted light glyph on the dark bar, primary on hover;
   matches the dark-theme header exactly (ticket, bell, theme toggle, demo-eye,
   mobile sidebar toggle are all `btn btn-icon btn-active-color-primary > i`). */
html[data-theme="light"] .app-header .btn.btn-icon,
html[data-theme="light"] .app-header .btn.btn-icon > i,
html[data-theme="light"] .app-header #kt_app_sidebar_mobile_toggle > i {
    color: var(--fx-header-icon, #9899ac) !important;
}
html[data-theme="light"] .app-header .btn.btn-icon:hover,
html[data-theme="light"] .app-header .btn.btn-icon:hover > i,
html[data-theme="light"] .app-header .btn.btn-active-color-primary:hover > i {
    color: var(--fx-header-icon-hover, #3699ff) !important;
}

/* Sidebar subgroup heading + collapsible caret — muted dark-grey hexes. */
/* The Nexus sidebar stays DARK in light theme (dark-sidebar layout), so these
   muted section-heading greys are token-driven via --fx-menu-heading[-hover] with
   the original light values as fallbacks. */
html[data-theme="light"] .app-sidebar .menu-section-heading,
html[data-theme="light"] .app-sidebar .menu-section-toggle .menu-section-text {
    color: var(--fx-menu-heading, #6b7280);
}
html[data-theme="light"] .app-sidebar .menu-section-toggle .menu-section-caret {
    border-color: var(--fx-menu-heading, #9aa0ad);
}
html[data-theme="light"] .app-sidebar .menu-section-toggle:hover .menu-section-text,
html[data-theme="light"] .app-sidebar .menu-section-toggle:hover .menu-section-caret {
    color: var(--fx-menu-heading-hover, #181c32);
    border-color: var(--fx-menu-heading-hover, #181c32);
}

/* Onboarding pills — keep the same soft-tinted look, slightly stronger ink
   for legibility on the light app background. */
html[data-theme="light"] .onboarding-pill.onboarding-newly-added { background: rgba(184, 117, 3, 0.12); color: #b87503; }
html[data-theme="light"] .onboarding-pill.onboarding-folders-provisioned { background: rgba(54, 153, 255, 0.12); color: #1c4f9c; }
html[data-theme="light"] .onboarding-pill.onboarding-assistant-provisioned { background: rgba(143, 75, 255, 0.12); color: #6b3fd1; }
html[data-theme="light"] .onboarding-pill.onboarding-active { background: rgba(19, 143, 94, 0.12); color: #138f5e; }

/* Bespoke form-input surface — site.css ALREADY ships a legible light surface
   as the base .nexus-form-input and scopes the dark variant to
   [data-theme="dark"], so light mode is correct with no override needed here.
   Documented so a future editor doesn't add a redundant rule. */

/* ---------- text-gray-* utility remap (LIGHT) — the load-bearing fix ----------
   The Razor pages universally use the `text-gray-100` utility to mean "prominent
   near-white heading" (194 uses), authored against the dark-sidebar mental
   model. fifteen-dark.css lifts gray-100/200/300 to near-WHITE for DARK; in
   Metronic's stock LIGHT palette gray-100 is genuinely a near-white light gray,
   so those headings paint near-white-on-white and vanish. This is the MIRROR of
   the fifteen-dark.css remap: in light mode the "prominent" gray tiers become
   dark INK so every heading / card title / table title re-themes — not just the
   body. (gray-400/500/600 are mid-grey on both backgrounds, left alone, same as
   fifteen-dark.) gray-900 — high-contrast ink in markup — returns to near-black.
   Scoped to html[data-theme="light"] so it is inert in dark. */
html[data-theme="light"] .text-gray-100 { color: #181c32 !important; }
html[data-theme="light"] .text-gray-200 { color: #1f2336 !important; }
html[data-theme="light"] .text-gray-300 { color: #2b2e43 !important; }
html[data-theme="light"] .text-gray-900 { color: #181c32 !important; }

/* ── Theme-aware + viewport-aware brand logo ─────────────────────────────
   Branding carries FOUR header logos: a WIDE desktop logo (light + dark) and a
   SQUARE mobile logo (light + dark) — one logo rarely reads on both light and
   dark chrome, and the wide wordmark doesn't fit the cramped mobile header.
   _BrandLockup renders all four <img>s; these rules show exactly ONE by
   (active theme × viewport width) and swap instantly when the viewer toggles
   theme (fifteen-theme.js flips html[data-theme]) or the viewport crosses the
   lg breakpoint. The mobile boundary is Bootstrap lg (992px) — the same point
   the header's mobile sidebar toggle (d-lg-none) appears.

   DESKTOP (default, ≥ 992px): show the wide desktop logo by theme; hide mobile. */
.fifteen-brand-logo-light { display: inline-block; }
.fifteen-brand-logo-dark { display: none; }
.fifteen-brand-logo-mobile-light,
.fifteen-brand-logo-mobile-dark { display: none; }
html[data-theme="dark"] .fifteen-brand-logo-light { display: none; }
html[data-theme="dark"] .fifteen-brand-logo-dark { display: inline-block; }

/* MOBILE (< 992px): hide the wide desktop logo, show the SQUARE mobile logo by theme. */
@media (max-width: 991.98px) {
    .fifteen-brand-logo-light,
    .fifteen-brand-logo-dark { display: none !important; }
    .fifteen-brand-logo-mobile-light { display: inline-block; }
    .fifteen-brand-logo-mobile-dark { display: none; }
    html[data-theme="dark"] .fifteen-brand-logo-mobile-light { display: none; }
    html[data-theme="dark"] .fifteen-brand-logo-mobile-dark { display: inline-block; }
}
