/* /Components/Layout/LoginLayout.razor.rz.scp.css */
.login-layout[b-giupkn0xdh] {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
}
/* /Components/Layout/MainLayout.razor.rz.scp.css */
/* IMP-086: renamed from the old .page/.sidebar pair (dotnet-new-blazor scaffold naming) to
   .shell/.shell-sidebar/.shell-main — no other file referenced the old class names (confirmed by
   repo-wide search before this rename). IMP-098 removed the fourth original member of that set,
   .shell-header (the "Top Shell") — see MainLayout.razor's own doc comment for why. */

.shell[b-cf3o206n63] {
    position: relative;
    z-index: var(--sail-z-base);
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

.shell-sidebar[b-cf3o206n63] {
    position: relative;
    z-index: var(--sail-z-sidebar);
    /* Mobile default (<641px, IMP-086 original, preserved): flush full-bleed bar — the floating glass
       panel treatment (IMP-096, below) is introduced only at the existing >=641px floor, never
       redesigning the mobile stacked/hamburger layout. */
    border-radius: 0;
    border-width: 0 1px 0 0;
}

.shell-main[b-cf3o206n63] {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-width: 0;
}

main[b-cf3o206n63] {
    flex: 1;
    min-width: 0;
}

/* Responsive floor (avoids horizontal page overflow, IMP-086): no element in the shell may force the
   page wider than its viewport, regardless of what a future page's own content does. */
.content[b-cf3o206n63] {
    max-width: 100%;
    overflow-x: hidden;
}

#blazor-error-ui[b-cf3o206n63] {
    color-scheme: light only;
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: var(--sail-z-toast);
}

    #blazor-error-ui .dismiss[b-cf3o206n63] {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }

/* Existing sub-641px mobile fallback: kept as a floor, not redesigned (UX-005 §6) — sidebar stacks
   above content, full width, exactly as the pre-IMP-086 .page/.sidebar pair already behaved. */

@media (min-width: 641px) {
    .shell[b-cf3o206n63] {
        flex-direction: row;
    }

    /* IMP-096/097/098: "premium glass cockpit panel" — the Sidebar detaches from the viewport edges on
       all four sides (top/bottom/left via margin, right via the natural flex gap this margin creates
       before .shell-main) rather than sitting flush like a conventional app sidebar. height/top/margin
       are sized from the same --sail-shell-float-inset token so the panel always fits exactly within
       the viewport with no scroll/overflow. Radius/border are restored to .sail-glass's own shared
       values (removing the flush-wall override above) so the Sidebar matches Command Center panels'
       radius language exactly. IMP-097 adds the Sidebar's own extra "thickness": a marginally crisper
       border than the shared shell-family border (--sail-glass-border-strong, reusing the existing
       content-panel token rather than inventing a new one), a richer two-stop reflection gradient
       (a brighter near-corner catch-light fading through the shared mid-tone sheen into the plain
       shell tint), and the strongest blur in the Shell family (--sail-sidebar-glass-blur). Never
       brighter overall: still the same --sail-shell-glass-bg tint/alpha as before, and the shared
       --sail-shell-elevation (app.css) already supplies the inset top-highlight/bottom-shadow bevel
       and richer outer shadow every Shell surface gets.
       IMP-098: display: flex/flex-direction: column turns the panel into NavMenu.razor's own two-part
       layout (brand+nav "upper section" above, the Workspace footer "lower section" below) — the
       previous plain-block Sidebar left NavMenu's .nav-scrollable to size itself from a hardcoded
       `calc(100vh - 3.5rem)` that didn't account for the Sidebar's own floating insets/brand-slot
       height, so the footer's existing margin-top: auto (NavMenu.razor.css, unchanged) pushed it to
       the bottom of an incorrectly-sized box rather than the Sidebar's true physical bottom. flex: 1 on
       .nav-scrollable (NavMenu.razor.css) now fills exactly the real remaining height instead. */
    .shell-sidebar[b-cf3o206n63] {
        height: calc(100vh - (2 * var(--sail-shell-float-inset)));
        position: sticky;
        top: var(--sail-shell-float-inset);
        margin: var(--sail-shell-float-inset);
        display: flex;
        flex-direction: column;
        overflow-y: auto;
        border-radius: var(--sail-radius-panel);
        border-width: 1px;
        /* IMP-100: a crisp Steel-Blue edge (was --sail-glass-border-strong, a neutral white-ish
           border) — the innermost of the glow's four layers, giving the perimeter a defined line
           before the glow blooms outward. */
        border-color: var(--sail-sidebar-border-glow);
        /* Corner reflections (IMP-099, unchanged by this ticket) — never a change to the base
           --sail-shell-glass-bg tint itself. */
        background:
            radial-gradient(120% 45% at 100% 100%, rgba(255, 255, 255, 0.03) 0%, transparent 60%),
            linear-gradient(165deg, rgba(255, 255, 255, 0.09) 0%, rgba(255, 255, 255, 0.04) 18%, rgba(255, 255, 255, 0) 46%),
            var(--sail-shell-glass-bg);
        -webkit-backdrop-filter: blur(var(--sail-sidebar-glass-blur));
        backdrop-filter: blur(var(--sail-sidebar-glass-blur));
        /* IMP-100: Steel-Blue-only glow, matching the ratified UX draft — replaces IMP-099's cyan+amber
           pair. --sail-shell-elevation supplies the neutral (non-color) inset top-highlight/bottom-
           shadow bevel and outer drop shadow; the four --sail-sidebar-glow-* layers (app.css) add the
           inner rim reflection, crisp/medium glow, and broad ambient bloom, all rgba(79, 179, 255, *)
           only. Static — no animation, per this ticket's explicit instruction. */
        box-shadow:
            var(--sail-shell-elevation),
            var(--sail-sidebar-glow-inner),
            var(--sail-sidebar-glow-crisp),
            var(--sail-sidebar-glow-medium),
            var(--sail-sidebar-glow-broad);
    }

    /* IMP-098: restores the Command Center's own premium breathing room now that the Top Shell (which
       previously supplied ~96px of top clearance via its own margin+height) is gone — without this, the
       Command Center's first card would sit only ~17.6px (the pre-existing base .content padding-top)
       below the true viewport edge, an abrupt regression against the Sidebar's own 18px floating inset
       right beside it. Deliberately more generous than the Sidebar's bare float inset (--sail-space-6,
       32px vs 18px) so the Command Center reads as comfortably placed inside the Shell's frame, not
       merely mirroring the Sidebar's own edge. Left/right unchanged. */
    article.content[b-cf3o206n63] {
        padding-top: var(--sail-space-6) !important;
        padding-left: 2rem !important;
        padding-right: 1.5rem !important;
    }
}

/* 1024px-class desktop/laptop (UX-005 §6 "slim collapsible sidebar rather than a fixed-width one at
   all desktop widths"): the sidebar narrows to an icon-only rail — NavMenu.razor.css hides the text
   labels/full wordmark at this same breakpoint pair. */
@media (min-width: 641px) and (max-width: 1279px) {
    .shell-sidebar[b-cf3o206n63] {
        width: 76px;
        flex: 0 0 76px;
    }
}

/* Wide desktop (default, IMP-086: "do not make the sidebar icon-only by default") */
@media (min-width: 1280px) {
    .shell-sidebar[b-cf3o206n63] {
        width: 264px;
        flex: 0 0 264px;
    }
}
/* /Components/Layout/NavMenu.razor.rz.scp.css */
/* ---------------------------------------------------------------------------------------------
   Brand slot (IMP-086, production asset wired in IMP-087) — replaces the old .top-row/.navbar-brand
   scaffold block. Two SailBrandMark instances (the component owns its own asset selection; this file
   only toggles which wrapper is visible): the wide symbol+wordmark lockup, and the icon-rail
   symbol-only mark (641px-1279px — see the media query at the bottom of this file).
   --------------------------------------------------------------------------------------------- */

.brand-slot[b-wp0td81zqd] {
    display: flex;
    align-items: center;
    /* IMP-096: modest breathing-room bump (3.5rem -> 3.75rem min-height, 1rem -> 1.25rem horizontal
       padding) so the brand mark doesn't sit flush against the now-floating Sidebar panel's own edges
       — a premium object needs internal margin, not just external detachment. Never a navigation
       redesign: same brand markup/logic, same collapsed/rail behavior below. */
    min-height: 3.75rem;
    padding: 0 1.25rem;
    /* IMP-095: lightened from rgba(0, 0, 0, 0.4) — that opaque fill stacked on top of the sidebar's own
       .sail-glass--shell tint compounded into a solid black band at the very top of the Sidebar,
       breaking the continuous ambient world exactly where the ticket's screenshot evidence flagged it.
       A restrained separator (the border-bottom below) is enough to mark the brand slot's boundary. */
    background-color: rgba(5, 7, 10, 0.16);
    border-bottom: 1px solid var(--sail-glass-border);
}

.brand-slot__link[b-wp0td81zqd] {
    display: flex;
    align-items: center;
    text-decoration: none;
}

.brand-slot__rail-mark[b-wp0td81zqd] {
    display: none;
}

/* ---------------------------------------------------------------------------------------------
   Navigation toggler (mobile, <641px — existing behavior kept as a floor per UX-005 §6).
   --------------------------------------------------------------------------------------------- */

.navbar-toggler[b-wp0td81zqd] {
    appearance: none;
    cursor: pointer;
    width: 3.5rem;
    height: 2.5rem;
    color: white;
    position: absolute;
    top: 0.5rem;
    right: 1rem;
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: var(--sail-radius-control);
    background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") no-repeat center/1.75rem rgba(255, 255, 255, 0.1);
}

.navbar-toggler:checked[b-wp0td81zqd] {
    background-color: rgba(255, 255, 255, 0.5);
}

.bi[b-wp0td81zqd] {
    display: inline-block;
    position: relative;
    width: 1.25rem;
    height: 1.25rem;
    margin-right: 0.75rem;
    top: -1px;
    background-size: cover;
    flex-shrink: 0;
}

/* IMP-115: per-nav-item icons (replacing the four/five-identical-house-icon flat nav DISC-042 §1
   flagged) are inline <svg>, stroke="currentColor", hand-drawn on a 20x20 grid, no hotlinked asset —
   rather than the older .bi background-image data-URI approach, which remains only for Sign Out below.
   currentColor means each icon matches its own nav-link's current text color (muted by default, white
   on hover/active).

   ENG-command-center-layout-rebuild AMENDED THIS COMMENT. It previously said "no icon library" and that
   an icon is "never a second, independent color cue, only a shape cue alongside the label". Both
   sentences are now false of the product as a whole, and are corrected here rather than left for a
   later reader to trip over:

   1. THERE IS NOW AN ICON LIBRARY. Phosphor Icons (MIT, "Copyright (c) 2023 Phosphor Icons") is
      vendored under wwwroot/icons/phosphor, with its LICENSE beside the files exactly as the fonts ship
      OFL.txt. It is used by the Command Center's tiles. Hand-drawing did not scale to filled, coloured
      tile icons, which is what that surface needed.

   2. THE SIDEBAR STILL USES THE HAND-DRAWN ICONS ABOVE, and that is a deliberate interim, not an
      oversight. Two idioms coexist: hand-drawn stroke icons here, vendored Phosphor duotone on the
      tiles. Converging them is a real decision with its own visual consequences and belongs to its own
      ticket — do not "tidy" one into the other on the way past.

   3. ON COLOUR: the tile icons DO carry colour, but it is IDENTITY, never status — orange means "this
      is the Goals tile", not "Goals are bad" (see the --cc-tile-* tokens in Home.razor.css, which
      deliberately avoid the semantic palette for that reason). The rule these nav icons follow — colour
      from context, never an independent signal — is unchanged HERE and still binding for the sidebar. */
.nav-link__icon[b-wp0td81zqd] {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 1.25rem;
    height: 1.25rem;
    margin-right: 0.75rem;
}

    .nav-link__icon svg[b-wp0td81zqd] {
        width: 100%;
        height: 100%;
    }

.bi-box-arrow-right-nav-menu[b-wp0td81zqd] {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-box-arrow-right' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M10 12.5a.5.5 0 0 1-.5.5h-8a.5.5 0 0 1-.5-.5v-9a.5.5 0 0 1 .5-.5h8a.5.5 0 0 1 .5.5v2a.5.5 0 0 0 1 0v-2A1.5 1.5 0 0 0 9.5 2h-8A1.5 1.5 0 0 0 0 3.5v9A1.5 1.5 0 0 0 1.5 14h8a1.5 1.5 0 0 0 1.5-1.5v-2a.5.5 0 0 0-1 0z'/%3E%3Cpath fill-rule='evenodd' d='M15.854 8.354a.5.5 0 0 0 0-.708l-3-3a.5.5 0 0 0-.708.708L14.293 7.5H5.5a.5.5 0 0 0 0 1h8.793l-2.147 2.146a.5.5 0 0 0 .708.708z'/%3E%3C/svg%3E");
}

/* IMP-107: the Sign Out control is a <button>, not an <a> — resets the browser's default button
   chrome so it renders pixel-identical to the NavLink items above it. */
.nav-item[b-wp0td81zqd]  button.nav-link {
    font: inherit;
    text-align: left;
    cursor: pointer;
}

/* IMP-115/ENG-049 §251: the three navigation groups (Operate/Manage/Reference) reflect user intent —
   pure structural grouping, never a second Business/architecture concept. Each group's label is a
   plain, non-interactive <p> (never a button/link/heading that would compete with the page's own
   heading structure) so it cannot be tabbed to or activated. */
.nav-group + .nav-group[b-wp0td81zqd] {
    margin-top: 0.5rem;
}

.nav-group__label[b-wp0td81zqd] {
    margin: 0;
    padding: 0 1.25rem 0.35rem;
    color: var(--sail-text-muted);
    font-size: var(--sail-text-2xs);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    border-left: 3px solid transparent;
}

/* IMP-115/ENG-047 §9: an open Operational Workspace (/work/{key}) is a contextual destination, not a
   permanent nav entry — neither Bridge nor Command Center's own <NavLink> becomes active for it. This
   subtly marks the Operate group label itself (border accent + weight, never color alone, matching the
   existing .nav-item ::deep a.active convention below) so the sidebar still orients the player toward
   "you are operating" without fabricating a third active link. */
.nav-group--contextual .nav-group__label[b-wp0td81zqd] {
    border-left-color: var(--sail-accent);
    color: #d7d7d7;
    font-weight: 600;
}

.nav-item[b-wp0td81zqd] {
    font-size: 0.9rem;
    padding-bottom: 0.5rem;
}

    .nav-item:first-of-type[b-wp0td81zqd] {
        padding-top: 1rem;
    }

    .nav-item:last-of-type[b-wp0td81zqd] {
        padding-bottom: 1rem;
    }

    .nav-item[b-wp0td81zqd]  .nav-link {
        color: #d7d7d7;
        background: none;
        border: none;
        border-left: 3px solid transparent;
        border-radius: 0 var(--sail-radius-control) var(--sail-radius-control) 0;
        height: 3rem;
        display: flex;
        align-items: center;
        line-height: 3rem;
        width: 100%;
        transition: background-color var(--sail-transition-base) var(--sail-ease),
                    color var(--sail-transition-base) var(--sail-ease),
                    border-color var(--sail-transition-base) var(--sail-ease);
    }

/* Active state (IMP-086): never color alone — a distinct left border accent joins the background
   tint/text-color change, and Blazor's NavLink already applies aria-current="page" for screen
   readers, so the state is legible without relying on hue perception at all. */
.nav-item[b-wp0td81zqd]  a.active {
    background-color: rgba(255, 255, 255, 0.12);
    border-left-color: var(--sail-accent);
    color: white;
}

.nav-item[b-wp0td81zqd]  .nav-link:hover {
    background-color: rgba(255, 255, 255, 0.08);
    color: white;
}

.nav-link__label[b-wp0td81zqd] {
    white-space: nowrap;
}

.nav-scrollable[b-wp0td81zqd] {
    display: none;
}

.navbar-toggler:checked ~ .nav-scrollable[b-wp0td81zqd] {
    display: block;
}

/* ---------------------------------------------------------------------------------------------
   Workspace footer (IMP-086, extended IMP-099, redesigned IMP-100 to match the ratified UX draft) —
   sits below the nav list, inside the same collapsible region as the nav on mobile. Four compact,
   icon-led rows (Workspace, Local Time, EVE Time, Weather) separated by subtle inset dividers —
   deliberately quiet environmental context, never four large cards and never styled as prominently as
   an operational surface. Anchored to the Sidebar's true physical bottom via margin-top: auto inside
   .nav-scrollable's own flex column (MainLayout.razor.css/NavMenu.razor.css §641px block, IMP-098's
   own fix for this).
   --------------------------------------------------------------------------------------------- */

.workspace-identity[b-wp0td81zqd] {
    display: flex;
    flex-direction: column;
    margin-top: auto;
    /* IMP-096: modest breathing-room bump (0.85rem -> 1rem vertical), matching the brand-slot's own
       increase above. */
    padding: 1rem 1.5rem;
    border-top: 1px solid var(--sail-glass-border);
}

.workspace-identity__row[b-wp0td81zqd] {
    display: flex;
    align-items: flex-start;
    gap: 0.65rem;
    padding: 0.15rem 0;
}

/* IMP-100: repository-local inline outline SVGs only (never a hotlinked asset or icon-library
   dependency) — sized/stroked consistently and tinted Steel Blue ("informational tint"), matching the
   Sidebar's own restored glow color language without implying semantic (Ready/Caution/Blocked) state.
   Always aria-hidden (set in NavMenu.razor) — the adjacent label/value text is what actually conveys
   meaning, per this ticket's own accessibility instruction. */
.workspace-identity__icon[b-wp0td81zqd] {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 1.15rem;
    height: 1.15rem;
    margin-top: 0.05rem;
    color: var(--sail-accent);
    opacity: 0.8;
}

    .workspace-identity__icon svg[b-wp0td81zqd] {
        width: 100%;
        height: 100%;
    }

.workspace-identity__content[b-wp0td81zqd] {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}

/* IMP-100: a subtle horizontal divider between rows — inset (not full-bleed) and deliberately quieter
   than the Sidebar's own (crisper, Steel-Blue) perimeter border, so the two never compete. */
.workspace-identity__divider[b-wp0td81zqd] {
    height: 1px;
    margin: 0.55rem 0.1rem;
    background: var(--sail-glass-border);
}

.workspace-identity__label[b-wp0td81zqd] {
    color: var(--sail-text-muted);
    font-size: var(--sail-text-2xs);
    letter-spacing: 0.08em;
}

.workspace-identity__value[b-wp0td81zqd] {
    color: var(--sail-text);
    font-size: var(--sail-text-sm);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* IMP-099: the secondary line within a row (the Local date under the Local time, the "UTC" tag
   under the EVE time, the Weather placeholder message) — deliberately quieter/smaller than
   .workspace-identity__value, exactly like .cc-character-portrait__meta's own "metadata is quieter
   than identity" precedent elsewhere in Sail. */
.workspace-identity__meta[b-wp0td81zqd] {
    color: var(--sail-text-muted);
    font-size: var(--sail-text-2xs);
    opacity: 0.85;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

@media (min-width: 641px) {
    .navbar-toggler[b-wp0td81zqd] {
        display: none;
    }

    .nav-scrollable[b-wp0td81zqd] {
        /* Never collapse the sidebar for wide screens */
        display: flex;
        flex-direction: column;

        /* IMP-098: flex: 1 (was a hardcoded height: calc(100vh - 3.5rem)) — that fixed value didn't
           account for the floating Sidebar's own insets/brand-slot height (MainLayout.razor.css), so
           it under/over-sized this box relative to the Sidebar's real available height, leaving
           .workspace-identity's own margin-top: auto (below) pushing it to the bottom of the wrong
           box rather than the Sidebar's true physical bottom. .shell-sidebar is now the flex column
           (MainLayout.razor.css) and this element is its second/lower flex item, so flex: 1 always
           fills exactly the real remaining space after the brand slot — the nav list stays top-aligned
           and the footer's own existing margin-top: auto still pushes it down, but now within a
           correctly-sized box, landing it at the Sidebar's actual bottom. Still scrolls internally
           (overflow-y: auto) if the nav list ever grows tall enough to need it. */
        flex: 1;
        min-height: 0;
        overflow-y: auto;
    }
}

/* 1024px-class desktop/laptop (UX-005 §6): icon-only rail — labels/workspace value hide visually but
   stay in the accessibility tree (clip, not display:none) so keyboard/screen-reader navigation is
   unaffected; the symbol-only SailBrandMark replaces the wide symbol+wordmark lockup (IMP-087: never
   the dark-tile compact asset here — see SailBrandPresentation.SymbolOnly's own doc comment). */
@media (min-width: 641px) and (max-width: 1279px) {
    .brand-slot[b-wp0td81zqd] {
        justify-content: center;
        padding: 0;
    }

    .brand-slot__wide-mark[b-wp0td81zqd] {
        display: none;
    }

    .brand-slot__rail-mark[b-wp0td81zqd] {
        display: block;
    }

    .nav-item[b-wp0td81zqd]  .nav-link {
        justify-content: center;
    }

    .bi[b-wp0td81zqd],
    .nav-link__icon[b-wp0td81zqd] {
        margin-right: 0;
    }

    /* IMP-100/115: clips the whole .workspace-identity__content wrapper (label + value + meta together)
       plus the new nav-group__label captions — equivalent to the previous per-class list, just simpler
       now that all three always live inside one wrapper per row. Screen readers still read this text
       (clip, never display: none); only each row/group's own icon (kept visible) is what a sighted
       icon-rail user sees, matching the ticket's explicit "compact icon-only contextual indicators with
       accessible labels" choice — the same pattern the nav items themselves already use at this exact
       breakpoint. */
    .nav-link__label[b-wp0td81zqd],
    .nav-group__label[b-wp0td81zqd],
    .workspace-identity__content[b-wp0td81zqd] {
        position: absolute;
        width: 1px;
        height: 1px;
        padding: 0;
        margin: -1px;
        overflow: hidden;
        clip: rect(0, 0, 0, 0);
        white-space: nowrap;
        border: 0;
    }

    .workspace-identity[b-wp0td81zqd] {
        align-items: center;
        padding: 1rem 0.5rem;
    }

    .workspace-identity__row[b-wp0td81zqd] {
        justify-content: center;
    }

    .workspace-identity__divider[b-wp0td81zqd] {
        margin: 0.55rem 0.35rem;
    }
}
/* /Components/Layout/ReconnectModal.razor.rz.scp.css */
.components-reconnect-first-attempt-visible[b-u7yuujqrkz],
.components-reconnect-repeated-attempt-visible[b-u7yuujqrkz],
.components-reconnect-failed-visible[b-u7yuujqrkz],
.components-pause-visible[b-u7yuujqrkz],
.components-resume-failed-visible[b-u7yuujqrkz],
.components-rejoining-animation[b-u7yuujqrkz] {
    display: none;
}

#components-reconnect-modal.components-reconnect-show .components-reconnect-first-attempt-visible[b-u7yuujqrkz],
#components-reconnect-modal.components-reconnect-show .components-rejoining-animation[b-u7yuujqrkz],
#components-reconnect-modal.components-reconnect-paused .components-pause-visible[b-u7yuujqrkz],
#components-reconnect-modal.components-reconnect-resume-failed .components-resume-failed-visible[b-u7yuujqrkz],
#components-reconnect-modal.components-reconnect-retrying[b-u7yuujqrkz],
#components-reconnect-modal.components-reconnect-retrying .components-reconnect-repeated-attempt-visible[b-u7yuujqrkz],
#components-reconnect-modal.components-reconnect-retrying .components-rejoining-animation[b-u7yuujqrkz],
#components-reconnect-modal.components-reconnect-failed[b-u7yuujqrkz],
#components-reconnect-modal.components-reconnect-failed .components-reconnect-failed-visible[b-u7yuujqrkz] {
    display: block;
}


#components-reconnect-modal[b-u7yuujqrkz] {
    background-color: white;
    width: 20rem;
    margin: 20vh auto;
    padding: 2rem;
    border: 0;
    border-radius: 0.5rem;
    box-shadow: 0 3px 6px 2px rgba(0, 0, 0, 0.3);
    opacity: 0;
    transition: display 0.5s allow-discrete, overlay 0.5s allow-discrete;
    animation: components-reconnect-modal-fadeOutOpacity-b-u7yuujqrkz 0.5s both;
    &[open]

{
    animation: components-reconnect-modal-slideUp-b-u7yuujqrkz 1.5s cubic-bezier(.05, .89, .25, 1.02) 0.3s, components-reconnect-modal-fadeInOpacity-b-u7yuujqrkz 0.5s ease-in-out 0.3s;
    animation-fill-mode: both;
}

}

#components-reconnect-modal[b-u7yuujqrkz]::backdrop {
    background-color: rgba(0, 0, 0, 0.4);
    animation: components-reconnect-modal-fadeInOpacity-b-u7yuujqrkz 0.5s ease-in-out;
    opacity: 1;
}

@keyframes components-reconnect-modal-slideUp-b-u7yuujqrkz {
    0% {
        transform: translateY(30px) scale(0.95);
    }

    100% {
        transform: translateY(0);
    }
}

@keyframes components-reconnect-modal-fadeInOpacity-b-u7yuujqrkz {
    0% {
        opacity: 0;
    }

    100% {
        opacity: 1;
    }
}

@keyframes components-reconnect-modal-fadeOutOpacity-b-u7yuujqrkz {
    0% {
        opacity: 1;
    }

    100% {
        opacity: 0;
    }
}

.components-reconnect-container[b-u7yuujqrkz] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
}

#components-reconnect-modal p[b-u7yuujqrkz] {
    margin: 0;
    text-align: center;
}

#components-reconnect-modal button[b-u7yuujqrkz] {
    border: 0;
    background-color: #6b9ed2;
    color: white;
    padding: 4px 24px;
    border-radius: 4px;
}

    #components-reconnect-modal button:hover[b-u7yuujqrkz] {
        background-color: #3b6ea2;
    }

    #components-reconnect-modal button:active[b-u7yuujqrkz] {
        background-color: #6b9ed2;
    }

.components-rejoining-animation[b-u7yuujqrkz] {
    position: relative;
    width: 80px;
    height: 80px;
}

    .components-rejoining-animation div[b-u7yuujqrkz] {
        position: absolute;
        border: 3px solid #0087ff;
        opacity: 1;
        border-radius: 50%;
        animation: components-rejoining-animation-b-u7yuujqrkz 1.5s cubic-bezier(0, 0.2, 0.8, 1) infinite;
    }

        .components-rejoining-animation div:nth-child(2)[b-u7yuujqrkz] {
            animation-delay: -0.5s;
        }

@keyframes components-rejoining-animation-b-u7yuujqrkz {
    0% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 0;
    }

    4.9% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 0;
    }

    5% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 1;
    }

    100% {
        top: 0px;
        left: 0px;
        width: 80px;
        height: 80px;
        opacity: 0;
    }
}
/* /Components/Layout/SailBrandMark.razor.rz.scp.css */
.sail-brand-mark[b-dhch1109zy] {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
}

.sail-brand-mark--symbol-only[b-dhch1109zy],
.sail-brand-mark--compact[b-dhch1109zy] {
    justify-content: center;
}

.sail-brand-mark__symbol[b-dhch1109zy],
.sail-brand-mark__tile[b-dhch1109zy] {
    display: block;
    height: 1.9rem;
    width: auto;
    flex-shrink: 0;
}

/* sail-brand-spec.md §5: the wordmark renders in its ratified typeface — "Saira Condensed", Weight 600.
   No longer a limitation: the family is vendored under wwwroot/fonts/saira-condensed with its own
   OFL.txt, and --sail-font-wordmark (app.css) resolves to it.

   It ships UNMODIFIED, and that is a licence requirement rather than a preference. Its own OFL.txt
   reserves the font name — "Copyright 2016 The Saira Project Authors (omnibus.type@gmail.com), with
   reserved font name "Saira"." — and OFL 1.1 condition 3 forbids a Modified Version from using a
   Reserved Font Name. Subsetting is modification. Anyone tempted to shrink this file (it is 96 KB to
   render four characters) must either leave it unmodified or rename the family so it no longer presents
   itself as "Saira".

   Its own font-family token rather than --sail-font-technical: this is genuinely a different typeface
   from the heading font, exactly as --sail-wordmark-color is a different colour from --sail-text. It is
   not a way around the ENG-technical-font-class-split guard, which bars scoped stylesheets from reaching
   for the *technical* token to escape the caps bundle.

   The weight and the .03em tracking below are brand-spec requirements of their own and were never part
   of that caps bundle — the split preserved them deliberately, and so does this. */
.sail-brand-mark__wordmark[b-dhch1109zy] {
    font-family: var(--sail-font-wordmark);
    font-weight: 600;
    font-size: var(--sail-text-lg);
    letter-spacing: 0.03em;
    /* Deliberately the dedicated --sail-wordmark-color token, never any semantic status token — the
       wordmark must never receive alert tinting (sail-brand-spec.md §4, IMP-087 explicit instruction). */
    color: var(--sail-wordmark-color);
    white-space: nowrap;
}

/* A subtle, honest "the mark just changed" cue (IMP-087) — never a duplicate visible mark: the previous
   <img> element is fully removed (its @key differs) before this one mounts and fades in from partial
   opacity. Automatically disabled for reduced-motion users by IMP-086's existing global
   `@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.001ms !important; } }`
   rule in app.css — no separate reduced-motion handling is needed here. No glow/neon (sail-brand-spec.md §7 Don't). */
@keyframes sail-brand-symbol-enter-b-dhch1109zy {
    from { opacity: 0.35; }
    to { opacity: 1; }
}

.sail-brand-mark__symbol[b-dhch1109zy],
.sail-brand-mark__tile[b-dhch1109zy] {
    animation: sail-brand-symbol-enter-b-dhch1109zy var(--sail-transition-slow) var(--sail-ease);
}
/* /Components/Pages/GoalDetail.razor.rz.scp.css */
/* IMP-091 (UX-008 §6): the Goal detail view's own scoped styles.

   Deliberately self-contained. Blazor CSS isolation scopes every .razor.css to its own component, so
   Home's cc-link/cc-refresh and OperationalWorkspace's ows-* are unreachable from here — a class name
   borrowed across components silently renders unstyled. Only the genuinely global utilities from
   wwwroot/app.css (sail-glass, sail-glass--strong, sail-font-technical, sail-glow-*) are shared. */

/* BUILD -- widen the goal page layout (reports/ENG-goal-page-width-and-blueprint-column-summary.md):
   90rem (1440px), matching Command Center's own already-shipped wide-page precedent (Home.razor.css's
   1400px) -- up from 60rem (960px), which starved the job tables below of the width they need (the
   Blueprint column's own text/dropdown collision this ticket also fixes). Page-scoped (Blazor CSS
   isolation): Bridge/Goals/Hubs/Policies/Reference each declare their OWN independent 60rem on their OWN
   root class in their OWN .razor.css file -- none of them share this selector, so widening it here
   cannot affect any other page. */
.goal-detail[b-6y77f7l2wh] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding: 1.5rem;
    max-width: 90rem;
    margin: 0 auto;
}

/* The EXCEPTION to the width above: prose/summary sections ("What to do", "Why this state", "Where it
   stands") stay at the page's own OLD 60rem measure -- long lines of prose across the new 90rem width
   would be worse, not better, to read. align-self: flex-start (rather than center) keeps this section's
   own LEFT edge flush with the wide table sections around it -- only the right edge stops early, so every
   section on the page still reads from one shared left rail rather than some being centered and others
   left-aligned. Tables and rows (goal-detail__job-table, the reaction schedule, the acquisition/production
   plan lists) are NOT given this modifier -- they use the new full width above. */
.goal-detail__section--prose[b-6y77f7l2wh] {
    width: 100%;
    max-width: 60rem;
    align-self: flex-start;
}

.goal-detail__return[b-6y77f7l2wh] {
    display: flex;
    gap: 1rem;
}

.goal-detail__link[b-6y77f7l2wh] {
    color: var(--sail-accent);
    text-decoration: none;
    font-size: 0.9rem;
}

.goal-detail__link:hover[b-6y77f7l2wh] {
    text-decoration: underline;
}

.goal-detail__loading[b-6y77f7l2wh] {
    color: var(--sail-text-muted);
}

/* --- panels (load failure, absent Goal) --------------------------------------------------------- */

.goal-detail__panel[b-6y77f7l2wh] {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    align-items: flex-start;
    padding: 1.5rem;
    border-radius: var(--sail-radius-panel, 1.25rem);
}

.goal-detail__eyebrow[b-6y77f7l2wh] {
    margin: 0;
    font-size: 0.75rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--sail-text-muted);
}

.goal-detail__panel-headline[b-6y77f7l2wh] {
    margin: 0;
    font-size: 1.3rem;
    color: var(--sail-text);
}

.goal-detail__panel-body[b-6y77f7l2wh] {
    margin: 0;
    color: var(--sail-text-muted);
}

/* --- the Goal ----------------------------------------------------------------------------------- */

.goal-detail__goal[b-6y77f7l2wh] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.goal-detail__header[b-6y77f7l2wh] {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    padding: 1.5rem;
    border-radius: var(--sail-radius-panel, 1.25rem);
}

.goal-detail__media[b-6y77f7l2wh] {
    flex-shrink: 0;
}

.goal-detail__identity[b-6y77f7l2wh] {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.4rem;
    min-width: 0;
}

.goal-detail__title[b-6y77f7l2wh] {
    margin: 0;
    font-size: 1.5rem;
    color: var(--sail-text);
}

.goal-detail__badge[b-6y77f7l2wh] {
    padding: 0.2rem 0.6rem;
    border-radius: var(--sail-radius-pill, 999px);
    font-size: 0.8rem;
    letter-spacing: 0.02em;
    color: var(--sail-text-muted);
    border: 1px solid var(--sail-border);
}

.goal-detail__value[b-6y77f7l2wh] {
    font-size: 0.9rem;
    color: var(--sail-text-muted);
}

/* --- sections ----------------------------------------------------------------------------------- */

.goal-detail__section[b-6y77f7l2wh] {
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
    padding: 1.25rem 1.5rem;
    border-radius: var(--sail-radius-panel, 1.25rem);
}

.goal-detail__heading[b-6y77f7l2wh] {
    margin: 0;
    font-size: 1rem;
    color: var(--sail-text);
}

.goal-detail__subheading[b-6y77f7l2wh] {
    margin: 0.4rem 0 0;
    font-size: 0.85rem;
    color: var(--sail-text-muted);
}

/* The one instruction — visually dominant, never rivalled by the supporting list below it. */

.goal-detail__instruction[b-6y77f7l2wh] {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    padding: 0.9rem 1rem;
    border-radius: var(--sail-radius-control, 0.625rem);
    border: 1px solid var(--sail-accent);
}

.goal-detail__instruction-text[b-6y77f7l2wh] {
    margin: 0;
    font-size: 1.05rem;
    color: var(--sail-text);
}

/* ENG-goal-detail-duplication-fix: .goal-detail__instruction-explanation is gone with the element it
   styled — the dominant instruction's explanation is the same string "Why this state" renders, and it now
   renders only there. Removed rather than left orphaned, so the stylesheet does not imply an element that
   no longer exists. */

.goal-detail__kind[b-6y77f7l2wh] {
    font-size: 0.7rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--sail-text-muted);
}

.goal-detail__no-action[b-6y77f7l2wh] {
    margin: 0;
    color: var(--sail-text-muted);
}

.goal-detail__supporting-list[b-6y77f7l2wh] {
    list-style: none;
    margin: 0.3rem 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.goal-detail__supporting-list > li[b-6y77f7l2wh] {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.goal-detail__supporting-text[b-6y77f7l2wh] {
    color: var(--sail-text-muted);
}

.goal-detail__supporting-explanation[b-6y77f7l2wh] {
    font-size: 0.85rem;
    color: var(--sail-text-muted);
    opacity: 0.85;
}

/* --- why this state ----------------------------------------------------------------------------- */

.goal-detail__explanation[b-6y77f7l2wh] {
    margin: 0;
    color: var(--sail-text-muted);
}

.goal-detail__group[b-6y77f7l2wh] {
    display: flex;
    gap: 0.6rem;
    align-items: baseline;
}

.goal-detail__group-label[b-6y77f7l2wh] {
    flex-shrink: 0;
    min-width: 4rem;
    font-size: 0.7rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--sail-text-muted);
}

.goal-detail__group-text[b-6y77f7l2wh] {
    color: var(--sail-text);
}

.goal-detail__owned-unresolved[b-6y77f7l2wh] {
    margin: 0;
    font-size: 0.9rem;
    color: var(--sail-text-muted);
}

/* --- where it stands ---------------------------------------------------------------------------- */

.goal-detail__facts[b-6y77f7l2wh] {
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 1.25rem;
}

.goal-detail__fact[b-6y77f7l2wh] {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.goal-detail__fact dt[b-6y77f7l2wh] {
    font-size: 0.7rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--sail-text-muted);
}

.goal-detail__fact dd[b-6y77f7l2wh] {
    margin: 0;
    color: var(--sail-text);
}

.goal-detail__absent[b-6y77f7l2wh],
.goal-detail__queue[b-6y77f7l2wh] {
    margin: 0;
    font-size: 0.9rem;
    color: var(--sail-text-muted);
}

/* ENG-where-it-stands-production-hubs: the build Goal's "built at …" line. Ordinary text rather than the
   muted tone its predecessor shared with .goal-detail__absent — that one reports an ABSENCE, this states a
   fact the reader came here for. Deliberately one flat colour with no emphasis of its own: a tone keyed on
   the Hub count, or a highlight on a Hub name, would turn naming into judging. */
.goal-detail__production-hubs[b-6y77f7l2wh] {
    margin: 0;
    font-size: 0.9rem;
    color: var(--sail-text);
}

/* --- production plan (ENG-staged-plan-ui) -------------------------------------------------------- */

.goal-detail__plan-stage[b-6y77f7l2wh] {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    padding: 0.9rem 1rem;
    border-radius: var(--sail-radius-control, 0.625rem);
    border: 1px solid var(--sail-border);
}

.goal-detail__plan-stage--final[b-6y77f7l2wh] {
    border-color: var(--sail-positive);
}

/* The stage IS a <details> (ENG-staged-plan-legibility) — this is its <summary>, styled as the same flex
   row the old always-visible header used, with the native disclosure marker left in place (no shared
   collapsible component in this repo; mirrors ProductionTreeView's own established <details> pattern). */
.goal-detail__plan-stage-summary[b-6y77f7l2wh] {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    cursor: pointer;
}

.goal-detail__plan-stage[open] > .goal-detail__plan-stage-summary[b-6y77f7l2wh] {
    margin-bottom: 0.2rem;
}

.goal-detail__plan-stage-badge[b-6y77f7l2wh] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.6rem;
    height: 1.6rem;
    padding: 0 0.4rem;
    border-radius: var(--sail-radius-pill, 999px);
    background: var(--sail-accent);
    color: var(--sail-bg);
    font-size: 0.8rem;
    font-weight: 600;
}

.goal-detail__plan-stage--final .goal-detail__plan-stage-badge[b-6y77f7l2wh] {
    background: var(--sail-positive);
}

.goal-detail__plan-stage-title[b-6y77f7l2wh] {
    font-size: 0.95rem;
    color: var(--sail-text);
}

.goal-detail__plan-stage-count[b-6y77f7l2wh] {
    font-size: 0.8rem;
    color: var(--sail-text-muted);
}

.goal-detail__plan-stage-body[b-6y77f7l2wh] {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

/* The "incoming raw materials" fold (ENG-staged-plan-legibility) — collapsed by default; on a real,
   mineral-heavy Goal this is the single biggest legibility win, often dozens of lines folded to one. */
.goal-detail__plan-incoming[b-6y77f7l2wh] {
    padding: 0.75rem 1rem;
    border-radius: var(--sail-radius-control, 0.625rem);
    border: 1px dashed var(--sail-border);
}

.goal-detail__plan-incoming-summary[b-6y77f7l2wh] {
    cursor: pointer;
    font-size: 0.85rem;
    color: var(--sail-text-muted);
}

.goal-detail__plan-incoming[open] > .goal-detail__plan-incoming-summary[b-6y77f7l2wh] {
    margin-bottom: 0.5rem;
}

.goal-detail__plan-build-group[b-6y77f7l2wh] {
    padding-left: 0.6rem;
    border-left: 2px solid var(--sail-border);
}

.goal-detail__plan-build-group--unrouted[b-6y77f7l2wh] {
    border-left-color: var(--sail-caution);
}

.goal-detail__plan-build-group-heading[b-6y77f7l2wh] {
    margin: 0 0 0.25rem;
    font-size: 0.85rem;
    color: var(--sail-text-muted);
}

.goal-detail__plan-build-group-heading--caution[b-6y77f7l2wh] {
    color: var(--sail-caution);
}

.goal-detail__plan-material-list[b-6y77f7l2wh] {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.goal-detail__plan-material-list > li[b-6y77f7l2wh] {
    color: var(--sail-text);
    font-size: 0.9rem;
}

/* ENG-goal-page-icons-align-transport-acquisition: the one shared icon+name alignment rule for every
   EVE-item-icon row on this page (staged-plan materials, job-table Product cell, transport lines, the
   acquisition box) — mirrors ProductionTreeView.razor.css's own .pt-row__name (inline-flex + centered
   items is what actually centers a small EveVisual against its text baseline; without a flex wrapper the
   icon sits on the text's own baseline instead of centered against the line, which read as "vertically
   offset"). One class instead of repeating this per surface, so a 5th surface never re-derives it. */
.goal-detail__icon-row[b-6y77f7l2wh] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
}

.goal-detail__plan-transport-group[b-6y77f7l2wh] {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    padding: 0.5rem 0.9rem;
    margin-left: 0.6rem;
    border-left: 3px solid var(--sail-caution);
}

/* One (From, To) route-group (ENG-staged-plan-route-grouping) — the one physical trip the owner actually
   makes; its heading names the route once, its materials list underneath instead of repeating the route
   on every line (the flat, illegible layout this replaced). */
.goal-detail__plan-route-group[b-6y77f7l2wh] {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}

.goal-detail__plan-route-heading[b-6y77f7l2wh] {
    margin: 0;
    display: flex;
    align-items: center;
    gap: 0.4rem;
    color: var(--sail-caution);
    font-size: 0.85rem;
    font-weight: 600;
}

.goal-detail__plan-route-material-list[b-6y77f7l2wh] {
    margin: 0 0 0 1.3rem;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
}

.goal-detail__plan-route-material-list > li[b-6y77f7l2wh] {
    color: var(--sail-text);
    font-size: 0.85rem;
}

.goal-detail__plan-transport-icon[b-6y77f7l2wh] {
    font-size: 0.9rem;
}

/* ENG-transport-volume-display: the required-m³ figure trails the quantity, muted like the acquisition
   box's own Hub hint -- a secondary logistics detail, never competing visually with the material name. */
.goal-detail__plan-transport-volume[b-6y77f7l2wh] {
    color: var(--sail-text-muted);
    margin-left: 0.3rem;
}

/* --- must acquire (ENG-staged-plan-route-grouping): hoisted above the production plan, its own box ---- */

.goal-detail__acquisitions-box[b-6y77f7l2wh] {
    border: 1px solid var(--sail-caution);
    background: rgba(232, 179, 57, 0.08);
}

.goal-detail__plan-acquisition-list[b-6y77f7l2wh] {
    margin: 0.3rem 0 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}

.goal-detail__plan-acquisition-list > li[b-6y77f7l2wh] {
    color: var(--sail-text);
    font-size: 0.9rem;
}

.goal-detail__plan-acquisition-hub[b-6y77f7l2wh] {
    color: var(--sail-text-muted);
}

/* --- covered from your stock (BUILD -- surface netted Buildable stock that has no transport plan,
   reports/ENG-covered-from-stock-section-summary.md): the acquisitions box's mirror image -- neutral
   accent, not the caution amber above, since owning the stock is the opposite of a blocking problem. --- */

.goal-detail__coverage-box[b-6y77f7l2wh] {
    border: 1px solid var(--sail-accent);
    background: rgba(79, 179, 255, 0.06);
}

.goal-detail__coverage-note[b-6y77f7l2wh] {
    margin: 0.2rem 0 0.4rem;
    color: var(--sail-text-muted);
    font-size: 0.85rem;
}

.goal-detail__coverage-hubs[b-6y77f7l2wh] {
    color: var(--sail-text-muted);
}

/* --- production jobs (Ravworks job-plan epic, Story 8 + 7b) ------------------------------------- */

.goal-detail__threshold-control[b-6y77f7l2wh] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.goal-detail__threshold-label[b-6y77f7l2wh] {
    font-size: 0.85rem;
    color: var(--sail-text-muted);
}

.goal-detail__threshold-input[b-6y77f7l2wh] {
    width: 4.5rem;
    padding: 0.3rem 0.5rem;
    border-radius: 0.4rem;
    border: 1px solid var(--sail-border);
    background: transparent;
    color: var(--sail-text);
}

/* BUILD -- widen the goal page layout + tighten the Blueprint column
   (reports/ENG-goal-page-width-and-blueprint-column-summary.md): the reaction maximum's own grey-out
   while optimize is on -- mirrors .goal-detail__threshold-save:disabled's own opacity treatment exactly,
   so a disabled input and a disabled button read as the same "not applicable right now" state. */
.goal-detail__threshold-input:disabled[b-6y77f7l2wh] {
    opacity: 0.5;
    cursor: default;
}

.goal-detail__threshold-unit[b-6y77f7l2wh] {
    font-size: 0.85rem;
    color: var(--sail-text-muted);
}

.goal-detail__threshold-save[b-6y77f7l2wh] {
    padding: 0.3rem 0.8rem;
    border-radius: 0.5rem;
    border: 1px solid var(--sail-accent);
    background: transparent;
    color: var(--sail-accent);
    cursor: pointer;
}

.goal-detail__threshold-save:disabled[b-6y77f7l2wh] {
    opacity: 0.5;
    cursor: default;
}

.goal-detail__threshold-busy[b-6y77f7l2wh] {
    font-size: 0.8rem;
    color: var(--sail-text-muted);
}

/* BUILD -- widen the goal page layout + tighten the Blueprint column: the reaction maximum's own
   "why is this greyed out" hint, shown only while optimize is on -- same restrained treatment as the
   busy indicator right above (a small muted note, never a caution/warning tone; this isn't a problem,
   just a fact about which control currently applies). */
.goal-detail__threshold-hint[b-6y77f7l2wh] {
    font-size: 0.8rem;
    color: var(--sail-text-muted);
    font-style: italic;
}

/* Reaction slot-optimize mode (Part B, reports/ENG-reaction-slot-optimize-and-info-note-summary.md) --
   a checkbox control, distinct enough from the numeric siblings' own input+Save pairing that it needs
   its own label layout rather than reusing .goal-detail__threshold-label/-input. */
.goal-detail__threshold-checkbox-label[b-6y77f7l2wh] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.85rem;
    color: var(--sail-text-muted);
    cursor: pointer;
}

.goal-detail__threshold-error[b-6y77f7l2wh] {
    margin: 0;
    font-size: 0.85rem;
    color: var(--sail-critical);
}

/* BUILD 2/4 (backlog #9): read-only replacement for the workspace-wide controls that moved to
   Settings -- mirrors .goal-detail__threshold-error's own muted/critical split, but as plain text
   rather than an input row. */
.goal-detail__settings-summary[b-6y77f7l2wh] {
    margin: 0.3rem 0;
    font-size: 0.85rem;
    color: var(--sail-text-muted);
}

.goal-detail__settings-summary-label[b-6y77f7l2wh] {
    color: var(--sail-text);
    font-weight: 600;
    margin-right: 0.3rem;
}

.goal-detail__settings-summary-link[b-6y77f7l2wh] {
    margin-left: 0.4rem;
    color: var(--sail-accent);
}

.goal-detail__jobs-empty[b-6y77f7l2wh] {
    margin: 0;
    color: var(--sail-text-muted);
}

.goal-detail__job-group[b-6y77f7l2wh] {
    margin-bottom: 1rem;
}

.goal-detail__job-group:last-child[b-6y77f7l2wh] {
    margin-bottom: 0;
}

/* Job-table UI polish: the collapsible section header -- mirrors Hubs.razor's own
   .hub-section__header button + chevron-span pattern (this component's own CSS isolation means those
   classes don't apply here, so the same shapes/tokens are repeated under this component's own names). */
.goal-detail__job-group-header[b-6y77f7l2wh] {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    width: 100%;
    padding: 0.4rem 0;
    background: transparent;
    border: none;
    cursor: pointer;
    text-align: left;
}

.goal-detail__job-group-header:hover .goal-detail__job-group-title[b-6y77f7l2wh] {
    color: var(--sail-accent);
}

.goal-detail__job-group-chevron[b-6y77f7l2wh] {
    color: var(--sail-text-muted);
    font-size: 0.85rem;
    width: 1em;
    flex: none;
}

.goal-detail__job-group-heading[b-6y77f7l2wh] {
    display: flex;
    flex-direction: column;
}

.goal-detail__job-group-title[b-6y77f7l2wh] {
    margin: 0;
    font-size: 0.95rem;
    color: var(--sail-text);
}

.goal-detail__job-group-subheading[b-6y77f7l2wh] {
    margin: 0;
    font-size: 0.8rem;
    color: var(--sail-text-muted);
}

/* Hub-fee prominence: pushed to the header's right edge -- the same horizontal position as the
   Install fee column below it, so a reader's eye connects the job fees above with this subtotal. */
.goal-detail__job-group-fee-subtotal[b-6y77f7l2wh] {
    margin-left: auto;
    text-align: right;
    font-size: 0.8rem;
}

.goal-detail__fee-subtotal-label[b-6y77f7l2wh] {
    color: var(--sail-text-muted);
}

/* Emphasized -- the real --sail-accent token (Steel-Blue, already ratified for "informational"
   prominence elsewhere, ResolveGlowClass), never an invented color. */
.goal-detail__fee-subtotal-amount[b-6y77f7l2wh] {
    color: var(--sail-accent);
    font-weight: 600;
    margin-left: 0.3rem;
}

.goal-detail__fee-unknown-hint[b-6y77f7l2wh] {
    color: var(--sail-text-muted);
    margin-left: 0.3rem;
}

/* Layer 3, Job Installation Fee cost UI: the Goal-wide total, above the threshold control -- the single
   most prominent fee figure on the page (the bottom line), right-aligned and the largest of the three
   fee-figure sizes (per-job < Hub subtotal < Goal total). */
.goal-detail__fee-total[b-6y77f7l2wh] {
    margin: 0 0 0.75rem;
    font-size: 0.95rem;
    text-align: right;
}

.goal-detail__fee-total-label[b-6y77f7l2wh] {
    color: var(--sail-text-muted);
}

.goal-detail__fee-total-amount[b-6y77f7l2wh] {
    color: var(--sail-accent);
    font-weight: 700;
    font-size: 1.1rem;
    margin-left: 0.3rem;
}

/* Job-table UI polish: the optional "collapse all / expand all" toggle, only rendered when there is
   more than one Hub section. Plain text buttons, matching the threshold control's own restrained style
   rather than introducing a new button treatment. */
.goal-detail__job-collapse-all[b-6y77f7l2wh] {
    display: flex;
    gap: 0.75rem;
    margin-bottom: 0.5rem;
}

.goal-detail__job-collapse-all-button[b-6y77f7l2wh] {
    background: transparent;
    border: 1px solid var(--sail-border);
    border-radius: var(--sail-radius-control, 0.5rem);
    color: var(--sail-text-muted);
    font-size: 0.8rem;
    padding: 0.2rem 0.6rem;
    cursor: pointer;
}

.goal-detail__job-collapse-all-button:hover[b-6y77f7l2wh] {
    color: var(--sail-text);
    border-color: var(--sail-text-muted);
}

/* BUILD -- align job table columns across all hub sections
   (reports/ENG-job-table-column-alignment-summary.md): table-layout: fixed makes column widths come
   ENTIRELY from the <colgroup>/<col> widths below (goal-detail__job-col--*), never from a row's own
   content -- the fix for "every section auto-sizes its own columns, so the page looks crooked while
   scrolling." width is deliberately NOT 100% (was, before this ticket) -- under table-layout: fixed, a
   table wider than the sum of its own declared column widths gets that extra space redistributed across
   columns in a way that differs by browser, which would silently reintroduce the very misalignment this
   ticket removes. Left at its own natural width (the sum of its <col> widths, ~80rem for the six-column
   manufacturing shape) instead -- deterministic and identical in every table instance, manufacturing or
   reaction, because both draw column widths from the exact same shared classes. */
.goal-detail__job-table[b-6y77f7l2wh] {
    table-layout: fixed;
    border-collapse: collapse;
    font-size: 0.85rem;
}

.goal-detail__job-table th[b-6y77f7l2wh] {
    text-align: left;
    color: var(--sail-text-muted);
    font-weight: 500;
    padding: 0.25rem 0.5rem;
    border-bottom: 1px solid var(--sail-border);
}

.goal-detail__job-table td[b-6y77f7l2wh] {
    padding: 0.25rem 0.5rem;
    color: var(--sail-text);
    border-bottom: 1px solid var(--sail-border);
    vertical-align: top;
}

/* The shared column-width budget (starting point per the ticket, tuned against the page's own new
   90rem width, reports/ENG-goal-page-width-and-blueprint-column-summary.md): manufacturing tables
   declare all six; reaction group tables (no Blueprint column) declare only the first five, so their own
   five SHARED columns (Product, Runs, Job, Per job, Install fee) still land at identical x-positions in
   both table shapes -- the reaction table's own <table> is simply narrower overall and ends early, the
   ticket's own stated acceptable alternative to leaving a visibly empty trailing column. Sums to 80rem for
   the full six-column shape. */
.goal-detail__job-col--product[b-6y77f7l2wh] {
    width: 24rem;
}

.goal-detail__job-col--runs[b-6y77f7l2wh] {
    width: 6.5rem;
}

.goal-detail__job-col--job[b-6y77f7l2wh] {
    width: 11rem;
}

.goal-detail__job-col--per-job[b-6y77f7l2wh] {
    width: 8rem;
}

.goal-detail__job-col--fee[b-6y77f7l2wh] {
    width: 9.5rem;
}

.goal-detail__job-col--blueprint[b-6y77f7l2wh] {
    width: 21rem;
}

/* Long product names (the longest real one on record: "Gravimetric-FTL Interlink Communicator") must wrap
   onto a second line under the fixed 24rem Product column rather than overflowing it or forcing the
   column wider -- min-width: 0 is the actual fix (a flex item's default min-width: auto would otherwise
   refuse to shrink below its own content's natural width inside the fixed-width cell, overflowing instead
   of wrapping); overflow-wrap: break-word is a defensive backstop for a single unbroken long word. */
.goal-detail__job-product[b-6y77f7l2wh] {
    overflow-wrap: break-word;
}

.goal-detail__job-product .goal-detail__icon-row[b-6y77f7l2wh] {
    min-width: 0;
}

/* Story 8 refinement: one badge per distinct split size ("4 × 214"), not one badge per whole job. */
.goal-detail__job-split-badge[b-6y77f7l2wh] {
    display: inline-block;
    padding: 0.1rem 0.5rem;
    border-radius: var(--sail-radius-pill, 999px);
    font-size: 0.8rem;
}

/* A job that actually split (2+ distinct sizes) -- the same caution/warning tone the acquisitions box
   already uses, reserved for a real split, never a plain single-job row. */
.goal-detail__job-split-badge--warning[b-6y77f7l2wh] {
    border: 1px solid var(--sail-caution);
    color: var(--sail-caution);
    background: rgba(232, 179, 57, 0.08);
}

/* A non-split job ("1 × R") -- still a badge, but de-emphasized/neutral, never the warning tone. */
.goal-detail__job-split-badge--muted[b-6y77f7l2wh] {
    border: 1px solid var(--sail-border);
    color: var(--sail-text-muted);
}

/* Layer 3, Job Installation Fee cost UI: the per-job fee cell, right-aligned like any other ISK figure. */
.goal-detail__job-fee[b-6y77f7l2wh] {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* An unknown fee ("—") -- the honest "not yet computable" state, never a fabricated value. */
.goal-detail__job-fee--unknown[b-6y77f7l2wh] {
    color: var(--sail-text-muted);
}

/* BUILD -- widen the goal page layout + tighten the Blueprint column
   (reports/ENG-goal-page-width-and-blueprint-column-summary.md): the verdict text and its override
   dropdown previously had no layout rule at all here, so the two sat on the same inline flow inside the
   table cell and collided/wrapped mid-word as soon as the verdict text got long. Stacked instead --
   verdict text on its own line, the dropdown directly beneath it -- so the shortened text this ticket
   also ships (no inline BPC breakdown, no repeated auto-strategy text, shorter dropdown labels) has a
   full line to itself and fits without wrapping in the common case. */
.goal-detail__job-blueprint[b-6y77f7l2wh] {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.3rem;
}

.goal-detail__job-blueprint-override[b-6y77f7l2wh] {
    background: transparent;
    color: var(--sail-text);
    border: 1px solid var(--sail-border);
    border-radius: 0.4rem;
    padding: 0.15rem 0.4rem;
    font-size: 0.8rem;
}

/* --- reaction slot scheduler (step 3) view -- strict-serial grouped table
   (reports/ENG-reaction-schedule-serial-grouped-view-summary.md), replacing the earlier per-slot
   timeline the owner found unreadable. Nested inside its own Hub section (reaction block hub
   placement, reports/ENG-reaction-block-hub-placement-collapsible-slots-summary.md) -- the
   --nested modifier drops the outer accent border/margin the standalone fallback still uses, since
   the Hub section's own .goal-detail__job-group already provides that visual boundary. ------------ */

.goal-detail__reaction-schedule[b-6y77f7l2wh] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    margin-bottom: 1rem;
    padding: 0.9rem 1rem;
    border-radius: var(--sail-radius-control, 0.625rem);
    border: 1px solid var(--sail-accent);
}

.goal-detail__reaction-schedule--nested[b-6y77f7l2wh] {
    margin-bottom: 0;
    padding: 0;
    border: none;
}

.goal-detail__reaction-schedule-makespan[b-6y77f7l2wh] {
    margin: 0;
    font-size: 0.95rem;
}

.goal-detail__reaction-schedule-makespan-label[b-6y77f7l2wh] {
    color: var(--sail-text-muted);
}

.goal-detail__reaction-schedule-makespan-amount[b-6y77f7l2wh] {
    color: var(--sail-accent);
    font-weight: 700;
    font-size: 1.1rem;
    margin-left: 0.3rem;
}

.goal-detail__reaction-schedule-order[b-6y77f7l2wh] {
    color: var(--sail-text-muted);
    font-size: 0.8rem;
    margin-left: 0.5rem;
}

.goal-detail__reaction-group[b-6y77f7l2wh] {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    padding-top: 0.5rem;
    border-top: 1px solid var(--sail-border);
}

.goal-detail__reaction-group:first-of-type[b-6y77f7l2wh] {
    padding-top: 0;
    border-top: none;
}

/* Fix 2: collapsible, mirrors .goal-detail__job-group-header's own button+chevron pattern exactly. */
.goal-detail__reaction-group-header[b-6y77f7l2wh] {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    width: 100%;
    padding: 0.3rem 0;
    background: transparent;
    border: none;
    cursor: pointer;
    text-align: left;
}

.goal-detail__reaction-group-header:hover .goal-detail__reaction-group-title[b-6y77f7l2wh] {
    color: var(--sail-accent);
}

.goal-detail__reaction-group-chevron[b-6y77f7l2wh] {
    color: var(--sail-text-muted);
    font-size: 0.8rem;
    width: 1em;
    flex: none;
}

.goal-detail__reaction-group-title[b-6y77f7l2wh] {
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--sail-text);
}

.goal-detail__reaction-group-makespan[b-6y77f7l2wh] {
    font-size: 0.8rem;
    color: var(--sail-text-muted);
    font-variant-numeric: tabular-nums;
}

/* Fix 3: real headroom surfaced honestly, pushed to the header's right edge like the Hub section's
   own fee subtotal. */
.goal-detail__reaction-group-slots[b-6y77f7l2wh] {
    margin-left: auto;
    font-size: 0.75rem;
    color: var(--sail-text-muted);
    font-variant-numeric: tabular-nums;
}

/* Part A: the serial-simplification info note (reports/ENG-reaction-slot-optimize-and-info-note-summary.md)
   -- the left-accent-border idiom this codebase already uses for informational (never error/warning)
   prominence elsewhere (OperationalWorkspace's own .ows-header, Bridge's own .bridge-card--direction). */
/* BUILD -- widen the goal page layout: this box is nested inside the now-wide "Production jobs" section,
   so it needs its OWN cap -- the same 60rem/flex-start treatment .goal-detail__section--prose uses above,
   for the identical reason (this box carries the serial-simplification note and the formula-shortfall
   hint, both genuine prose, never a table). */
.goal-detail__reaction-info-note[b-6y77f7l2wh] {
    width: 100%;
    max-width: 60rem;
    align-self: flex-start;
    padding: 0.6rem 0.8rem;
    border-radius: var(--sail-radius-control, 0.5rem);
    border-left: 3px solid var(--sail-accent);
    background: rgba(79, 179, 255, 0.06);
}

.goal-detail__reaction-info-note-text[b-6y77f7l2wh] {
    margin: 0;
    font-size: 0.8rem;
    color: var(--sail-text-muted);
    line-height: 1.45;
}

/* --- execution hand-off ------------------------------------------------------------------------- */


/* BI-038 built count — the header chip beside the status badge and the estimated-value marker.
   Muted like .goal-detail__value: it qualifies the badge rather than competing with it. */
.goal-detail__built[b-6y77f7l2wh] {
    font-size: 0.9rem;
    color: var(--sail-text-muted);
}
/* /Components/Pages/Goals.razor.rz.scp.css */
/* IMP-090: the Goal Management Supporting Surface. Restrained, reusing the existing design tokens and
   glass system (app.css) and the shared cc-header/cc-banner/cc-loading/cc-link/cc-refresh vocabulary
   already established by Bridge.razor/Home.razor — no new branding, no typography changes. */

.goals-page[b-6t3fi6oe3t] {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    max-width: 60rem;
    margin: 0 auto;
}

/* --- create form --------------------------------------------------------------------------------- */

.goals-create[b-6t3fi6oe3t] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding: var(--sail-space-5, 1.5rem);
    border-radius: var(--sail-radius-panel, 1.25rem);
}

.goals-create__title[b-6t3fi6oe3t] {
    margin: 0;
    font-size: 1.05rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--sail-text);
}

.goals-create__field[b-6t3fi6oe3t] {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.goals-create__field label[b-6t3fi6oe3t] {
    font-size: 0.85rem;
    color: var(--sail-text-muted);
}

.goals-create__input[b-6t3fi6oe3t] {
    padding: 0.5rem 0.75rem;
    border-radius: var(--sail-radius-control, 0.625rem);
    border: 1px solid var(--sail-border);
    background: var(--sail-bg-elevated);
    color: var(--sail-text);
    font-size: 1rem;
}

.goals-create__actions[b-6t3fi6oe3t] {
    display: flex;
    justify-content: flex-end;
}

/* --- priority-order edit mode (BUILD -- user-controlled goal priority order) ----------------------- */

.goals-reorder[b-6t3fi6oe3t] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding: var(--sail-space-5, 1.5rem);
    border-radius: var(--sail-radius-panel, 1.25rem);
}

.goals-reorder__title[b-6t3fi6oe3t] {
    margin: 0;
    font-size: 1.05rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--sail-text);
}

.goals-reorder__hint[b-6t3fi6oe3t] {
    margin: 0;
    color: var(--sail-text-muted);
    font-size: 0.9rem;
}

.goals-reorder__list[b-6t3fi6oe3t] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.goals-reorder__row[b-6t3fi6oe3t] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.6rem 0.9rem;
    border-radius: var(--sail-radius-control, 0.625rem);
    border: 1px solid var(--sail-border);
    background: var(--sail-bg-elevated);
}

.goals-reorder__name[b-6t3fi6oe3t] {
    color: var(--sail-text);
}

.goals-reorder__buttons[b-6t3fi6oe3t] {
    display: flex;
    gap: 0.4rem;
    flex-shrink: 0;
}

.goals-reorder__actions[b-6t3fi6oe3t] {
    display: flex;
    justify-content: flex-end;
    gap: 0.6rem;
}

/* --- empty state ---------------------------------------------------------------------------------- */

.goals-empty[b-6t3fi6oe3t] {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.75rem;
    padding: var(--sail-space-5, 1.5rem);
    border-radius: var(--sail-radius-panel, 1.25rem);
}

.goals-empty__headline[b-6t3fi6oe3t] {
    margin: 0;
    font-size: 1.1rem;
    color: var(--sail-text);
}

.goals-empty__body[b-6t3fi6oe3t] {
    margin: 0;
    color: var(--sail-text-muted);
}

/* --- goal list/cards ------------------------------------------------------------------------------ */

.goals-list[b-6t3fi6oe3t] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
}

/* ENG-goals-landing-page: the card is now a two-column row — item artwork beside the text — matching the
   Command Center work-package card's own media/body split for the very same Goals. align-items: flex-start
   keeps the art at the top of a card whose text wraps to several lines rather than centring it against a
   ragged block. */
.goal-card[b-6t3fi6oe3t] {
    display: flex;
    flex-direction: row;
    align-items: flex-start;
    gap: 1rem;
    padding: 1.1rem 1.25rem;
    border-radius: var(--sail-radius-panel, 1.25rem);
}

.goal-card__media[b-6t3fi6oe3t] {
    flex: 0 0 auto;
    display: flex;
}

/* min-width: 0 — a flex item's automatic minimum size is its content, so without this a long Goal name or
   explanation pushes the card wider instead of wrapping, and the badge leaves the card. */
.goal-card__body[b-6t3fi6oe3t] {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.goal-card__head[b-6t3fi6oe3t] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
}

.goal-card__title[b-6t3fi6oe3t] {
    margin: 0;
    font-size: 1.05rem;
    color: var(--sail-text);
}

.goal-card__link[b-6t3fi6oe3t] {
    color: inherit;
    text-decoration: none;
}

.goal-card__link:hover[b-6t3fi6oe3t],
.goal-card__link:focus-visible[b-6t3fi6oe3t] {
    color: var(--sail-accent);
    text-decoration: underline;
}

.goal-card__badge[b-6t3fi6oe3t] {
    flex-shrink: 0;
    padding: 0.2rem 0.6rem;
    border-radius: var(--sail-radius-pill, 999px);
    font-size: 0.8rem;
    letter-spacing: 0.02em;
    color: var(--sail-text-muted);
    border: 1px solid var(--sail-border);
}

.goal-card__explanation[b-6t3fi6oe3t] {
    margin: 0;
    color: var(--sail-text-muted);
}

.goal-card__hub[b-6t3fi6oe3t] {
    margin: 0;
    font-size: 0.9rem;
    color: var(--sail-text-muted);
}

.goal-card__actions[b-6t3fi6oe3t] {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-top: 0.35rem;
}


.goal-card__confirm-text[b-6t3fi6oe3t] {
    margin: 0;
    color: var(--sail-text);
    font-size: 0.9rem;
}


/* BI-038 built count — sits beside the badge in the card head, not in the body, so it does not
   compete with the explanation line. Muted and shrink-proof, matching .goal-card__badge. */
.goal-card__built[b-6t3fi6oe3t] {
    flex-shrink: 0;
    font-size: 0.8rem;
    color: var(--sail-text-muted);
}
/* /Components/Pages/Home.razor.rz.scp.css */
.cc[b-dctez9r8y6] {
    max-width: 1400px;
    margin: 0 auto;
    /* ENG-command-center-monospace-removal: the page-wide `font-family: ui-monospace, "Cascadia Code",
       "Segoe UI", sans-serif` that used to sit here is deliberately gone. It was legacy, not intent — it
       carried no comment in a heavily-commented file, predates the overhaul (8db57ec), and the ratified
       UX-005 §1 names exactly two typographic roles with no monospace among them. The Command Center now
       inherits Poppins/Work Sans from the app tokens like every other page.

       This line replaces the one thing that removal would otherwise have taken away silently. The
       monospace was giving every figure on this page fixed-width digits *incidentally*, whether or not it
       asked for them — and this page declares font-variant-numeric nowhere. Without this, counts that
       change on refresh (the Active Industry stat grid, the PI running/reset counts and cycle-end times,
       the Operations lines) would reflow by a fraction of a character each time.

       Declared on the page root rather than on each figure, because that is exactly the scope the
       monospace had: it is the same property-for-property replacement, it reaches the Operations modal
       (which nests inside .cc), and a figure added later is covered without anyone remembering to. The
       tree's own .pt-col already declares this independently and is unaffected either way. */
    font-variant-numeric: tabular-nums;
    font-size: 0.875rem;
    /* IMP-101 §5: one unified band-to-band vertical rhythm — every top-level Command Center band
       (header, NEXT, Operational Summary, Execution Plan, Supporting Information) now shares this same
       gap instead of five slightly different margin-bottom values (1.25rem/1.5rem/1.5rem/1.25rem/
       1.375rem), so the page reads as one calm composition rather than independently-spaced boxes. */
    --cc-band-gap: 2rem;
    /* ENG-CC-002: the supporting column's fixed track width. ~256px — a touch above the draft's ~240px
       so the compact count text ("No Policies declared yet.") reads on one line; the Work Queue takes the
       remaining space via minmax(0, 1fr).
       ENG-command-center-layout-rebuild: widened 16rem -> 15.625rem is a no-op; the real change is that
       this column is now sticky and holds four tiles rather than eight (see .cc-supporting). */
    --cc-supporting-width: 15.625rem;

    /* ENG-command-center-layout-rebuild: per-tile IDENTITY colours for the Phosphor duotone icons.
       ============================ THESE ARE NOT STATUS COLOURS ============================
       Orange on the Goals tile means "this is the Goals tile". It does NOT mean Goals are in trouble,
       and the green on PI does NOT mean PI is healthy. Sail's semantic palette
       (--sail-positive/caution/critical/accent) is deliberately NOT reused here for exactly that
       reason: a tile whose identity colour happened to be --sail-critical would read as an alert.
       Status on these tiles is carried where it always was — in the text lines, and in each card's own
       existing status glow class. If you ever need an icon to signal state, it needs its own mechanism
       and its own ticket; do not repurpose these.
       ====================================================================================== */
    --cc-tile-goals: #e8a13a;
    --cc-tile-policies: #7c8cf8;
    --cc-tile-operations: #56c7d6;
    --cc-tile-pi: #5cc98c;
    --cc-tile-transport: #c79be8;
    --cc-tile-hubs: #f08a6c;
    --cc-tile-inventory: #9aa7b8;
    --cc-tile-characters: #8fb3d9;

    /* ENG-disc-right-and-queue-box REMOVED --cc-column-head-height (3.25rem).
       ENG-column-alignment-fix introduced it to reserve one shared height across both columns' heading
       blocks, so their content started on the same line: the left had a two-line heading, the right a
       one-line label.

       Giving the Work Queue its own glass box retired the problem rather than solving it again. The
       heading and its subtitle now sit INSIDE that box, the way each tile carries its own label, so the
       two columns no longer begin with comparable bare headings that need equalising — they begin with
       two boxes, and those already start on the same line because both are the first item in their own
       grid track, and that track keeps its start alignment. The reservation had nothing left to reserve,
       and a magic number that no longer earns its place is worse than none. */
}

/* ENG-CC-002: the two-column Command Center body — Work Queue (primary) left, supporting band right.
   minmax(0, 1fr) on the primary track is what stops the Work Queue's own content from ever forcing
   horizontal overflow; align-items: start top-aligns the supporting column with the Work Queue. The
   header, banners, and change-summary render above this grid, full-width. */
.cc-main[b-dctez9r8y6] {
    display: grid;
    grid-template-columns: minmax(0, 1fr) var(--cc-supporting-width);
    gap: var(--cc-band-gap);
    align-items: start;
}

/* ENG-column-alignment-fix: the Work Queue's container stretches to the taller of the two columns, so
   there is no empty band between the last work package and the wide tiles below.

   The minimum is expressed as the GRID ROW ITSELF, not as a number. `.cc-main` keeps `align-items: start`
   (the sticky column must stay content-height, or it would fill the row and have nothing to stick
   within), and only this track opts into `stretch`. A grid row is as tall as its tallest item, so:

     few Goals   -> the supporting column sets the row height; this container stretches up to meet it and
                    both columns end together.
     many Goals  -> this container sets the row height and simply grows; the supporting column stays
                    content-height and keeps sticking.

   Neither column needs to know the other's height, and no value is duplicated between them. It also
   degrades by itself: below 900px .cc-main becomes one column, each item is its own row, and
   `align-self: stretch` resolves to that item's own content height — never a tall empty box.

   Deliberately NOT a fixed height with internal scrolling: work packages must never be hidden behind a
   scrollbar inside the queue. */
.cc-primary[b-dctez9r8y6] {
    min-width: 0;
    align-self: stretch;
    display: flex;
    flex-direction: column;
}

    /* Fills whatever height the stretch above resolved to. */
    .cc-primary > .cc-work-queue[b-dctez9r8y6] {
        flex: 1 1 auto;

        /* ENG-button-unification-and-column-alignment: this is why the two columns' BOTTOMS still sat
           ~35px apart after the stretch landed. The Work Queue section also carries `.cc-section`, whose
           `margin-bottom: var(--cc-band-gap)` (2rem/32px) is meant to separate top-level bands from one
           another. Inside this column it separates the box from nothing — the box IS the column's only
           child — and the margin sat between the box's visible edge and the bottom of the stretched
           track, so the box stopped 32px short of the supporting column beside it.

           Zeroed structurally rather than compensated: the band gap below .cc-main is already owned by
           .cc-wide's own margin-top, so this margin was double-counting a separation that something else
           already provides. No value is introduced, and nothing needs to stay in sync. */
        margin-bottom: 0;
    }

/* ENG-command-center-layout-rebuild: the overview column stays in view while the Work Queue scrolls.
   That is the whole point of the change — with several Goals the overview used to scroll away exactly
   when you wanted to check the queue against it.

   ============================ FOUR TILES IS THE LIMIT ============================
   This column holds Goals, Policies, Operations and PI, and four is what fits a normal viewport.
   A FIFTH TILE WOULD BREAK THIS RULE, not merely crowd it: once the column is taller than the
   viewport, `position: sticky` pins the top and strands the bottom tile permanently off-screen, and
   nothing warns you — it simply stops working for whoever added it.

   If a fifth overview is needed, it goes in the .cc-wide band below (as Transport, Hubs and Inventory
   already do) or something moves out of here. Do not just add one.
   ================================================================================= */
.cc-supporting[b-dctez9r8y6] {
    min-width: 0;
    position: sticky;
    /* Clears the floating Sidebar's own inset so the pinned column never touches the viewport edge. */
    top: var(--sail-shell-float-inset, 1rem);
}

/* ---------------------------------------------------------------------------------------------
   IMP-092/UX-005 §3.9: the global "Analyzing Workspace…" overlay. A restrained dark/glass treatment,
   never a generic spinner/progress bar — the Sail brand mark and the one semantic statement are the
   whole visual. The existing Command Center stays dimly visible behind it (a translucent, blurred
   backdrop, never fully opaque), and the overlay's own fixed/full-viewport/high-z-index footprint is
   what blocks background pointer interaction (the same technique as .cc-modal-backdrop).
   --------------------------------------------------------------------------------------------- */

.cc-analysis-overlay[b-dctez9r8y6] {
    position: fixed;
    inset: 0;
    z-index: var(--sail-z-overlay);
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(4, 10, 18, 0.72);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
}

    .cc-analysis-overlay:focus[b-dctez9r8y6] {
        /* Programmatically focused (Home.razor.js's own focusElement, IMP-090 precedent) so keyboard
           focus never lingers on a now-blocked background control — no visible outline needed since
           this is not itself an interactive control. */
        outline: none;
    }

.cc-analysis-overlay__content[b-dctez9r8y6] {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
    padding: 2rem 2.75rem;
    border-radius: var(--sail-radius-panel);
    background: var(--sail-glass-bg-strong);
    border: 1px solid var(--sail-glass-border-strong);
    box-shadow: var(--sail-shadow-lg);
    overflow: hidden;
}

/* ENG-technical-font-class-split: the font now arrives via the global .sail-font-technical class on the
   element, instead of this rule re-declaring the token to escape the old class's bundled uppercasing —
   this is a sentence ("Analyzing Workspace…"), never a label. The .04em tracking below is kept as this
   statement's own. */
.cc-analysis-overlay__statement[b-dctez9r8y6] {
    margin: 0;
    font-size: var(--sail-text-lg);
    letter-spacing: 0.04em;
    color: var(--sail-text);
}

/* Restrained ambient scan/light pass (UX-005: "subtle scan/light pass ... controlled opacity
   movement") — never a spinner, never a progress bar, never high-frequency flicker. Collapsed to an
   imperceptibly-fast static frame by the existing global prefers-reduced-motion rule in app.css (which
   already zeroes every animation-duration on the page) — no separate reduced-motion override needed. */
.cc-analysis-overlay__content[b-dctez9r8y6]::before {
    content: "";
    position: absolute;
    inset: -60% -120%;
    background: linear-gradient(100deg, transparent 42%, rgba(79, 179, 255, 0.14) 50%, transparent 58%);
    animation: cc-analysis-scan-b-dctez9r8y6 3.6s linear infinite;
    pointer-events: none;
}

@keyframes cc-analysis-scan-b-dctez9r8y6 {
    from { transform: translateX(-30%); }
    to { transform: translateX(30%); }
}

/* IMP-088/UX-005 §3.1: contextual header — uses the IMP-086 glass panel treatment instead of a plain
   bottom border, since this is now the page's own first decision-relevant surface, not a bare title bar.

   ENG-goals-landing-page: every other declaration this rule used to carry — the flex construction, the
   h1 treatment, .cc-header__identity/__workspace/__statement/__actions and .cc-freshness — now lives in
   wwwroot/app.css, promoted VERBATIM for the same reason .cc-link/.cc-refresh were (see the note left
   below, and app.css's own). Goals/Policies/Hubs already wrote this exact markup and received none of
   it, because a .razor.css cannot be shared.

   What stays here is one declaration, and only because it is genuinely Command Center geometry rather
   than header identity: --cc-band-gap is this page's own band rhythm token and exists nowhere else. The
   rendered header is unchanged. */
.cc-header[b-dctez9r8y6] {
    margin-bottom: var(--cc-band-gap);
}

/* ENG-button-styling: .cc-link and .cc-refresh were defined here, but Goals/Hubs/Policies/Login/
   OperationalWorkspace all borrow them — and Blazor CSS isolation rewrites every rule in a .razor.css
   with this component's own [b-xxxxx] attribute, so those twenty-four borrowing sites silently rendered
   as browser-default buttons. They are the app's shared primary/quiet action vocabulary, not Command
   Center chrome, so they now live in wwwroot/app.css alongside sail-glass/sail-interactive — the one
   sheet that genuinely is global (the trap GoalDetail.razor.css already documents at its own head).
   Home's own two usages (.cc-link on the Link EVE Character anchor, .cc-refresh on Refresh) resolve
   there unchanged. */

/* ---------------------------------------------------------------------------------------------
   IMP-088/UX-005 §3.3: equal-height Goals / Operations / PI overview row.
   IMP-101 §3/§6: "Operational Summary" — the three items no longer each carry their own sail-glass
   (moved onto this row instead, Home.razor); they now read as one shared "instrument band" (medium
   glass tier, between NEXT/Execution Plan's strong tier and Supporting Information's quiet tier)
   rather than three independently floating cards. Zero inter-item gap plus a subtle border-left
   divider (below) replaces the previous gap-separated equal-height grid — the items now sit flush
   against each other like adjoining gauges on one panel.
   --------------------------------------------------------------------------------------------- */

.cc-overview-row[b-dctez9r8y6] {
    display: grid;
    grid-template-columns: 1fr;
    /* ENG-supporting-detail-cards: the five sections are five independent cards now, so this is a plain
       stack and separation is the gap alone — the shared glass that used to frame them moved onto each
       card, and the hairline dividers that used to sit between them are gone (saying it twice). The gap
       matches .cc-work-queue__list's own card-stack rhythm, so both columns space their cards alike.
       The former 0.25rem padding went with the shared panel: it existed to inset the tiles from that
       panel's own edge, and there is no longer a panel edge to inset from. */
    gap: 0.75rem;
}

/* ENG-supporting-detail-cards: each section is its own surface now. The background, border, radius,
   blur and elevation all come from the shared .sail-glass class carried in the markup — the same
   treatment the Work Queue's own cards and every other panel in the app already use, deliberately
   reused rather than reinvented here. This rule keeps only the card's internal layout.

   The border-top that used to live here (transparent by default, tinted for every card after the
   first) is gone with the shared panel that made it necessary: separation is the stack's gap now, and
   a hairline between two already-separated glass cards would state the same thing twice. */
/* ENG-column-alignment-fix: disc LEFT, text right — as drafted. It previously stacked the disc ABOVE the
   label, so every tile grew by the disc's height plus a gap while the space beside the label sat empty.
   Moving it recovers ~52px per tile, which is what closes the hole in .cc-primary below.

   A two-column grid rather than a flex row, because that needs no wrapper element around the text: real
   children all take column 2 (`> *` never matches a pseudo-element), and the disc/glyph pseudo-elements
   are placed explicitly in column 1, spanning every row so they centre against the whole text block. */
.cc-overview-card[b-dctez9r8y6] {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    padding: 1rem 1.25rem;
    transition: background-color var(--sail-transition-fast) var(--sail-ease);
}

/* ENG-disc-right-and-queue-box: the disc moved from the LEFT to the RIGHT. On the left it squeezed the
   text column, which truncated the PI tile's cycle-end line mid-phrase while the empty space sat on the
   right. Now the label, figure and caption start at the card's own left edge and the disc occupies a
   right-hand track beside them.

   The head is its own element so the disc centres against exactly the upper text block — `align-items:
   center` on this two-track grid — rather than against the whole card. Supporting lines and the action
   link are siblings of this block, not children, so they run the card's full width and pass under the
   disc. */
.cc-overview-card__head[b-dctez9r8y6] {
    display: grid;
    grid-template-columns: minmax(0, 1fr) var(--cc-tile-disc, 2.75rem);
    column-gap: 0.75rem;
    row-gap: 0.35rem;
    align-items: center;
}

    .cc-overview-card__head > *[b-dctez9r8y6] {
        grid-column: 1;
    }

    /* IMP-101 §7: interactive affordance stays a quiet hover/focus tint (typography/spacing over heavy
       outlines) rather than a further elevation step — the card's own glass already frames it. Never
       the only cue: :focus-visible's existing global outline (app.css) and each item's own status
       glow/cc-changed-overview-card box-shadow still apply independently of this. */
    .cc-overview-card--interactive:hover[b-dctez9r8y6],
    .cc-overview-card--interactive:focus-visible[b-dctez9r8y6] {
        background: rgba(255, 255, 255, 0.03);
    }

/* ENG-command-center-layout-rebuild: the full-width band beneath both columns — Transport, Hubs and
   Inventory. Three equal tracks at desktop; collapses with the rest of the composition below 900px. */
.cc-wide[b-dctez9r8y6] {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.75rem;
    margin-top: var(--cc-band-gap);
}

/* ENG-command-center-layout-rebuild: the tile icon.
   Rendered as a CSS mask over a flat background-color, NOT as an <img> and not as inline markup. Two
   reasons, both deliberate: the vendored Phosphor files declare fill="currentColor", which resolves to
   nothing inside an <img> (they would render black), and a mask keeps the SVG files byte-for-byte as
   vendored while the colour lives in CSS where the identity tokens are.

   Duotone survives the mask intact: the files are two paths, one at opacity 0.2, and a mask uses alpha —
   so the background shows through at full strength for the foreground path and at 20% for the backing
   one. One colour at two opacities, exactly as the weight intends, and the icon never introduces a
   second hue of its own. */
/* ENG-tile-presentation-fix: the icon sits in a COLOURED DISC, as drafted — it previously rendered as a
   bare glyph at label height, which made the duotone weight pointless (the 0.2-opacity backing path is
   invisible at ~18px, and the shape unreadable). That legibility is the whole reason Phosphor was chosen
   over hand-drawing.

   The disc is the identity marker: it carries the tile's colour as a ~12% tint with a ~35% border, and
   the glyph inside takes the same colour at the two duotone opacities via the mask. This does not weaken
   cc2f59b's identity-not-status rule — the disc is what marks identity, and it still encodes no state.

   Sized off two variables so the wide band and the narrower sticky column differ without duplicating the
   rule. A ::before on the CARD rather than on the title, so the disc is the card's own first block-level
   item above the title, not an oversized inline bullet inside a heading. */
#cc-overview-goals .cc-overview-card__head[b-dctez9r8y6]::before,
#cc-overview-policies .cc-overview-card__head[b-dctez9r8y6]::before,
#cc-overview-operations-button .cc-overview-card__head[b-dctez9r8y6]::before,
#cc-overview-pi .cc-overview-card__head[b-dctez9r8y6]::before,
#cc-overview-transport .cc-overview-card__head[b-dctez9r8y6]::before,
#cc-overview-hubs .cc-overview-card__head[b-dctez9r8y6]::before,
#cc-overview-inventory .cc-overview-card__head[b-dctez9r8y6]::before {
    content: "";
    /* Column 1, spanning every row, centred against the whole text block beside it. */
    grid-column: 2;
    grid-row: 1 / -1;
    align-self: center;
    width: var(--cc-tile-disc, 2.75rem);
    height: var(--cc-tile-disc, 2.75rem);
    border-radius: 50%;
    background-color: color-mix(in srgb, var(--cc-tile-icon) 12%, transparent);
    border: 1.5px solid color-mix(in srgb, var(--cc-tile-icon) 35%, transparent);
}

/* The glyph itself, as a second pseudo-element laid over the disc.
   Two elements rather than one because a mask clips its whole box: masking the glyph onto the disc
   element would clip away the tint and border along with it. So ::before is the disc, ::after is the
   masked glyph, positioned at the card's own padding origin and sized to the disc so the mask centres
   the icon inside it. The mask keeps the vendored SVGs byte-for-byte and keeps the duotone effect —
   the 0.2-opacity backing path shows at 20% of the same colour. */
#cc-overview-goals .cc-overview-card__head[b-dctez9r8y6]::after,
#cc-overview-policies .cc-overview-card__head[b-dctez9r8y6]::after,
#cc-overview-operations-button .cc-overview-card__head[b-dctez9r8y6]::after,
#cc-overview-pi .cc-overview-card__head[b-dctez9r8y6]::after,
#cc-overview-transport .cc-overview-card__head[b-dctez9r8y6]::after,
#cc-overview-hubs .cc-overview-card__head[b-dctez9r8y6]::after,
#cc-overview-inventory .cc-overview-card__head[b-dctez9r8y6]::after {
    content: "";
    /* The SAME cell as the disc. Two grid items may occupy one cell and simply overlap, and the later one
       paints on top — so the glyph lands dead-centre on the disc with no positioning arithmetic at all.
       This replaces the absolute top/left offsets that used to hard-code the card's own padding, which
       would have silently drifted the moment the disc moved. */
    grid-column: 2;
    grid-row: 1 / -1;
    align-self: center;
    width: var(--cc-tile-disc, 2.75rem);
    height: var(--cc-tile-disc, 2.75rem);
    pointer-events: none;
    background-color: var(--cc-tile-icon);
    -webkit-mask: var(--cc-tile-glyph) no-repeat center / var(--cc-tile-glyph-size, 1.375rem);
    mask: var(--cc-tile-glyph) no-repeat center / var(--cc-tile-glyph-size, 1.375rem);
}

/* The two bands' drafted sizes: 44px disc with a 22px icon in the wide band, 38px with 21px in the
   narrower sticky column. (The `position: relative` that used to sit here anchored the absolutely-
   positioned glyph; grid placement replaced that, so it is gone with it.) */
.cc-wide .cc-overview-card[b-dctez9r8y6] {
    --cc-tile-disc: 2.75rem;
    --cc-tile-glyph-size: 1.375rem;
}

.cc-supporting .cc-overview-card[b-dctez9r8y6] {
    --cc-tile-disc: 2.375rem;
    --cc-tile-glyph-size: 1.3125rem;
}

#cc-overview-goals[b-dctez9r8y6] { --cc-tile-icon: var(--cc-tile-goals); --cc-tile-glyph: url("/icons/phosphor/target-duotone.svg"); }
#cc-overview-policies[b-dctez9r8y6] { --cc-tile-icon: var(--cc-tile-policies); --cc-tile-glyph: url("/icons/phosphor/shield-duotone.svg"); }
#cc-overview-operations-button[b-dctez9r8y6] { --cc-tile-icon: var(--cc-tile-operations); --cc-tile-glyph: url("/icons/phosphor/gear-duotone.svg"); }
#cc-overview-pi[b-dctez9r8y6] { --cc-tile-icon: var(--cc-tile-pi); --cc-tile-glyph: url("/icons/phosphor/planet-duotone.svg"); }
#cc-overview-transport[b-dctez9r8y6] { --cc-tile-icon: var(--cc-tile-transport); --cc-tile-glyph: url("/icons/phosphor/truck-duotone.svg"); }
#cc-overview-hubs[b-dctez9r8y6] { --cc-tile-icon: var(--cc-tile-hubs); --cc-tile-glyph: url("/icons/phosphor/map-pin-duotone.svg"); }
#cc-overview-inventory[b-dctez9r8y6] { --cc-tile-icon: var(--cc-tile-inventory); --cc-tile-glyph: url("/icons/phosphor/package-duotone.svg"); }

.cc-overview-card__title[b-dctez9r8y6] {
    margin: 0;
    font-size: 0.75rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--sail-text-muted);
}

/* ENG-tile-presentation-fix: the drafted figure/caption hierarchy. Both used to render at body size, so
   the tiles read as paragraphs rather than as an overview. The figure is the one thing you scan; the
   caption tells you what it counts. A tile whose leading line carries no number renders no figure at all
   — the caption simply stands alone, and nothing is invented to fill the slot. */
.cc-overview-card__figure[b-dctez9r8y6] {
    margin: 0;
    font-size: 1.75rem;          /* 28px, wide band */
    line-height: 1.05;
    font-weight: 600;
    color: var(--sail-text);
}

.cc-supporting .cc-overview-card__figure[b-dctez9r8y6] {
    font-size: 1.4375rem;        /* 23px, sticky column */
}

.cc-overview-card__caption[b-dctez9r8y6] {
    margin: 0;
    font-size: 0.8rem;
    color: var(--sail-text-muted);
}

.cc-overview-card__lines[b-dctez9r8y6] {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: 0.9rem;
    font-weight: 600;
}

    /* Dense-surface two-line clamp (UX-005 responsive rule) — defensive: today's generated overview
       lines are always short, but this keeps a future longer line from breaking the equal-height row. */
    .cc-overview-card__lines li[b-dctez9r8y6] {
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
    }

.cc-overview-card__empty[b-dctez9r8y6] {
    margin: 0;
    color: var(--sail-text-muted);
    font-size: 0.85rem;
}

/* PI's temporary capability-unavailable presentation (IMP-088) — deliberately quiet/neutral, never
   styled like a Blocked/error card (no critical border/glow is ever applied to this card). */
.cc-overview-card--quiet[b-dctez9r8y6] {
    opacity: 0.75;
}

/* IMP-090: Goals/Operations are real <button>s (keyboard-operable) — this class strips native button
   chrome so they read identically to the plain .cc-overview-card layout above, PI included. */
.cc-overview-card--interactive[b-dctez9r8y6] {
    background: none;
    border: none;
    width: 100%;
    font: inherit;
    color: inherit;
    text-align: left;
    cursor: pointer;
}

/* The restrained "View Goals"/"View Operations" activation cue (IMP-090) — quiet accent text, pushed to
   the card's own bottom edge via margin-top: auto so it stays visually consistent regardless of how
   many overview lines precede it in the equal-height row. Never rendered on the PI card. */
.cc-overview-card__cta[b-dctez9r8y6] {
    margin-top: auto;
    color: var(--sail-accent);
    font-size: 0.7rem;
    letter-spacing: 0.03em;
    text-transform: uppercase;
}

.cc-banner[b-dctez9r8y6] {
    margin: 0 0 0.75rem;
    padding: 0.5rem 0.75rem;
    border-radius: 3px;
    border-left: 3px solid;
    font-size: 0.8rem;
}

.cc-banner--positive[b-dctez9r8y6] {
    background: rgba(61, 220, 151, 0.08);
    border-color: var(--sail-positive);
}

.cc-banner--critical[b-dctez9r8y6] {
    background: rgba(239, 83, 80, 0.1);
    border-color: var(--sail-critical);
}

.cc-loading[b-dctez9r8y6], .cc-empty[b-dctez9r8y6] {
    color: var(--sail-text-muted);
    font-size: 0.85rem;
}

.cc-section[b-dctez9r8y6] {
    margin-bottom: var(--cc-band-gap);
}

    .cc-section h2[b-dctez9r8y6] {
        margin: 0 0 0.5rem;
        color: var(--sail-text-muted);
        font-size: 0.75rem;
        letter-spacing: 0.08em;
        text-transform: uppercase;
    }

/* Status is never conveyed by color alone: each tone also carries distinct wording (CommandCenterDisplay)
   and a distinct leading glyph here, so a grayscale or color-blind view still discriminates every state. */
.cc-badge[b-dctez9r8y6] {
    display: inline-block;
    padding: 0.15rem 0.45rem;
    border: 1px solid transparent;
    border-radius: 2px;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    white-space: nowrap;
}

.cc-badge--positive[b-dctez9r8y6] {
    color: var(--sail-positive);
    border-color: var(--sail-positive);
    background: rgba(61, 220, 151, 0.08);
}

    .cc-badge--positive[b-dctez9r8y6]::before {
        content: "✓ ";
    }

.cc-badge--caution[b-dctez9r8y6] {
    color: var(--sail-caution);
    border-color: var(--sail-caution);
    background: rgba(232, 179, 57, 0.08);
}

    .cc-badge--caution[b-dctez9r8y6]::before {
        content: "» ";
    }

.cc-badge--critical[b-dctez9r8y6] {
    color: var(--sail-critical);
    border-color: var(--sail-critical);
    background: rgba(239, 83, 80, 0.08);
}

    .cc-badge--critical[b-dctez9r8y6]::before {
        content: "✕ ";
    }

.cc-badge--neutral[b-dctez9r8y6] {
    color: var(--sail-neutral);
    border-color: var(--sail-neutral);
    background: rgba(124, 133, 147, 0.08);
}

    .cc-badge--neutral[b-dctez9r8y6]::before {
        content: "… ";
    }

/* ---------------------------------------------------------------------------------------------
   IMP-092/UX-005 §3.9: exact refresh-scoped change emphasis — a distinct, static (never pulsing/
   flashing) blue-white edge illumination, deliberately never reusing the positive/caution/critical
   status glow above: "something changed" is never itself better/worse/blocked. Applied only while
   Home.razor's own transient _activeChangedSubjects set is non-empty for the given subject, and always
   paired with the plain-text .cc-changed-marker below so the signal is never color-only.
   --------------------------------------------------------------------------------------------- */

/* IMP-112: Workspace Readiness moved into the Command Center header (its single owner) and the
   standalone Supporting Detail section was removed with it, taking the last consumer of the section's
   own change-highlight glow. The header keeps the accessible, non-color-only .cc-changed-marker below —
   the same "Changed" cue it has always rendered for readiness — so the change signal is preserved. */
.cc-changed-marker[b-dctez9r8y6] {
    display: inline-block;
    margin-left: 0.4rem;
    padding: 0.05rem 0.4rem;
    border: 1px solid rgba(214, 234, 255, 0.5);
    border-radius: 2px;
    color: var(--sail-accent);
    font-size: 0.62rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    vertical-align: middle;
    white-space: nowrap;
}

.cc-queue-tag[b-dctez9r8y6] {
    margin: 0 0 0.5rem;
    color: var(--sail-accent);
    font-size: 0.75rem;
}

/* The Work Queue's own per-step Recommendation-kind label (IMP-086). IMP-111 retired the Command
   Center's Policy cards, which were the last consumer of the filled dominant-action block (the primary
   action wrapper with its action text and explanation) — that block is gone; this small kind label
   remains, still used standalone by the Work Queue step rows and the Operational Workspace run steps. */
.cc-action-kind[b-dctez9r8y6] {
    color: var(--sail-accent);
    font-size: 0.65rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

/* IMP-114 (ENG-049 §61): the ephemeral "what changed this refresh" disclosure — a compact, transient
   banner beside the Refresh feedback (never a standalone Supporting Information card). Deliberately quiet:
   a restrained Steel Blue left edge (the same --sail-accent the header's own change marker uses) and a
   faint tint, so it reads as transient refresh feedback rather than a content section. Rendered only when
   a just-completed refresh actually changed something; nothing at all otherwise. */
.cc-change-summary[b-dctez9r8y6] {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    margin: 0 0 0.75rem;
    padding: 0.5rem 0.75rem;
    border-left: 3px solid var(--sail-accent);
    background: rgba(79, 179, 255, 0.06);
    border-radius: 3px;
}

.cc-change-summary__label[b-dctez9r8y6] {
    color: var(--sail-text-muted);
    font-size: 0.65rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.cc-change-summary__list[b-dctez9r8y6] {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: 0.8rem;
}

.cc-stat-grid[b-dctez9r8y6] {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0.4rem 0.75rem;
    margin: 0;
}

    .cc-stat-grid div[b-dctez9r8y6] {
        display: flex;
        flex-direction: column;
    }

    .cc-stat-grid dt[b-dctez9r8y6] {
        color: var(--sail-text-muted);
        font-size: 0.65rem;
        text-transform: uppercase;
    }

    /* Deliberately smaller/lighter than a decision's own action text (IMP-075): a summary count is
       reassurance, not a decision, and must never visually out-shout the one thing the player should act on. */
    .cc-stat-grid dd[b-dctez9r8y6] {
        margin: 0;
        font-size: 0.85rem;
        font-weight: 500;
        color: var(--sail-text-muted);
    }

/* ---------------------------------------------------------------------------------------------
   IMP-090/UX-005 §3.5: Operations detail modal content — Active Industry's own stat grid (reusing
   .cc-stat-grid verbatim, moved out of the main page's now-removed .cc-industry section) plus the
   Production Queue list, kept as its own clearly separate subsection so it never reads as if a Job and
   a queued Goal were the same, related row.
   --------------------------------------------------------------------------------------------- */

.cc-modal-operations[b-dctez9r8y6] {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
}

.cc-modal-operations__subheading[b-dctez9r8y6] {
    margin: 0 0 0.5rem;
    color: var(--sail-text-muted);
    font-size: 0.75rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.cc-modal-operations__queue-list[b-dctez9r8y6] {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

    .cc-modal-operations__queue-list li[b-dctez9r8y6] {
        display: flex;
        align-items: baseline;
        justify-content: space-between;
        gap: 0.75rem;
        padding: 0.4rem 0;
        border-top: 1px solid var(--sail-border);
    }

        .cc-modal-operations__queue-list li:first-child[b-dctez9r8y6] {
            border-top: none;
            padding-top: 0;
        }

.cc-modal-operations__queue-goal[b-dctez9r8y6] {
    font-weight: 500;
    font-size: 0.85rem;
}

/* ---------------------------------------------------------------------------------------------
   IMP-088: responsive behavior — verified at 1600px, ~1024px, ~768px. Overview cards stay in one
   equal-height row down to 900px (comfortable at both 1600 and ~1024 content widths, accounting for
   the IMP-086 sidebar's own icon-rail/wide tiers); below that they stack to avoid horizontal
   compression to unreadability. NEXT and the header never change shape at any width — no card becomes
   horizontally compressed to unreadability, and no page-level horizontal overflow is introduced.
   --------------------------------------------------------------------------------------------- */

/* ENG-goals-landing-page: .cc-header's own flex-wrap moved to app.css with the rest of the header
   construction — it is what keeps the actions from being crushed against the title at narrow widths,
   which every page carrying this header needs, not the Command Center alone. */

@media (max-width: 899px) {
    /* ENG-CC-002: below this width the two-column composition collapses to a single stack — the
       supporting column drops back below the Work Queue, exactly the pre-two-column arrangement, so no
       content is lost on smaller viewports. (The overview cards already stack vertically at every width
       now, so no separate overview-row/border override is needed here anymore.) */
    .cc-main[b-dctez9r8y6] {
        grid-template-columns: 1fr;
    }

    /* ENG-command-center-layout-rebuild: once the composition is a single stack there is nothing beside
       the overview to stay level with, so pinning it would just hold tiles over the scrolling queue. */
    .cc-supporting[b-dctez9r8y6] {
        position: static;
    }

    .cc-wide[b-dctez9r8y6] {
        grid-template-columns: 1fr;
    }
}

/* ENG-command-center-layout-rebuild: the full-width Character strip at the foot of the page.
   These rules deliberately mirror /reference's own strip, and the duplication is forced rather than
   chosen: Blazor CSS isolation scopes Reference.razor.css to that component, so a class defined there
   cannot reach this page. The MECHANISM is genuinely shared — both render EveVisual with
   EveVisualKind.Character — and only the styling is restated. Consolidating the two (or dropping one when
   /reference's overlap is decided) is a follow-up, deliberately not folded into a layout ticket. */
.cc-character-strip[b-dctez9r8y6] {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    margin-top: var(--cc-band-gap);
}

.cc-character-strip__head[b-dctez9r8y6] {
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
}

    .cc-character-strip__head h2[b-dctez9r8y6] {
        margin: 0;
        font-size: 0.75rem;
        color: var(--sail-text-muted);
    }

        /* The strip's own band icon, on the same mask mechanism as the tiles. The portraits below are
           real EVE character art (EveVisual); this only labels the band. */
        .cc-character-strip__head h2[b-dctez9r8y6]::before {
            content: "";
            display: inline-block;
            width: 1.15rem;
            height: 1.15rem;
            margin-right: 0.45rem;
            vertical-align: -0.22rem;
            background-color: var(--cc-tile-characters);
            -webkit-mask: url("/icons/phosphor/users-duotone.svg") no-repeat center / contain;
            mask: url("/icons/phosphor/users-duotone.svg") no-repeat center / contain;
        }

.cc-character-strip__count[b-dctez9r8y6] {
    color: var(--sail-text-muted);
    font-size: 0.75rem;
}

/* ENG-tile-presentation-fix: the row NEVER wraps. Eight characters used to render seven-plus-one, and a
   single orphan on a second row reads as a bug.

   A single-row grid whose tracks divide the width equally and shrink with the count, down to a floor —
   past that the row scrolls horizontally instead of wrapping. `grid-auto-flow: column` is what
   guarantees one row at any count: there is no second row for an overflowing item to fall to.

   The count is not fixed, so the behaviour is stated for the sizes that matter:
     8  (today)  -> ~10rem tracks, comfortable.
     12          -> ~6.6rem tracks, tighter but each portrait and both text lines still fit.
     20          -> the 5.5rem floor engages; the row becomes horizontally scrollable and STILL does not
                    wrap. 5.5rem (88px) is the floor because the 2.25rem portrait plus the two text lines
                    stop reading below it — past that, scrolling is the honest answer rather than
                    shrinking portraits into illegibility.
   Matches the approach /reference's own strip already takes (overflow-x, never flex-wrap). */
.cc-character-strip__row[b-dctez9r8y6] {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(5.5rem, 1fr);
    gap: 0.75rem;
    overflow-x: auto;
    padding-bottom: 0.25rem;
}

/* Non-interactive here (a plain div, not /reference's button) — this strip opens no popover, and a
   button that activates nothing would be a dead control. */
.cc-character-portrait[b-dctez9r8y6] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.3rem;
    padding: 0.75rem 0.5rem;
    /* A grid item defaults to min-width: auto, which refuses to shrink below its content and would
       defeat the track floor above entirely. Zero here hands sizing to grid-auto-columns' own minmax. */
    min-width: 0;
    text-align: center;
    border-radius: var(--sail-radius-panel);
    background: var(--sail-glass-bg);
    border: 1px solid var(--sail-glass-border);
}

/* Both text lines truncate rather than widen their track — a long Character name must not be what
   decides the row's layout. */
.cc-character-portrait__name[b-dctez9r8y6],
.cc-character-portrait__meta[b-dctez9r8y6] {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.cc-character-portrait__name[b-dctez9r8y6] {
    font-size: 0.85rem;
    color: var(--sail-text);
}

.cc-character-portrait__meta[b-dctez9r8y6] {
    font-size: 0.72rem;
    color: var(--sail-text-muted);
}

/* -----------------------------------------------------------------------------------------------
   IMP-086 (ENG-045/ENG-046/ENG-DISC-001): the Command Center Work Queue — the primary content unit.
   Restrained, reusing the existing tokens/glass system; Attention treatment follows PriorityTier only,
   equivalent packages get equal weight, evidence/contained-work disclose quietly. No global overhaul.
   ----------------------------------------------------------------------------------------------- */

/* ENG-disc-right-and-queue-box: the Work Queue is a real container now, not loose cards on the page.
   ENG-column-alignment-fix gave it the stretch that makes it reach the supporting column's height, but
   without a visible surface the gap before the wide tiles read exactly as it had before — the space was
   filled by nothing you could see.

   The surface is `sail-glass` in the markup, the SAME class the supporting tiles and the header already
   use, so this reuses the app's treatment rather than inventing a container style. Its padding matches
   the tiles' own 1rem/1.25rem, and the heading and subtitle sit inside it exactly as each tile carries
   its own label. */
.cc-work-queue[b-dctez9r8y6] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding: 1rem 1.25rem;
}

.cc-work-queue__head[b-dctez9r8y6] {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

    /* ENG-button-disabled-state-fix: "Work Queue" reads as a section heading again. Inside its own box it
       was rendering at .cc-section h2's 0.75rem muted label size — identical to the tile labels beside it,
       which made the page's PRIMARY content the quietest text in its own container.

       Raised to --sail-text-md and full-strength text colour, keeping the uppercase/tracked label language
       the rest of the page uses so it reads as the same family, one step up. Deliberately still below the
       page <h1>: this names the primary section, not the page. The subtitle is untouched. */
    .cc-work-queue__head h2[b-dctez9r8y6] {
        font-size: var(--sail-text-md);
        color: var(--sail-text);
        letter-spacing: 0.06em;
    }

.cc-work-queue__hint[b-dctez9r8y6] {
    color: var(--sail-text-muted);
    font-size: 0.9rem;
}

.cc-work-queue__list[b-dctez9r8y6] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.cc-work-package[b-dctez9r8y6] {
    padding: 1.15rem 1.35rem;
    border-radius: 1rem;
    display: flex;
    /* ENG-CC-001: the subject-item thumbnail sits left, the tags/title/explanation/disclosures flow
       right of it in the __body column — reusing the same flex idiom the card already used vertically. */
    flex-direction: row;
    align-items: flex-start;
    gap: 1rem;
    border-left: 3px solid transparent;
}

/* ENG-CC-001: the fixed-size EVE thumbnail column, never shrinking the image to fit the text.
   ENG-CC-003: vertically centered against the whole card via align-self (the card row stays
   align-items: flex-start so the text block keeps reading from the top — only the image re-centers). */
.cc-work-package__media[b-dctez9r8y6] {
    flex: 0 0 auto;
    align-self: center;
}

/* ENG-CC-003 (was the ENG-CC-001 size bump): the card requests EveVisualSize.Large (a 128px Image
   Server source), displayed here at 6rem/96px — still no upscaling (128 >= 96). Scoped to this card
   only, via ::deep into EveVisual's own root; the global .eve-visual--large stays 80px, so no other
   surface is affected. */
.cc-work-package__media[b-dctez9r8y6]  .eve-visual {
    width: 6rem;
    height: 6rem;
}

/* The item thumbnail sits directly on the glass card, so drop EveVisual's own dark tile frame (its
   .eve-visual background + .eve-visual--item border) HERE only — it did not fit the glass look. Scoped via
   ::deep to this card's own icon; EveVisual is untouched, so the production-tree row icons' coloured state
   frames (.pt-node--*, a separate wrapper) and every other consumer keep their framing. */
.cc-work-package__media[b-dctez9r8y6]  .eve-visual {
    border: none;
    background: transparent;
}

/* ENG-CC-003: on the work-package card only, the item icon is "presented" with air around it —
   object-fit: contain + padding so it is fully visible inside the 96px frame rather than filling it
   edge-to-edge. Scoped via ::deep to this card's own image; the global .eve-visual__image rule
   (EveVisual.razor.css) is untouched, so Reference's Character portraits (and every other consumer)
   keep their cover behaviour. The Sail fallback (.eve-visual__fallback) already has its own
   contain+padding globally and is unaffected. */
.cc-work-package__media[b-dctez9r8y6]  .eve-visual__image {
    object-fit: contain;
    padding: 11%;
}

/* ENG-CC-001: the card's textual content, carrying the vertical rhythm the card itself previously owned. */
.cc-work-package__body[b-dctez9r8y6] {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
}

/* Attention (tier-1) is recognizable — a strong but restrained caution edge, never an invented score. */
.cc-work-package--attention[b-dctez9r8y6] {
    border-left-color: var(--sail-caution);
}

/* Tier-4 objective-evidence fallback / everything else: neutral, no implied value magnitude. */
.cc-work-package--neutral[b-dctez9r8y6] {
    border-left-color: var(--sail-border);
}

.cc-work-package__tags[b-dctez9r8y6] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
}

.cc-work-package__kind[b-dctez9r8y6] {
    font-size: 0.72rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--sail-text-muted);
    padding: 0.12rem 0.5rem;
    border: 1px solid var(--sail-glass-border-strong);
    border-radius: 999px;
}

.cc-work-package__attention[b-dctez9r8y6] {
    font-size: 0.72rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--sail-caution);
    padding: 0.12rem 0.5rem;
    border: 1px solid rgba(232, 179, 57, 0.4);
    border-radius: 999px;
}

.cc-work-package__equivalent[b-dctez9r8y6] {
    font-size: 0.72rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--sail-text-muted);
    padding: 0.12rem 0.5rem;
    border: 1px dashed var(--sail-glass-border-strong);
    border-radius: 999px;
}

.cc-work-package__state[b-dctez9r8y6] {
    margin-left: auto;
    font-size: 0.8rem;
    color: var(--sail-text-muted);
}

/* ENG-CC-001: the estimated acquisition value — a quiet technical figure on the metadata line, never
   emphasized as a score or magnitude beyond the plain number the read model supplies. */
.cc-work-package__value[b-dctez9r8y6] {
    font-size: 0.8rem;
    color: var(--sail-text-muted);
}

.cc-work-package__title[b-dctez9r8y6] {
    margin: 0;
    font-size: 1.1rem;
    color: var(--sail-text);
}

.cc-work-package__explanation[b-dctez9r8y6] {
    margin: 0;
    color: var(--sail-text-muted);
    line-height: 1.45;
}

.cc-work-package__disclosure > summary[b-dctez9r8y6] {
    cursor: pointer;
    color: var(--sail-accent);
    font-size: 0.9rem;
    width: fit-content;
}

.cc-work-package__steps[b-dctez9r8y6],
.cc-work-package__evidence[b-dctez9r8y6] {
    list-style: none;
    margin: 0.5rem 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    color: var(--sail-text-muted);
}

.cc-work-package__evidence[b-dctez9r8y6] {
    padding-left: 1.1rem;
    list-style: disc;
}

.cc-work-package__step[b-dctez9r8y6] {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
}

.cc-work-package__step-explanation[b-dctez9r8y6] {
    font-size: 0.85rem;
    color: var(--sail-text-muted);
}

/* ENG-button-disabled-state-fix: this rule is LAYOUT ONLY now, and that is the whole fix.

   It used to carry the unavailable look (dashed border, muted colour, not-allowed cursor) as the BASE,
   with `--available` overriding it. That worked while both lived here, because Blazor compiles a scoped
   selector with a [b-xxxxx] attribute: the base was (0,2,0) and the scoped override (0,2,1), so the
   override won.

   1bed8dd moved the override into app.css as `a.cc-work-package__action--available` — (0,1,1), which
   LOSES to the base's (0,2,0). So every available action silently inherited the unavailable treatment:
   dashed, grey, not-allowed, while still navigating correctly.

   Splitting the states apart removes the contest entirely rather than out-specifying it: the base styles
   neither state, the shared rule in app.css styles the available one, and the rule below styles the
   unavailable one from its own explicit [disabled] selector. */
.cc-work-package__action[b-dctez9r8y6] {
    align-self: flex-start;
}

/* ENG-button-disabled-state-fix: the card's actions share one row, wrapping only when the card is too
   narrow for them. They stacked before because they were siblings inside the card's own flex column. */
.cc-work-package__actions[b-dctez9r8y6] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.25rem;
}

/* The honest unavailable affordance, now stated explicitly instead of being inherited from a base.
   Only the "coming soon" control is a disabled <button>; the available one is an <a> and can never match
   this. Deliberately NOT the shared button treatment: dashed rather than solid, muted rather than
   coloured, and not-allowed rather than pointer — so a control that cannot be used never looks like one
   that can. */
button.cc-work-package__action[disabled][b-dctez9r8y6] {
    padding: 0.4rem 0.85rem;
    border-radius: 0.6rem;
    border: 1px dashed var(--sail-glass-border-strong);
    background: transparent;
    color: var(--sail-text-muted);
    font-size: 0.85rem;
    cursor: not-allowed;
}

.cc-work-queue__calm[b-dctez9r8y6] {
    padding: 2rem 1.5rem;
    border-radius: var(--sail-radius-panel, 1.25rem);
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    align-items: center;
    text-align: center;
    border: 1px solid rgba(61, 220, 151, 0.25);
}

.cc-work-queue__calm-eyebrow[b-dctez9r8y6] {
    margin: 0;
    font-size: 0.8rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--sail-positive);
}

.cc-work-queue__calm-headline[b-dctez9r8y6] {
    margin: 0;
    font-size: 1.4rem;
    color: var(--sail-text);
}

.cc-work-queue__calm-body[b-dctez9r8y6] {
    margin: 0;
    max-width: 42ch;
    color: var(--sail-text-muted);
}

/* Transitional demotion of the legacy sections: a self-contained divider heading marking where the
   Work Queue ends and the retained legacy supporting content begins (no container wrapper — see
   Home.razor for why). */
/* ENG-supporting-detail-cards: the supporting column's own title, renamed from
   .cc-legacy-supporting__note.

   Both the old name and its border-top were vestiges of the pre-ENG-CC-002 layout, when this content
   was a horizontal band BELOW the Work Queue and that rule separated it from the queue above. In a
   16rem right-hand column it divided nothing from nothing, and it was the only ruled label on the page
   — every other .cc section label is unruled. It is deliberately gone, along with the 1.25rem
   padding-top that existed solely to hold the text clear of it, and the 2.5rem top margin that pushed
   the label down past content which no longer sits above it.

   The label itself is deliberately KEPT (see the report). The Work Queue column carries a visible
   heading, and UX-005 §3.3/§3.5 requires this band to read as "clearly secondary to the Work Queue,
   never a second dashboard" — five untitled floating cards would read as exactly that second
   dashboard. The bottom margin matches the stack's own gap so the title sits in the same rhythm as the
   cards it introduces. */
.cc-supporting__title[b-dctez9r8y6] {
    margin: 0 0 0.75rem;
    font-size: 0.75rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--sail-text-muted);
}

/* IMP-087 (ENG-048 §7): a PI Work Package's action is a real link to its Operational Workspace — an
   actionable accent affordance, distinct from the dashed disabled state other (not-yet-implemented)
   kinds keep. */


/* BI-038 built count — follows the state on the work-package metadata line. No margin-left:auto:
   .cc-work-package__state already pushes the pair right; this trails it. */
.cc-work-package__built[b-dctez9r8y6] {
    font-size: 0.8rem;
    color: var(--sail-text-muted);
}
/* /Components/Pages/Hubs.razor.rz.scp.css */
/* IMP-116: the Hub Management Supporting Surface. Mirrors Goals.razor.css (IMP-090)/Policies.razor.css
   (IMP-091) exactly — same class names, same rules — since Blazor CSS isolation scopes each .razor.css
   to its own component only; this duplication is the same pattern Bridge.razor/Home.razor already
   established for their own independent, overlapping visual vocabulary. Restrained, reusing the existing
   design tokens and glass system (app.css) — no new branding, no typography changes, no Design System. */

.goals-page[b-ak2elbmeln] {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    max-width: 60rem;
    margin: 0 auto;
}

/* --- create form --------------------------------------------------------------------------------- */

.goals-create[b-ak2elbmeln] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding: var(--sail-space-5, 1.5rem);
    border-radius: var(--sail-radius-panel, 1.25rem);
}

.goals-create__title[b-ak2elbmeln] {
    margin: 0;
    font-size: 1.05rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--sail-text);
}

.goals-create__field[b-ak2elbmeln] {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.goals-create__field label[b-ak2elbmeln] {
    font-size: 0.85rem;
    color: var(--sail-text-muted);
}

.goals-create__input[b-ak2elbmeln] {
    padding: 0.5rem 0.75rem;
    border-radius: var(--sail-radius-control, 0.625rem);
    border: 1px solid var(--sail-border);
    background: var(--sail-bg-elevated);
    color: var(--sail-text);
    font-size: 1rem;
}

.goals-create__hint[b-ak2elbmeln] {
    margin: 0;
    font-size: 0.78rem;
    color: var(--sail-text-muted);
}

.hub-category-option[b-ak2elbmeln] {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 0.5rem;
    color: var(--sail-text);
    font-size: 0.95rem;
    cursor: pointer;
}

/* Ravworks job-plan epic, Story 3b: the four (Hub, Activity) ME/TE inputs beneath a checked activity. */
.hub-activity-efficiency[b-ak2elbmeln] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    padding: 0.4rem 0 0.6rem 1.75rem;
}

.hub-activity-efficiency label[b-ak2elbmeln] {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    color: var(--sail-text-muted);
    font-size: 0.8rem;
}

.hub-activity-efficiency__input[b-ak2elbmeln] {
    width: 5rem;
    padding: 0.25rem 0.4rem;
    border-radius: var(--sail-radius-control, 0.4rem);
    border: 1px solid var(--sail-border);
    background: var(--sail-bg-elevated);
    color: var(--sail-text);
    font-size: 0.9rem;
}

.goals-create__actions[b-ak2elbmeln] {
    display: flex;
    justify-content: flex-end;
}

/* --- empty state ---------------------------------------------------------------------------------- */

.goals-empty[b-ak2elbmeln] {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.75rem;
    padding: var(--sail-space-5, 1.5rem);
    border-radius: var(--sail-radius-panel, 1.25rem);
}

.goals-empty__headline[b-ak2elbmeln] {
    margin: 0;
    font-size: 1.1rem;
    color: var(--sail-text);
}

.goals-empty__body[b-ak2elbmeln] {
    margin: 0;
    color: var(--sail-text-muted);
}

/* --- hub list/cards ------------------------------------------------------------------------------ */

.goals-list[b-ak2elbmeln] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
}

.goal-card[b-ak2elbmeln] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 1.1rem 1.25rem;
    border-radius: var(--sail-radius-panel, 1.25rem);
}

.goal-card__head[b-ak2elbmeln] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
}

.goal-card__title[b-ak2elbmeln] {
    margin: 0;
    font-size: 1.05rem;
    color: var(--sail-text);
}

.hub-card__categories[b-ak2elbmeln],
.hub-card__activities[b-ak2elbmeln] {
    margin: 0;
    font-size: 0.82rem;
    color: var(--sail-text-muted);
    letter-spacing: 0.02em;
}

/* --- collapsible sections (Hub Definition / Mapped / Unmapped) ------------------------------------ */

.hub-section[b-ak2elbmeln] {
    border-radius: var(--sail-radius-panel, 1.25rem);
    overflow: hidden;
}

.hub-section__header[b-ak2elbmeln] {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    width: 100%;
    padding: 0.9rem 1.25rem;
    background: transparent;
    border: none;
    cursor: pointer;
    color: var(--sail-text);
    text-align: left;
}

.hub-section__header:hover[b-ak2elbmeln] {
    background: var(--sail-bg-card);
}

.hub-section__chevron[b-ak2elbmeln] {
    color: var(--sail-text-muted);
    font-size: 0.85rem;
    width: 1em;
    flex: none;
}

.hub-section__title[b-ak2elbmeln] {
    font-size: 1.05rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--sail-text);
}

.hub-section__count[b-ak2elbmeln] {
    margin-left: auto;
    font-size: 0.85rem;
    color: var(--sail-text-muted);
    font-variant-numeric: tabular-nums;
}

.hub-section__body[b-ak2elbmeln] {
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
    padding: 0 1.25rem 1.25rem;
}

.hub-section__toolbar[b-ak2elbmeln] {
    display: flex;
    justify-content: flex-end;
}

.hub-section__empty[b-ak2elbmeln] {
    margin: 0;
    color: var(--sail-text-muted);
}

.hub-section__unresolved[b-ak2elbmeln] {
    margin: 0;
    font-size: 0.82rem;
    color: var(--sail-text-muted);
    font-style: italic;
}

/* --- stock locations (read-only) ----------------------------------------------------------------- */

.locations-section[b-ak2elbmeln] {
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
    margin-top: 1.5rem;
}

.locations-section__title[b-ak2elbmeln] {
    margin: 0;
    font-size: 1.05rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--sail-text);
}

.locations-section__hint[b-ak2elbmeln] {
    margin: 0;
    font-size: 0.82rem;
    color: var(--sail-text-muted);
}

.location-badge[b-ak2elbmeln] {
    font-size: 0.78rem;
    padding: 0.15rem 0.55rem;
    border-radius: var(--sail-radius-pill, 999px);
    border: 1px solid var(--sail-border);
    color: var(--sail-text-muted);
    white-space: nowrap;
}

.location-badge--mapped[b-ak2elbmeln] {
    color: var(--sail-positive);
    border-color: var(--sail-positive);
}

.location-badge--unmapped[b-ak2elbmeln] {
    color: var(--sail-caution);
    border-color: var(--sail-caution);
}

.location-card__meta[b-ak2elbmeln] {
    margin: 0;
    font-size: 0.85rem;
    color: var(--sail-text-muted);
}

.location-card__nested[b-ak2elbmeln] {
    color: var(--sail-text-muted);
}

.location-card__contents[b-ak2elbmeln] {
    margin: 0;
    font-size: 0.82rem;
    color: var(--sail-text);
    letter-spacing: 0.01em;
}

.location-card__actions[b-ak2elbmeln] {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    margin-top: 0.35rem;
}

.location-card__picker[b-ak2elbmeln] {
    padding: 0.4rem 0.6rem;
    border-radius: var(--sail-radius-control, 0.625rem);
    border: 1px solid var(--sail-border);
    background: var(--sail-bg-elevated);
    color: var(--sail-text);
    font-size: 0.9rem;
}

.location-card__hint[b-ak2elbmeln] {
    font-size: 0.82rem;
    color: var(--sail-text-muted);
}

.goal-card__actions[b-ak2elbmeln] {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-top: 0.35rem;
}





.hub-edit-form[b-ak2elbmeln] {
    margin-top: 0.6rem;
}



.goal-card__confirm-text[b-ak2elbmeln] {
    margin: 0;
    color: var(--sail-text);
    font-size: 0.9rem;
}



/* Routing health banner + Production Needs rollup (fine-routing UI surface). This page had no local
   .cc-banner rule of its own (every other page that uses one — Home/Reference/Goals — defines its own
   scoped copy, since Blazor CSS isolation never leaks a class rule across component files), so the base
   rule is included here too rather than left to rely on another page's scoped styling. */
.cc-banner[b-ak2elbmeln] {
    margin: 0 0 0.5rem;
    padding: 0.5rem 0.75rem;
    border-radius: 3px;
    border-left: 3px solid;
    font-size: 0.8rem;
}

.cc-banner--critical[b-ak2elbmeln] {
    background: rgba(239, 83, 80, 0.1);
    border-color: var(--sail-critical);
}

.cc-banner--caution[b-ak2elbmeln] {
    background: rgba(232, 179, 57, 0.1);
    border-color: var(--sail-caution);
}

.cc-banner--positive[b-ak2elbmeln] {
    background: rgba(61, 220, 151, 0.08);
    border-color: var(--sail-positive);
}

/* --- Ravworks efficiency import preview (Ravworks job-plan epic, Import Ticket B) ---------------- */

.ravworks-import-preview__table[b-ak2elbmeln] {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.85rem;
    margin-bottom: 0.75rem;
}

.ravworks-import-preview__table th[b-ak2elbmeln] {
    text-align: left;
    color: var(--sail-text-muted);
    font-weight: 500;
    padding: 0.25rem 0.5rem;
    border-bottom: 1px solid var(--sail-border);
}

.ravworks-import-preview__table td[b-ak2elbmeln] {
    padding: 0.25rem 0.5rem;
    color: var(--sail-text);
    border-bottom: 1px solid var(--sail-border);
}

.ravworks-import-preview__badge[b-ak2elbmeln] {
    font-size: 0.7rem;
    padding: 0.1rem 0.4rem;
    border-radius: var(--sail-radius-control, 4px);
    white-space: nowrap;
}

.ravworks-import-preview__badge--overwrite[b-ak2elbmeln] {
    background: rgba(232, 179, 57, 0.15);
    color: var(--sail-caution);
}

.ravworks-import-preview__badge--add[b-ak2elbmeln] {
    background: rgba(61, 220, 151, 0.12);
    color: var(--sail-positive);
}

.routing-health-banner[b-ak2elbmeln] {
    margin-bottom: 0.75rem;
}

.production-need-group[b-ak2elbmeln] {
    margin-bottom: 1rem;
}

.production-need-group:last-child[b-ak2elbmeln] {
    margin-bottom: 0;
}

.production-need-group__title[b-ak2elbmeln] {
    margin: 0 0 0.4rem;
    font-size: 0.95rem;
    color: var(--sail-text);
}

.production-need-table[b-ak2elbmeln] {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.85rem;
}

.production-need-table th[b-ak2elbmeln] {
    text-align: left;
    color: var(--sail-text-muted);
    font-weight: 500;
    padding: 0.25rem 0.5rem;
    border-bottom: 1px solid var(--sail-border);
}

.production-need-table td[b-ak2elbmeln] {
    padding: 0.25rem 0.5rem;
    color: var(--sail-text);
    border-bottom: 1px solid var(--sail-border);
}

.production-need-row--short td[b-ak2elbmeln] {
    color: var(--sail-critical);
}

.production-need-row--covered td[b-ak2elbmeln] {
    color: var(--sail-text-muted);
}
/* /Components/Pages/Login.razor.rz.scp.css */
.login-panel[b-t4ejz9xl0w] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
    width: min(24rem, 100%);
    padding: 2.5rem 2rem;
    border-radius: 10px;
    text-align: center;
}

.login-panel__tagline[b-t4ejz9xl0w] {
    color: var(--sail-text-muted, #9aa7b5);
    margin: 0;
}

.login-panel__message[b-t4ejz9xl0w] {
    color: var(--sail-caution, #e8b84f);
    font-size: 0.85rem;
    margin: 0;
}

.login-panel__action[b-t4ejz9xl0w] {
    margin-top: 0.5rem;
}
/* /Components/Pages/OperationalWorkspace.razor.rz.scp.css */
/* IMP-087 (ENG-048): the Operational Workspace — the reference layout for every future workspace.
   Clarity, focus, calm; one obvious objective, restrained supporting information. Reuses the existing
   design tokens and glass system (app.css); no broad styling changes. */

.ows[b-0ggu92dghz] {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
    max-width: 52rem;
    margin: 0 auto;
}

.ows-return[b-0ggu92dghz] {
    display: flex;
    gap: 1.25rem;
}

/* --- workspace ---------------------------------------------------------------------------------- */

.ows-workspace[b-0ggu92dghz] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.ows-header[b-0ggu92dghz] {
    padding: 1.75rem 1.75rem 1.5rem;
    border-radius: var(--sail-radius-panel, 1.25rem);
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    border-left: 3px solid var(--sail-accent);
}

.ows-kind[b-0ggu92dghz] {
    font-size: 0.72rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--sail-text-muted);
}

.ows-title[b-0ggu92dghz] {
    margin: 0;
    font-size: 1.75rem;
    color: var(--sail-text);
}

.ows-explanation[b-0ggu92dghz] {
    margin: 0;
    color: var(--sail-text-muted);
    line-height: 1.45;
}

.ows-status[b-0ggu92dghz] {
    margin: 0.25rem 0 0;
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
}

.ows-status__label[b-0ggu92dghz] {
    font-size: 0.72rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--sail-text-muted);
}

.ows-status__value[b-0ggu92dghz] {
    color: var(--sail-text);
    font-size: 0.95rem;
}

/* --- body: operational guidance ----------------------------------------------------------------- */

.ows-body[b-0ggu92dghz] {
    padding: 1.5rem 1.75rem;
    border-radius: 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.ows-body__heading[b-0ggu92dghz] {
    margin: 0;
    font-size: 1.15rem;
    color: var(--sail-text);
}

.ows-body__lead[b-0ggu92dghz] {
    margin: 0;
    color: var(--sail-text);
    line-height: 1.5;
}

.ows-steps[b-0ggu92dghz] {
    margin: 0;
    padding-left: 1.35rem;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    color: var(--sail-text-muted);
    line-height: 1.45;
}

.ows-completion-note[b-0ggu92dghz] {
    margin: 0.25rem 0 0;
    font-size: 0.9rem;
    color: var(--sail-text-muted);
    border-top: 1px solid var(--sail-glass-border);
    padding-top: 0.75rem;
}

/* --- evidence disclosure ------------------------------------------------------------------------ */

.ows-evidence > summary[b-0ggu92dghz] {
    cursor: pointer;
    color: var(--sail-accent);
    font-size: 0.9rem;
    width: fit-content;
}

.ows-evidence__list[b-0ggu92dghz] {
    margin: 0.5rem 0 0;
    padding-left: 1.1rem;
    color: var(--sail-text-muted);
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

/* --- build-goal production tree card ------------------------------------------------------------ */

/* A padded glass card (mirrors .ows-body above it) so the tree block sits as a visual equal beside
   "Carry out this work" — the padding applies in BOTH collapsed and open states (it is on the <details>
   itself, always rendered). The .sail-glass class already supplies the surface; this adds the padding. */
.ows-build-tree[b-0ggu92dghz] {
    padding: 1.5rem 1.75rem;
    border-radius: 1rem;
}

/* The <summary> is the card heading AND the collapse control — drop the native disclosure marker.
   Layout: [chevron] [96px icon] [ title + summary ]. */
.ows-build-tree__heading[b-0ggu92dghz] {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    cursor: pointer;
    list-style: none;
}
.ows-build-tree__heading[b-0ggu92dghz]::-webkit-details-marker {
    display: none;
}
.ows-build-tree__heading[b-0ggu92dghz]::marker {
    content: "";
}

/* The target item's icon at 96px — the SAME display size as the Command Center WorkQueue card thumbnail
   (Home.razor.css's .cc-work-package__media ::deep .eve-visual). EveVisualSize.Large is a 128px source, so
   96px is not upscaled. Scoped via ::deep to THIS header only — EveVisual and the 64px tree ROW icons are
   untouched. */
.ows-build-tree__heading[b-0ggu92dghz]  .eve-visual {
    width: 6rem;
    height: 6rem;
}

.ows-build-tree__text[b-0ggu92dghz] {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}

/* Heading title — mirrors the WorkQueue card's goal title (.cc-work-package__title: 1.1rem; the h3's
   Bootstrap-reboot weight 500), so the two surfaces present the same item identically. */
.ows-build-tree__title[b-0ggu92dghz] {
    font-size: 1.1rem;
    font-weight: 500;
    color: var(--sail-text);
}

/* A smaller muted summary of the end product's own quantities, so the collapsed header shows what it is
   short of. */
.ows-build-tree__summary[b-0ggu92dghz] {
    font-size: 0.85rem;
    color: var(--sail-text-muted);
}
.ows-build-tree__short[b-0ggu92dghz] {
    color: var(--sail-critical);
    font-weight: 500;
}

/* A chevron that belongs to the heading — ▸ collapsed, ▾ open — instead of the bare native marker. */
.ows-build-tree__chevron[b-0ggu92dghz] {
    flex: none;
    width: 1em;
    text-align: center;
    font-size: 0.9rem;
    color: var(--sail-text-muted);
}
.ows-build-tree__chevron[b-0ggu92dghz]::before {
    content: "▸";
}
.ows-build-tree[open] .ows-build-tree__chevron[b-0ggu92dghz]::before {
    content: "▾";
}

/* Open only: a hairline divider under the heading separating it from the tree (collapsed = no divider). */
.ows-build-tree[open] .ows-build-tree__heading[b-0ggu92dghz] {
    padding-bottom: 0.75rem;
    margin-bottom: 0.75rem;
    border-bottom: 1px solid var(--sail-border);
}

/* --- panels (completion / error) ---------------------------------------------------------------- */

.ows-panel[b-0ggu92dghz] {
    padding: 2.25rem 2rem;
    border-radius: var(--sail-radius-panel, 1.25rem);
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    align-items: center;
    text-align: center;
}

.ows-panel__eyebrow[b-0ggu92dghz] {
    margin: 0;
    font-size: 0.8rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--sail-text-muted);
}

.ows-panel--complete .ows-panel__eyebrow[b-0ggu92dghz] {
    color: var(--sail-positive);
}

.ows-panel--complete[b-0ggu92dghz] {
    border: 1px solid rgba(61, 220, 151, 0.25);
}

.ows-panel__headline[b-0ggu92dghz] {
    margin: 0;
    font-size: 1.5rem;
    color: var(--sail-text);
}

.ows-panel__body[b-0ggu92dghz] {
    margin: 0;
    max-width: 44ch;
    color: var(--sail-text-muted);
    line-height: 1.5;
}

.ows-panel__actions[b-0ggu92dghz] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    justify-content: center;
    margin-top: 0.5rem;
}

@media (max-width: 40rem) {
    .ows-header[b-0ggu92dghz],
    .ows-panel[b-0ggu92dghz] {
        padding: 1.5rem 1.25rem;
    }

    .ows-title[b-0ggu92dghz] {
        font-size: 1.45rem;
    }
}

/* IMP-088 (ENG-036/ENG-048): the Acquisition workspace body — already-derived required item/quantity,
   selected Hub, keyed Acquisition-Plan context, and the lead/secondary contained steps. Reuses the same
   restrained tokens; no calculation, no new visual language. */

.ows-facts[b-0ggu92dghz] {
    margin: 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
    gap: 0.5rem 1.25rem;
}

.ows-fact[b-0ggu92dghz] {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
}

.ows-fact dt[b-0ggu92dghz] {
    font-size: 0.72rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--sail-text-muted);
}

.ows-fact dd[b-0ggu92dghz] {
    margin: 0;
    color: var(--sail-text);
}

.ows-hub-group[b-0ggu92dghz] {
    margin: 0;
    color: var(--sail-text-muted);
    font-size: 0.9rem;
}

.ows-hub-group strong[b-0ggu92dghz] {
    color: var(--sail-text);
}

.ows-lead-step[b-0ggu92dghz] {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    padding: 0.85rem 1rem;
    border-radius: 0.6rem;
    border-left: 3px solid var(--sail-accent);
    background: var(--sail-glass-bg);
}

.ows-lead-step__text[b-0ggu92dghz] {
    color: var(--sail-text);
}

.ows-lead-step__explanation[b-0ggu92dghz] {
    font-size: 0.85rem;
    color: var(--sail-text-muted);
}

.ows-steps-list[b-0ggu92dghz] {
    list-style: none;
    margin: 0.5rem 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.ows-steps-list > li[b-0ggu92dghz] {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
}

/* BI-038 built count — trails the status value, muted so the status stays the primary signal. */
.ows-status__built[b-0ggu92dghz] {
    margin-left: 0.5rem;
    font-size: 0.9rem;
    color: var(--sail-text-muted);
}
/* /Components/Pages/Policies.razor.rz.scp.css */
/* IMP-091: the Policy Management Supporting Surface. Mirrors Goals.razor.css (IMP-090) exactly — same
   class names, same rules — since Blazor CSS isolation scopes each .razor.css to its own component only;
   this duplication is the same pattern Bridge.razor/Home.razor already established for their own
   independent, overlapping visual vocabulary. Restrained, reusing the existing design tokens and glass
   system (app.css) — no new branding, no typography changes. */

.goals-page[b-dwig71ji42] {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    max-width: 60rem;
    margin: 0 auto;
}

/* --- create form --------------------------------------------------------------------------------- */

.goals-create[b-dwig71ji42] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding: var(--sail-space-5, 1.5rem);
    border-radius: var(--sail-radius-panel, 1.25rem);
}

.goals-create__title[b-dwig71ji42] {
    margin: 0;
    font-size: 1.05rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--sail-text);
}

.goals-create__field[b-dwig71ji42] {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.goals-create__field label[b-dwig71ji42] {
    font-size: 0.85rem;
    color: var(--sail-text-muted);
}

.goals-create__input[b-dwig71ji42] {
    padding: 0.5rem 0.75rem;
    border-radius: var(--sail-radius-control, 0.625rem);
    border: 1px solid var(--sail-border);
    background: var(--sail-bg-elevated);
    color: var(--sail-text);
    font-size: 1rem;
}

.goals-create__actions[b-dwig71ji42] {
    display: flex;
    justify-content: flex-end;
}

/* --- empty state ---------------------------------------------------------------------------------- */

.goals-empty[b-dwig71ji42] {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.75rem;
    padding: var(--sail-space-5, 1.5rem);
    border-radius: var(--sail-radius-panel, 1.25rem);
}

.goals-empty__headline[b-dwig71ji42] {
    margin: 0;
    font-size: 1.1rem;
    color: var(--sail-text);
}

.goals-empty__body[b-dwig71ji42] {
    margin: 0;
    color: var(--sail-text-muted);
}

/* --- goal list/cards ------------------------------------------------------------------------------ */

.goals-list[b-dwig71ji42] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
}

.goal-card[b-dwig71ji42] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 1.1rem 1.25rem;
    border-radius: var(--sail-radius-panel, 1.25rem);
}

.goal-card__head[b-dwig71ji42] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
}

.goal-card__title[b-dwig71ji42] {
    margin: 0;
    font-size: 1.05rem;
    color: var(--sail-text);
}

.goal-card__badge[b-dwig71ji42] {
    flex-shrink: 0;
    padding: 0.2rem 0.6rem;
    border-radius: var(--sail-radius-pill, 999px);
    font-size: 0.8rem;
    letter-spacing: 0.02em;
    color: var(--sail-text-muted);
    border: 1px solid var(--sail-border);
}

.goal-card__explanation[b-dwig71ji42] {
    margin: 0;
    color: var(--sail-text-muted);
}

.goal-card__actions[b-dwig71ji42] {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-top: 0.35rem;
}



.goal-card__confirm-text[b-dwig71ji42] {
    margin: 0;
    color: var(--sail-text);
    font-size: 0.9rem;
}


/* /Components/Pages/Reference.razor.rz.scp.css */
/* IMP-113/ENG-049 §242 (Phase D): the Reference surface — read-only Workspace contents (Inventory
   counts + Character roster), demoted off the Command Center's operational path. Reuses the existing
   design tokens and glass system (app.css) and the shared cc-header/cc-banner/cc-loading vocabulary
   already established by Bridge.razor/Home.razor/Goals.razor — no new branding, no typography changes.
   The Inventory + Character strip + popover presentation below is relocated verbatim from Home.razor.css
   (IMP-091/IMP-093/IMP-101), not redesigned. */

.reference-page[b-e7zk420es4] {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    max-width: 60rem;
    margin: 0 auto;
}

/* --- page chrome (shared cc-header/cc-banner/cc-loading vocabulary) ------------------------------- */

.cc-header[b-e7zk420es4] {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    gap: 1rem;
    padding: 1rem 1.25rem;
    border-radius: var(--sail-radius-panel);
    flex-wrap: wrap;
}

.cc-header__identity[b-e7zk420es4] {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

    .cc-header h1[b-e7zk420es4] {
        margin: 0;
        font-size: 1.25rem;
        letter-spacing: 0.03em;
        text-transform: uppercase;
    }

.cc-header__workspace[b-e7zk420es4] {
    margin: 0;
    color: var(--sail-text-muted);
    font-size: 0.7rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

.cc-banner[b-e7zk420es4] {
    margin: 0;
    padding: 0.5rem 0.75rem;
    border-radius: 3px;
    border-left: 3px solid;
    font-size: 0.8rem;
}

.cc-banner--critical[b-e7zk420es4] {
    background: rgba(239, 83, 80, 0.1);
    border-color: var(--sail-critical);
}

.cc-loading[b-e7zk420es4], .cc-empty[b-e7zk420es4] {
    color: var(--sail-text-muted);
    font-size: 0.85rem;
}

.cc-section[b-e7zk420es4] {
    margin: 0;
}

    .cc-section h2[b-e7zk420es4] {
        margin: 0 0 0.5rem;
        color: var(--sail-text-muted);
        font-size: 0.75rem;
        letter-spacing: 0.08em;
        text-transform: uppercase;
    }

/* --- Inventory (relocated from Home.razor.css .cc-stat-grid) -------------------------------------- */

.cc-stat-grid[b-e7zk420es4] {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0.4rem 0.75rem;
    margin: 0;
}

    .cc-stat-grid div[b-e7zk420es4] {
        display: flex;
        flex-direction: column;
    }

    .cc-stat-grid dt[b-e7zk420es4] {
        color: var(--sail-text-muted);
        font-size: 0.65rem;
        text-transform: uppercase;
    }

    /* Deliberately smaller/lighter than a decision's own action text (IMP-075): a summary count is
       reassurance, not a decision, and must never visually out-shout the one thing the player should act on. */
    .cc-stat-grid dd[b-e7zk420es4] {
        margin: 0;
        font-size: 0.85rem;
        font-weight: 500;
        color: var(--sail-text-muted);
    }

/* --- Character strip + popover (relocated verbatim from Home.razor.css IMP-091/093/101) ----------- */

.cc-character-strip[b-e7zk420es4] {
    padding: 1rem 1.25rem;
    /* IMP-093/IMP-101 §9: a deliberately quieter glass tier — lower background opacity and less blur
       than the shared --sail-glass-bg/blur tokens, with its inherited elevation shadow removed, so the
       roster reads as a quiet, flat reference surface. Border/radius are still inherited from .sail-glass. */
    background: rgba(21, 26, 33, 0.36);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    box-shadow: none;
}

.cc-character-strip__head[b-e7zk420es4] {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.5rem;
    margin-bottom: 0.75rem;
}

    .cc-character-strip__head h2[b-e7zk420es4] {
        margin: 0;
    }

.cc-character-strip__count[b-e7zk420es4] {
    color: var(--sail-text-muted);
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

/* Wide desktop: one horizontal row, portraits left-to-right in the read model's own existing order.
   Overflow stays inside this one strip (internal scroll), never a page-level horizontal scrollbar and
   never a tall multi-row "Character wall" at any width — the same internal-scroll-container precedent
   established by BUG-029/ENG-036 §6b. */
.cc-character-strip__row[b-e7zk420es4] {
    display: flex;
    gap: 0.6rem;
    overflow-x: auto;
    padding-bottom: 0.25rem;
}

/* A real, keyboard-operable <button> (IMP-091) — background/border reset so it still reads as a plain
   portrait tile, not a generic button, until hovered/focused. */
.cc-character-portrait[b-e7zk420es4] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.4rem;
    flex-shrink: 0;
    width: 108px;
    padding: 0.6rem 0.5rem;
    background: none;
    border: 1px solid transparent;
    border-radius: var(--sail-radius-control);
    color: inherit;
    font: inherit;
    text-align: center;
    cursor: pointer;
    transition: border-color var(--sail-transition-fast) var(--sail-ease),
                background var(--sail-transition-fast) var(--sail-ease);
}

    .cc-character-portrait:hover[b-e7zk420es4],
    .cc-character-portrait:focus-visible[b-e7zk420es4] {
        background: var(--sail-glass-bg);
        border-color: var(--sail-glass-border);
    }

    /* IMP-093: a real higher-resolution fetch (paired with the Medium EveVisualSize in Reference.razor),
       never an upscaled 32px source. */
    .cc-character-portrait .eve-visual[b-e7zk420es4] {
        width: 2.75rem;
        height: 2.75rem;
    }

.cc-character-portrait__name[b-e7zk420es4] {
    max-width: 100%;
    font-size: 0.8rem;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* IMP-093: Asset/Blueprint counts are metadata, not identity — kept clearly quieter than the Character
   name above it (smaller, lower opacity), never removed. */
.cc-character-portrait__meta[b-e7zk420es4] {
    max-width: 100%;
    color: var(--sail-text-muted);
    font-size: 0.6rem;
    opacity: 0.8;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* The compact anchored quick-popover (IMP-091) — deliberately plain .sail-glass and no modal-scale
   glow/box-shadow beyond the shared .sail-glass treatment. Position (top/left) is set by
   Reference.razor.js's own one-shot positionCharacterPopover — this stylesheet only defines the
   fallback centered position and the restrained entrance. */
.cc-character-popover[b-e7zk420es4] {
    position: fixed;
    z-index: var(--sail-z-toast);
    width: min(260px, calc(100vw - 1.5rem));
    padding: 0.85rem 1rem;
    border-radius: var(--sail-radius-control);
    animation: cc-character-popover-fade-in-b-e7zk420es4 var(--sail-transition-fast) var(--sail-ease) forwards;
}

@keyframes cc-character-popover-fade-in-b-e7zk420es4 {
    from { opacity: 0; }
    to { opacity: 1; }
}

/* Narrow-viewport fallback (IMP-091 explicit instruction) — precise anchoring becomes unstable on a
   small screen, so Reference.razor.js instead applies this plain centered position. */
.cc-character-popover--centered[b-e7zk420es4] {
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

.cc-character-popover__name[b-e7zk420es4] {
    margin: 0 0 0.3rem;
    font-size: 0.9rem;
    font-weight: 600;
}

.cc-character-popover__sync[b-e7zk420es4] {
    margin: 0 0 0.4rem;
    color: var(--sail-text-muted);
    font-size: 0.75rem;
}

.cc-character-popover__operations[b-e7zk420es4] {
    margin: 0;
    color: var(--sail-text-muted);
    font-size: 0.75rem;
    font-style: italic;
}
/* /Components/Pages/Settings.razor.rz.scp.css */
/* BUILD 1/4 -- Settings page (backlog #9, reports/DISC-settings-page-scope.md). Copied from
   GoalDetail.razor.css's own .goal-detail__threshold-* rules (Blazor CSS isolation scopes that file's
   classes to GoalDetail.razor only) so the per-control visual behavior is identical, never a shared
   reference across files. */

.settings__group[b-u8rj9nb8aj] {
    padding: 1.25rem 1.5rem;
    margin-bottom: 1.5rem;
    border-radius: 0.75rem;
}

.settings__group-title[b-u8rj9nb8aj] {
    margin: 0 0 0.5rem;
    font-size: 1.05rem;
}

.settings__group-body[b-u8rj9nb8aj] {
    margin: 0 0 1rem;
    font-size: 0.85rem;
    color: var(--sail-text-muted);
}

.settings__control[b-u8rj9nb8aj] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-bottom: 0.5rem;
}

.settings__label[b-u8rj9nb8aj] {
    font-size: 0.85rem;
    color: var(--sail-text-muted);
}

.settings__input[b-u8rj9nb8aj] {
    width: 5.5rem;
    padding: 0.3rem 0.5rem;
    border-radius: 0.4rem;
    border: 1px solid var(--sail-border);
    background: transparent;
    color: var(--sail-text);
}

.settings__input:disabled[b-u8rj9nb8aj] {
    opacity: 0.5;
    cursor: default;
}

.settings__unit[b-u8rj9nb8aj] {
    font-size: 0.85rem;
    color: var(--sail-text-muted);
}



.settings__busy[b-u8rj9nb8aj] {
    font-size: 0.8rem;
    color: var(--sail-text-muted);
}

/* Distinguishes "the rule's own hardcoded fallback is currently in effect" from a deliberately stored
   value -- the ticket's own explicit requirement: an unset control must never read as an empty box that
   looks like "off". */
.settings__default-note[b-u8rj9nb8aj] {
    font-size: 0.8rem;
    font-style: italic;
    color: var(--sail-text-muted);
}

.settings__error[b-u8rj9nb8aj] {
    margin: 0;
    font-size: 0.85rem;
    color: var(--sail-critical);
}

/* BUILD 2/4 (backlog #9): the reaction slot-optimize toggle -- copied from GoalDetail.razor.css's own
   .goal-detail__threshold-checkbox-label (same CSS-isolation reason as the header comment above). */
.settings__toggle-label[b-u8rj9nb8aj] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.85rem;
    color: var(--sail-text-muted);
    cursor: pointer;
}

/* BUILD 3/4 (backlog #9): the Blacklist group's category checkbox list -- the retired standalone
   /production-blacklist page reused Goals.razor.css's own .goals-list/.goal-card classes, but Blazor CSS
   isolation means those rules only ever matched Goals.razor's own rendered elements (the scope attribute
   never carried across components), so this list was effectively unstyled there beyond the shared
   sail-glass/cc- utility classes. New, real rules here rather than perpetuating that gap. */
.settings__blacklist-list[b-u8rj9nb8aj] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.settings__blacklist-item[b-u8rj9nb8aj] {
    padding: 0.6rem 0.9rem;
    border-radius: 0.6rem;
}

.settings__blacklist-label[b-u8rj9nb8aj] {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    font-size: 0.9rem;
    color: var(--sail-text);
    cursor: pointer;
}

/* 4b-1 (backlog #2): the import preview's diff tables/badges. */
.settings__import-preview[b-u8rj9nb8aj] {
    margin-top: 1rem;
}

.settings__import-preview-table[b-u8rj9nb8aj] {
    width: 100%;
    border-collapse: collapse;
    margin-bottom: 1rem;
    font-size: 0.85rem;
}

.settings__import-preview-table th[b-u8rj9nb8aj] {
    text-align: left;
    padding: 0.4rem 0.6rem;
    color: var(--sail-text-muted);
    font-weight: 600;
}

.settings__import-preview-table td[b-u8rj9nb8aj] {
    padding: 0.4rem 0.6rem;
    border-top: 1px solid var(--sail-border);
    color: var(--sail-text);
}

.settings__import-badge[b-u8rj9nb8aj] {
    display: inline-block;
    padding: 0.15rem 0.5rem;
    border-radius: 0.4rem;
    font-size: 0.75rem;
}

.settings__import-badge--same[b-u8rj9nb8aj],
.settings__import-badge--keptunchanged[b-u8rj9nb8aj] {
    color: var(--sail-text-muted);
}

.settings__import-badge--changed[b-u8rj9nb8aj],
.settings__import-badge--new[b-u8rj9nb8aj],
.settings__import-badge--update[b-u8rj9nb8aj] {
    color: var(--sail-accent);
}

.settings__import-badge--notinfile[b-u8rj9nb8aj] {
    font-style: italic;
    color: var(--sail-text-muted);
}

/* 4b-2 (backlog #2): the per-item apply outcome list -- best-effort, so both outcomes render side by side. */
.settings__import-apply-outcome[b-u8rj9nb8aj] {
    list-style: none;
    margin: 0.75rem 0 0;
    padding: 0;
    font-size: 0.85rem;
}

.settings__import-apply-item--ok[b-u8rj9nb8aj] {
    color: var(--sail-text);
}

.settings__import-apply-item--fail[b-u8rj9nb8aj] {
    color: var(--sail-critical);
}
/* /Components/Shared/CommandCenterDetailModal.razor.rz.scp.css */
/* ---------------------------------------------------------------------------------------------
   IMP-090/UX-005 §3.5: Command Center card-to-modal shell — backdrop, dialog surface, and the
   source-aware open/close transform. The transform itself is applied via inline style/transform by
   Home.razor.js (a one-shot FLIP: capture source rect, seed the surface's transform, then clear it so
   this stylesheet's own transition animates it back to identity) — this file only defines the transition
   and the restrained fallback used whenever source geometry is unavailable (see openCardModal/
   closeCardModal). Reduced motion needs no separate rule here: app.css's existing global
   prefers-reduced-motion collapse already drives every transition-duration below to ~0.
   --------------------------------------------------------------------------------------------- */

.cc-modal-backdrop[b-g2bj2541sr] {
    position: fixed;
    inset: 0;
    z-index: var(--sail-z-modal);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--sail-space-4);
    background: rgba(4, 10, 18, 0.55);
    backdrop-filter: blur(3px);
}

.cc-modal-surface[b-g2bj2541sr] {
    width: min(720px, 100%);
    max-height: 85vh;
    overflow-y: auto;
    padding: var(--sail-space-4) var(--sail-space-5);
    border-radius: var(--sail-radius-panel);
    /* The FLIP transform's own transform-origin — matches the translate math in Home.razor.js, which
       computes the offset between the surface's own center and the source card's center. */
    transform-origin: center center;
    transition: transform var(--sail-transition-base) var(--sail-ease),
                opacity var(--sail-transition-base) var(--sail-ease);
}

/* The restrained fade/scale fallback (IMP-090 explicit requirement) used only when the source overview
   card's geometry cannot be resolved (viewport/layout change) — never a thrown error, never a
   still-locked page. Toggled as a class rather than inline style so it composes cleanly whether the
   fallback applies on open, on close, or (defensively) both. */
.cc-modal-surface--fallback-enter[b-g2bj2541sr] {
    opacity: 0;
    transform: scale(0.96);
}

.cc-modal-surface__head[b-g2bj2541sr] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1rem;
}

.cc-modal-surface__title[b-g2bj2541sr] {
    margin: 0;
    font-size: 1.1rem;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--sail-text);
}

.cc-modal-surface__close[b-g2bj2541sr] {
    flex-shrink: 0;
    background: none;
    border: 1px solid var(--sail-glass-border);
    border-radius: 50%;
    width: 2rem;
    height: 2rem;
    color: var(--sail-text-muted);
    font-size: 0.9rem;
    line-height: 1;
    cursor: pointer;
}

    .cc-modal-surface__close:hover[b-g2bj2541sr] {
        color: var(--sail-text);
        border-color: var(--sail-text-muted);
    }

@media (max-width: 640px) {
    .cc-modal-surface[b-g2bj2541sr] {
        max-height: 90vh;
    }
}
/* /Components/Shared/EveVisual.razor.rz.scp.css */
.eve-visual[b-o2bd4vhyiw] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    overflow: hidden;
    background: var(--sail-bg-elevated);
}

.eve-visual__image[b-o2bd4vhyiw],
.eve-visual__fallback[b-o2bd4vhyiw] {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* The Sail fallback mark never fills the frame edge-to-edge like a real Item/Character image would —
   a restrained abstract glyph, deliberately smaller than its own frame, never mistaken for a real,
   resolved EVE visual. */
.eve-visual__fallback[b-o2bd4vhyiw] {
    object-fit: contain;
    padding: 18%;
    opacity: 0.55;
}

/* Size hook (IMP-087: "explicit size variant or CSS sizing hook") — both the EveVisualSize parameter
   and these CSS classes exist; a consumer that needs a one-off size can also just override width/height
   directly on the host element via its own scoped CSS without touching this component. */
.eve-visual--small[b-o2bd4vhyiw] { width: 1.5rem; height: 1.5rem; }
.eve-visual--medium[b-o2bd4vhyiw] { width: 2.25rem; height: 2.25rem; }
/* EveVisualSize.Large requests a 128px source from the Image Server (EveVisualSize.cs), so this 5rem
   (80px) frame has no upscaling — no new EveVisualSize member or second resolution path is needed.
   Consumer note (corrected — NEXT, the original Large consumer, was retired): the Command Center Work
   Queue card and the production-tree header are the Large consumers today, and they override this display
   size up to 6rem/96px via their own scoped CSS (Home.razor.css / OperationalWorkspace.razor.css), leaving
   this global default at 80px for any future full-size use. */
.eve-visual--large[b-o2bd4vhyiw] { width: 5rem; height: 5rem; }

/* Item: clean/freestanding — a plain soft-radius tile, matching the rest of the shell's inner-control radius. */
.eve-visual--item[b-o2bd4vhyiw] {
    border-radius: var(--sail-radius-control);
    border: 1px solid var(--sail-border);
}

/* Character: portrait framing — circular, distinct from an Item's own rectangular tile. */
.eve-visual--character[b-o2bd4vhyiw] {
    border-radius: 50%;
    border: 1px solid var(--sail-border);
}
/* /Components/Shared/ProductionTreeView.razor.rz.scp.css */
/* ENG tree vertical-table redesign — a Ravworks-style vertical indented table, scoped to ProductionTreeView.
   The component is recursive (same component type at every level), so this scope id is shared across depths and
   these selectors apply at every level. All colour comes from the --sail-* design tokens (no hardcoded hex), so
   the four states stay distinguishable under whatever values the theme defines.

   Layout: a div-grid "table" (NOT <table>/<tr>, so the native <details> collapse survives). Every row shares one
   grid template, and only the NAME cell is indented (by --pt-depth), so the number columns align across all
   depths. A node's children render as rows BELOW it (the <details> body), indented one level deeper. */

/* --- Vertical stacking: block containers, full width (no horizontal offset) ---------------------------- */

.pt-details[b-5kv933d9y9] {
    display: block;
}

.pt-children[b-5kv933d9y9] {
    display: block;
}

/* --- Table wrapper + column header (emitted ONCE by the root instance, Depth 0) ------------------------ */

.pt-table[b-5kv933d9y9] {
    display: block;
}

/* Shares the .pt-row grid so the labels line up exactly over the number columns; styled as a quiet header
   (muted, uppercase, a hairline bottom border), not a data row. */
.pt-header[b-5kv933d9y9] {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 5rem 5rem 5rem;
    align-items: center;
    padding: 2px 0;
    border-bottom: 1px solid var(--sail-border);
    margin-bottom: var(--sail-space-1);
}
.pt-col--head[b-5kv933d9y9] {
    color: var(--sail-text-muted);
    font-size: var(--sail-text-2xs);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-weight: 500;
}

/* We render our own row-start ▸/▾ toggle, so drop the native disclosure marker. */
.pt-row--branch[b-5kv933d9y9] {
    list-style: none;
    cursor: pointer;
}
.pt-row--branch[b-5kv933d9y9]::-webkit-details-marker {
    display: none;
}
.pt-row--branch[b-5kv933d9y9]::marker {
    content: "";
}

/* --- The row: [name cell (indented)] [need] [have] [short] --------------------------------------------- */

.pt-row[b-5kv933d9y9] {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 5rem 5rem 5rem;
    align-items: center;
    padding: var(--sail-space-1) 0;     /* a little vertical rhythm around the 64px icon */
    border-radius: var(--sail-radius-control);
    font-family: var(--sail-font-sans);
}

.pt-row:hover[b-5kv933d9y9] {
    background: var(--sail-bg-card);
}

.pt-row__name[b-5kv933d9y9] {
    display: flex;
    align-items: center;
    gap: var(--sail-space-2);
    min-width: 0;
    padding-left: calc(var(--pt-depth) * 1.5rem);   /* indent ONLY the name cell → number columns stay aligned */
}

.pt-row__guide[b-5kv933d9y9] {
    color: var(--sail-text-muted);
    flex: none;
}

.pt-row__label[b-5kv933d9y9] {
    color: var(--sail-text);
    font-size: var(--sail-text-sm);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* --- Row-start collapse toggle (▸ collapsed / ▾ open); a leaf has a same-width spacer ------------------- */

.pt-row__toggle[b-5kv933d9y9] {
    flex: none;
    width: 1em;
    text-align: center;
    color: var(--sail-text-muted);
    font-size: var(--sail-text-xs);
}
.pt-row__toggle[b-5kv933d9y9]::before {
    content: "▸";
}
.pt-details[open] > summary .pt-row__toggle[b-5kv933d9y9]::before {
    content: "▾";
}
.pt-row__toggle--leaf[b-5kv933d9y9]::before {
    content: "";                        /* no glyph, but keeps the icon/name aligned with branch rows */
}

/* --- Number columns: tabular, right-aligned, aligned across depths ------------------------------------- */

.pt-col[b-5kv933d9y9] {
    text-align: right;
    font-variant-numeric: tabular-nums;
    padding: 0 var(--sail-space-2);
    font-size: var(--sail-text-sm);
    color: var(--sail-text-muted);
}

/* "short" only ever carries a number when MissingQuantity > 0 (the cell is empty otherwise), so this danger
   colour only shows on a genuine shortfall. */
.pt-col--short[b-5kv933d9y9] {
    color: var(--sail-critical);
    font-weight: 500;
}

/* --- The icon inside its CATEGORY frame (channel 1 of 2: category here, state on the row) -------------- */

.pt-node[b-5kv933d9y9] {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    padding: 2px;
    border: 2px solid var(--sail-neutral);
    border-radius: var(--sail-radius-control);
    background: var(--sail-bg-card);
    transition: border-color var(--sail-transition-fast);
}

.pt-node .eve-visual[b-5kv933d9y9] {
    width: 64px;
    height: 64px;
    display: block;
}
.pt-node .eve-visual__image[b-5kv933d9y9],
.pt-node .eve-visual__fallback[b-5kv933d9y9] {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

/* Category frame colour (keyed on Depth + NodeKind + IsReaction + IsPlanetaryIndustry, NOT on blocked/
   satisfied state) — end product = red, manufacturing buildable = amber, reaction buildable = teal, PI
   commodity leaf = dark orange, raw "acquire, don't build" leaf = green. All from design tokens (no hex).
   Reaction teal and PI dark-orange stay dormant (every node false) until a snapshot carrying the respective
   SDE discriminator is ingested. */
.pt-node--root[b-5kv933d9y9] {
    border-color: var(--sail-critical);
}
.pt-node--buildable[b-5kv933d9y9] {
    border-color: var(--sail-caution);
}
.pt-node--reaction[b-5kv933d9y9] {
    border-color: var(--sail-teal);
}
.pt-node--pi[b-5kv933d9y9] {
    border-color: var(--sail-pi);
}
.pt-node--leaf[b-5kv933d9y9] {
    border-color: var(--sail-raw);
}

/* --- Row state treatment (channel 2 of 2: the whole row carries blocked/satisfied, never the frame) --- */

/* Blocked rows have NO background tint — the red short-column number already signals blocked, and a red
   row background on top of it made the tree noisy. The blocked-row hook is still produced by RowStateClass
   as a semantic marker; it just carries no styling rule now. */

/* Satisfied row is signalled ONLY by the success check trailing the "have" column — the green ✓ + the empty
   short column already convey "fully in stock", so the row renders at normal brightness (the dim was removed;
   it just made these rows hard to read). The .pt-row--satisfied hook is still produced by RowStateClass and is
   required here as the ✓ selector's anchor. */
.pt-row--satisfied .pt-col--have[b-5kv933d9y9]::after {
    content: " ✓";
    color: var(--sail-positive);
    font-weight: 500;
}

/* --- Cycle-cut badge (kept) ---------------------------------------------------------------------------- */

.pt-node__cycle[b-5kv933d9y9] {
    position: absolute;
    top: -6px;
    left: -6px;
    font-size: var(--sail-text-2xs);
    color: var(--sail-caution);
    background: var(--sail-bg-elevated);
    border: 1px solid var(--sail-caution);
    border-radius: var(--sail-radius-pill);
    padding: 0 var(--sail-space-1);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
