/* ===============================================================================================
   ENG-font-adoption: the three ratified families, vendored under wwwroot/fonts and served from this
   origin. No hotlinking — SailBrandMark.razor.css's IMP-087 constraint bars it, and there is no CSP
   here that would catch a third-party font request.

   All three are SIL Open Font License 1.1. Each family's own OFL.txt, taken from the same distribution
   as its font files, ships beside them — OFL 1.1 condition 2 requires the copyright notice and licence
   travel with the Font Software, so those files are part of the licence compliance, not documentation.

   Weights are the ones actually used, established from the stylesheets rather than shipped wholesale:
   400 (body default), 500, 600, 700. Work Sans is a variable font, so one file covers 400-700; Poppins
   is static on this distribution, so it needs one file per weight. Latin subset only.

   Saira Condensed is the exception, deliberately: its copyright line reserves the font name "Saira",
   and OFL 1.1 condition 3 forbids a Modified Version from using a Reserved Font Name. Subsetting is
   modification, so it ships as the UNMODIFIED upstream SairaCondensed-SemiBold.ttf (96,028 bytes,
   byte-identical to the google/fonts release) rather than a ~9 KB latin woff2 slice. Poppins and Work
   Sans carry no Reserved Font Name clause at all, so their subsetting is unconstrained. That single
   clause is why one word costs more than either whole body family — see the report.

   font-display: swap everywhere: text paints immediately in the fallback and reflows when the font
   arrives. Never blocking — a font that fails to load must never cost a reader the page.
   =============================================================================================== */

@font-face {
    font-family: "Poppins";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("/fonts/poppins/poppins-400.woff2") format("woff2");
}

@font-face {
    font-family: "Poppins";
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url("/fonts/poppins/poppins-500.woff2") format("woff2");
}

@font-face {
    font-family: "Poppins";
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url("/fonts/poppins/poppins-600.woff2") format("woff2");
}

@font-face {
    font-family: "Poppins";
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url("/fonts/poppins/poppins-700.woff2") format("woff2");
}

/* Variable: one file answers every weight in the 400-700 range this app uses. */
@font-face {
    font-family: "Work Sans";
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url("/fonts/work-sans/work-sans-variable.woff2") format("woff2");
}

/* Unmodified upstream TTF — see the Reserved Font Name note above. One weight, one size, one word. */
@font-face {
    font-family: "Saira Condensed";
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url("/fonts/saira-condensed/SairaCondensed-SemiBold.ttf") format("truetype");
}

:root {
    /* IMP-071: a dark, desktop-first application palette, shared by the app shell and the Command
       Center screen's own scoped stylesheet — custom properties inherit through Blazor's CSS isolation
       even though selectors don't, so Home.razor.css reads these directly. IMP-086 leaves every one of
       these five semantic colors and the three existing background/border tokens at their exact prior
       values — Home.razor.css hardcodes rgba() overlays derived from them (e.g. badge fills), so
       changing a value here without auditing every derived rgba() would desync the two. New tokens are
       added alongside instead. */
    --sail-bg: #0d1117;
    --sail-bg-elevated: #151a21;
    --sail-bg-card: #1a2029;
    --sail-border: #2a323d;
    --sail-text: #e6e9ef;
    --sail-text-muted: #8b93a1;
    --sail-positive: #3ddc97;
    --sail-caution: #e8b339;
    --sail-critical: #ef5350;
    --sail-neutral: #7c8593;
    --sail-accent: #4fb3ff;
    --sail-teal: #2dd4bf;
    /* Production-tree leaf-frame categories (DISC-pi-dark-orange-scope). --sail-raw is a tree-specific darker
       green for raw "acquire, don't build" leaves — deliberately NOT --sail-positive (which the satisfied ✓
       and several other surfaces share), so darkening the raw leaf never touches them. --sail-pi is a dark
       orange for Planetary Industry commodities, distinct from --sail-caution (buildable amber) and
       --sail-teal (reaction). */
    --sail-raw: #4d7c2a;
    --sail-pi: #c2410c;

    /* IMP-086/UX-005 §1: the ratified five-role token set above already covers every semantic color
       requirement ("no new semantic roles are required" — UX-005 §1) and --sail-text/--sail-text-muted
       already cover primary/secondary text. What was genuinely missing is below: glass/background-layer,
       spacing, radius, type, elevation, glow, motion, and z-index tokens for the new shell. */

    /* IMP-087/sail-brand-spec.md §4: the exact supplied wordmark-on-dark color — distinct from the more
       general --sail-text so the wordmark can be tuned independently of body text without the two
       silently drifting apart from an unrelated future body-text change. */
    --sail-wordmark-color: #e8eef4;

    /* Background layers (glass/ambient) */
    --sail-bg-void: #05070a;
    --sail-glass-bg: rgba(21, 26, 33, 0.62);
    --sail-glass-bg-strong: rgba(21, 26, 33, 0.82);
    --sail-glass-blur: 20px;
    --sail-glass-border: rgba(230, 233, 239, 0.08);
    --sail-glass-border-strong: rgba(230, 233, 239, 0.16);

    /* IMP-095: a distinct, more-translucent glass tier for the Sail Shell (sidebar + upper header) —
       deliberately NOT --sail-glass-bg (62% opaque navy). --sail-glass-bg was tuned for Command Center
       content surfaces sitting over open scene; applied to the full-height sidebar it compounded with
       the artwork's own dark left edge into a near-solid wall (IMP-095 visual finding).
       IMP-095's first attempt made the tint color itself near-black (rgba(7,9,13,0.4)) — pixel-sampled
       verification against the real running app showed this made the Sidebar *darker* than before
       (avg luminance 22.4 -> 13.8), not lighter: with an inherently dark backdrop at that screen
       column, a darker tint's own alpha-weighted contribution dominates the small extra backdrop
       weight a lower alpha buys, net-darkening the result. The fix is a much lower alpha at the
       *same* hue as the content tier (not darker), so whatever dim light/gradient the backdrop does
       carry (the veil's own base gradient, the amber utility-light glow mapped to this column) is
       revealed rather than crushed — verified to raise, not lower, sampled Sidebar luminance. */
    --sail-shell-glass-bg: rgba(21, 26, 33, 0.3);
    --sail-shell-glass-blur: 20px;

    /* IMP-096: a slightly stronger blur for the Sidebar specifically than the shared shell-glass tier
       above (which Header also uses) — the ticket asks for the floating Sidebar panel to read as
       "slightly stronger blur than content panels," but Header must not change in this ticket, so this
       is its own token rather than raising --sail-shell-glass-blur (which both surfaces share). */
    --sail-sidebar-glass-blur: 24px;

    /* IMP-096: the floating-panel inset — how far the Sidebar sits from the viewport edges (top/
       bottom/left) and from the main content column (right), so it reads as a detached premium glass
       object rather than a flush application wall. Within the ratified 16-20px range. IMP-097 reused
       this same token for the Top Shell's own floating insets (one Shell language, not two
       independently-tuned ones); IMP-098 removed the Top Shell entirely, so this token is Sidebar-only
       again, but is kept as its own named token rather than inlined — the Sidebar's floating math
       (MainLayout.razor.css) and Command Center's own restored top breathing room both still derive
       from it. */
    --sail-shell-float-inset: 18px;

    /* IMP-097: "One Shell language" — a crisper border and a richer, reflective elevation for Sail
       Shell surfaces (via .sail-glass--shell below), distinct from plain content panels'
       --sail-glass-border/--sail-shadow-md. The border is a touch stronger than content's 0.08 (edge
       definition befitting a "premium glass cockpit panel," never a bright/neon frame). The elevation
       layers a thin inset top highlight (a glass edge catching light) over a thin inset bottom shadow
       (a bevel/thickness cue) over a slightly richer outer drop shadow than --sail-shadow-md — restrained,
       never an obvious glow. Originally shared by the Sidebar and the Top Shell; IMP-098 removed the
       Top Shell, so only the Sidebar uses this today — kept as shared/named tokens (not inlined) since
       they represent the Shell's own design language, not a Sidebar-specific one, for any future Shell
       surface to reuse. */
    --sail-shell-glass-border: rgba(230, 233, 239, 0.14);
    --sail-shell-elevation:
        inset 0 1px 0 rgba(255, 255, 255, 0.07),
        inset 0 -1px 0 rgba(0, 0, 0, 0.2),
        0 12px 32px rgba(0, 0, 0, 0.5);

    /* IMP-100: the Sidebar's own Steel-Blue-only premium glow, matching the ratified UX draft — IMP-099's
       two-tone cyan/amber pair is retired entirely (the draft explicitly forbids any non-Steel-Blue
       color on the Sidebar edge; the logo's own separate semantic-state tint is untouched by this).
       Light, not fill: every value below is a box-shadow/border-color, never a change to
       --sail-shell-glass-bg's own alpha, so the panel itself never gets brighter/more opaque. Four
       layers reusing only --sail-accent's own rgb(79, 179, 255): a crisp border-color for a defined
       edge, an inner rim reflection, a close/medium glow for immediate visibility at 1600px, and a
       broad low-opacity bloom that softly fades into the ambient world — restrained (no animation, no
       per-nav-item glow, no blown-out white) despite being significantly more prominent than IMP-099's
       version. */
    --sail-sidebar-border-glow: rgba(79, 179, 255, 0.55);
    --sail-sidebar-glow-inner: inset 0 0 0 1px rgba(79, 179, 255, 0.22);
    --sail-sidebar-glow-crisp: 0 0 14px 0px rgba(79, 179, 255, 0.45);
    --sail-sidebar-glow-medium: 0 0 34px 2px rgba(79, 179, 255, 0.28);
    --sail-sidebar-glow-broad: 0 0 70px 6px rgba(79, 179, 255, 0.14);

    /* IMP-086: local, replaceable ambient background asset slot (UX-005 §8 gap 6 — no real art exists
       yet). Defaults to "none" so the gradient-only fallback in .ambient-environment shows through;
       supplying the real asset later is a one-line override of this custom property (or a per-area
       override via an .ambient-environment--* modifier), never a shell restructuring. */
    --sail-ambient-image: none;

    /* Radii — large soft panel radius vs. a smaller inner-control radius (UX-005 §1 "large soft radii") */
    --sail-radius-panel: 1.25rem;
    --sail-radius-control: 0.625rem;
    --sail-radius-pill: 999px;

    /* Spacing scale */
    --sail-space-1: 0.25rem;
    --sail-space-2: 0.5rem;
    --sail-space-3: 0.75rem;
    --sail-space-4: 1rem;
    --sail-space-5: 1.5rem;
    --sail-space-6: 2rem;
    --sail-space-7: 3rem;
    --sail-space-8: 4rem;

    /* Hybrid typography, as ratified in wwwroot/brand/sail-brand-spec.md §5 and UX-005 §1: Poppins for
       titles, labels, nav and system vocabulary; Work Sans for decisions, names and prose. Both are
       vendored under wwwroot/fonts (see the @font-face block below) — never hotlinked, which
       SailBrandMark.razor.css's own IMP-087 constraint bars and which no CSP would catch.

       Each chain keeps a system fallback, so a failed font load degrades to what shipped before this
       ticket rather than to an unstyled default. Poppins is geometric where the previous stack was
       condensed — a trade-off recorded and accepted in brand spec §5 (wider glyphs truncate earlier in
       narrow contexts); it is not a defect and is not fixed here.

       Caps and tracking are deliberately NOT bundled into these tokens (see .sail-font-technical /
       .sail-label below) — that split shipped separately so Poppins' wider uppercase could not land on
       the six prose sites that should never have been uppercased. */
    --sail-font-technical: "Poppins", "Segoe UI", "Helvetica Neue", Helvetica, Arial, sans-serif;
    --sail-font-sans: "Work Sans", "Segoe UI", "Helvetica Neue", Helvetica, Arial, sans-serif;

    /* The wordmark's own family — brand spec §5 ratifies Saira Condensed Weight 600 for it specifically,
       distinct from the heading font, exactly as --sail-wordmark-color is distinct from --sail-text.
       Its own token (rather than the wordmark rule reading --sail-font-technical) also keeps the
       ENG-technical-font-class-split guard meaningful: that guard bars scoped stylesheets from reaching
       for the technical token, and this is a genuinely different font, not a way around the guard. */
    --sail-font-wordmark: "Saira Condensed", "Poppins", "Segoe UI", Helvetica, Arial, sans-serif;

    --sail-text-2xs: 0.6875rem;
    --sail-text-xs: 0.75rem;
    --sail-text-sm: 0.8125rem;
    --sail-text-base: 0.9375rem;
    --sail-text-md: 1.05rem;
    --sail-text-lg: 1.25rem;
    --sail-text-xl: 1.6rem;
    --sail-text-2xl: 2.1rem;

    /* Elevation */
    --sail-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.35);
    --sail-shadow-md: 0 8px 24px rgba(0, 0, 0, 0.45);
    --sail-shadow-lg: 0 20px 60px rgba(0, 0, 0, 0.55);

    /* Semantic glow — reuses the same five-role palette above, never a new color */
    --sail-glow-positive: 0 0 0 1px rgba(61, 220, 151, 0.35), 0 0 24px rgba(61, 220, 151, 0.25);
    --sail-glow-caution: 0 0 0 1px rgba(232, 179, 57, 0.35), 0 0 24px rgba(232, 179, 57, 0.25);
    --sail-glow-critical: 0 0 0 1px rgba(239, 83, 80, 0.35), 0 0 24px rgba(239, 83, 80, 0.25);
    --sail-glow-accent: 0 0 0 1px rgba(79, 179, 255, 0.35), 0 0 24px rgba(79, 179, 255, 0.25);

    /* IMP-092: the transient "something changed this refresh" treatment — deliberately its own
       blue-white token, never reused from the Ready/Caution/Blocked semantic-status glows above, since
       it must never itself imply better/worse/blocked. A static, always-on edge illumination (never a
       :hover/:focus-visible-only trigger like the glows above), so it stays readable without motion. */
    --sail-glow-changed: 0 0 0 1px rgba(214, 234, 255, 0.55), 0 0 20px rgba(79, 179, 255, 0.22);

    /* Transitions / motion durations */
    --sail-transition-fast: 120ms;
    --sail-transition-base: 220ms;
    --sail-transition-slow: 420ms;
    --sail-ease: cubic-bezier(0.2, 0.7, 0.2, 1);
    --sail-motion-ambient-pulse: 9s;
    --sail-motion-ambient-haze: 75s;
    --sail-motion-ambient-flicker: 5.5s;

    /* IMP-094: motion tokens for the ratified Command Center scene composition — a slow cyan
       illumination breathing cycle, three distinct utility-light flicker timings (asynchronous
       zones borrow these three, never one shared animation shifted by delay alone), one distant
       traversal, and one near-imperceptible structural shadow sweep. */
    --sail-motion-ambient-cyan-breathe: 15s;
    --sail-motion-ambient-utility-a: 18s;
    --sail-motion-ambient-utility-b: 23s;
    --sail-motion-ambient-utility-c: 27s;
    --sail-motion-ambient-distant-light: 30s;
    --sail-motion-ambient-shadow: 95s;

    /* IMP-099: the second distant light's own cycle (§6 "tiny moving lights deep inside the station")
       — deliberately a different duration from the first (30s) so the two traversals never fall into
       a visible synchronized rhythm. */
    --sail-motion-ambient-distant-light-2: 42s;

    /* IMP-095: two "hero" utility-light zones (of the existing seven) recalibrated for conscious
       perceptibility — IMP-094's a/b/c profiles were real but their brief (sub-second) dips were
       invisible in peripheral vision over ~60s of normal observation. The other five zones keep their
       existing a/b/c timing/profiles unchanged (motion hierarchy: most zones stay subtle; exactly two
       are deliberately more active — see sail-utility-flicker-hero-a/-b below). */
    --sail-motion-ambient-utility-hero-a: 24s;
    --sail-motion-ambient-utility-hero-b: 26s;

    /* Z-index layers */
    --sail-z-ambient: 0;
    --sail-z-base: 1;
    --sail-z-sidebar: 20;
    --sail-z-overlay: 40;
    --sail-z-modal: 50;
    --sail-z-toast: 60;
}

html, body {
    font-family: var(--sail-font-sans);
    background: var(--sail-bg);
    color: var(--sail-text);
}

a, .btn-link {
    color: var(--sail-accent);
}

/* ---------------------------------------------------------------------------------------------
   IMP-086: reusable glass-surface and typography utility classes for the new shell. Deliberately
   opt-in classes, not a blanket h1-h6/body selector rewrite — Home.razor.css's own existing rules
   (e.g. .cc's monospace technical font, .cc-card__head h3's readable-sans Goal name) are untouched
   per this ticket's "do not yet rebuild the Command Center content hierarchy" boundary. The
   Command Center composition ticket adopts these classes deliberately, file by file.
   --------------------------------------------------------------------------------------------- */

.sail-glass {
    background: var(--sail-glass-bg);
    -webkit-backdrop-filter: blur(var(--sail-glass-blur));
    backdrop-filter: blur(var(--sail-glass-blur));
    border: 1px solid var(--sail-glass-border);
    border-radius: var(--sail-radius-panel);
    box-shadow: var(--sail-shadow-md);
}

.sail-glass--strong {
    background: var(--sail-glass-bg-strong);
    border-color: var(--sail-glass-border-strong);
}

/* IMP-095/097/098: the Sail Shell's own glass tier — see --sail-shell-glass-bg's own doc comment above
   for why this is a distinct, lighter/more-translucent tier rather than reusing .sail-glass/
   .sail-glass--strong verbatim. Combined with .sail-glass on the same element (radius is still
   inherited from it) — this modifier overrides background/blur, and (IMP-097) border-color and
   box-shadow, for the Shell's own "premium glass cockpit" border/elevation language. Originally shared
   by the Sidebar and the Top Shell (IMP-097's "one Shell language" requirement); IMP-098 removed the
   Top Shell, so only .shell-sidebar uses this class today. The Sidebar's own extra touches (stronger
   blur/border, reflection gradient) are layered on top via its own scoped rule in
   MainLayout.razor.css — this class remains the shared base any future Shell surface would reuse. */
.sail-glass--shell {
    background: var(--sail-shell-glass-bg);
    -webkit-backdrop-filter: blur(var(--sail-shell-glass-blur));
    backdrop-filter: blur(var(--sail-shell-glass-blur));
    border-color: var(--sail-shell-glass-border);
    box-shadow: var(--sail-shell-elevation);
}

/* ENG-technical-font-class-split: the technical font, the uppercasing and the tracking are three
   separate decisions and are no longer one class.

   .sail-font-technical previously bundled all three. That was wrong at six sites rendering prose,
   parentheticals or unit abbreviations ("(built, not bought)" -> "(BUILT, NOT BOUGHT)", "2d 5h" ->
   "2D 5H"), and two further sites had already routed around it by re-declaring the token in their own
   scoped stylesheet — the wordmark, whose brand spec mandates Sentence Case, and the "Analyzing
   Workspace…" overlay statement. The need arose twice and was solved by duplication twice.

   So: this class is now exactly what its name says, and the label treatment below is opted into. A site
   wanting the technical font without caps takes this class rather than re-declaring the token — an audit
   (TechnicalFontClassAuditTests) fails the build if a scoped stylesheet reaches for the token again. */
.sail-font-technical {
    font-family: var(--sail-font-technical);
}

/* The label treatment — technical font, uppercased, tracked. Deliberately self-contained rather than a
   caps-only modifier composed onto .sail-font-technical: every site that wants caps here also wants this
   font, so one class is one decision, and the 37 sites carrying it swap one class name for another with
   no change in rendering. Applied to short fixed labels only — nav group headings, page/section titles,
   column and status labels, kind chips. Never to a sentence, a parenthetical, or a formatted value. */
.sail-label {
    font-family: var(--sail-font-technical);
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.sail-font-sans {
    font-family: var(--sail-font-sans);
}

/* ---------------------------------------------------------------------------------------------
   IMP-086: interaction foundation — strong hover lift, semantic glow, active/pressed, disabled/
   processing, and focus-visible. Shared classes/tokens only; no Goal modal or card-to-modal
   transform is implemented yet (that is its own later ticket per UX-005 §9).
   --------------------------------------------------------------------------------------------- */

.sail-interactive {
    transition: transform var(--sail-transition-base) var(--sail-ease),
                box-shadow var(--sail-transition-base) var(--sail-ease),
                border-color var(--sail-transition-base) var(--sail-ease);
}

.sail-interactive:hover {
    transform: translateY(-2px);
    border-color: var(--sail-glass-border-strong);
    box-shadow: var(--sail-shadow-lg);
}

.sail-interactive:active {
    transform: translateY(0);
    box-shadow: var(--sail-shadow-sm);
}

.sail-glow-positive:hover, .sail-glow-positive:focus-visible { box-shadow: var(--sail-glow-positive); }
.sail-glow-caution:hover, .sail-glow-caution:focus-visible { box-shadow: var(--sail-glow-caution); }
.sail-glow-critical:hover, .sail-glow-critical:focus-visible { box-shadow: var(--sail-glow-critical); }
.sail-glow-accent:hover, .sail-glow-accent:focus-visible { box-shadow: var(--sail-glow-accent); }

/* aria-busy is the semantic, screen-reader-visible signal; .sail-is-processing is the paired visual
   treatment — never color alone (opacity + disabled pointer events + the aria-busy state itself). */
.sail-is-processing, [aria-busy="true"] {
    opacity: 0.75;
    pointer-events: none;
}

[disabled],
.sail-is-disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* Keyboard-visible focus (accessibility): only :focus-visible, never plain :focus, so mouse clicks
   never show the ring — global, so every future overlay/modal z-index layer inherits it for free. */
:focus-visible {
    outline: 2px solid var(--sail-accent);
    outline-offset: 2px;
    border-radius: var(--sail-radius-control);
}

/* ---------------------------------------------------------------------------------------------
   ENG-button-styling: the shared action vocabulary — two weights, promoted here verbatim from
   Home.razor.css.

   They were always intended to be shared (Goals.razor.css's own head calls them "the shared
   cc-header/cc-banner/cc-loading/cc-link/cc-refresh vocabulary"), but a .razor.css cannot share
   anything: Blazor CSS isolation rewrites each of its rules with that one component's [b-xxxxx]
   attribute, so every borrowing site outside Home rendered as browser-default chrome. This sheet is
   the only genuinely global one — the same mechanism sail-glass/sail-interactive already use, and the
   trap GoalDetail.razor.css documents at its own head.

   Two weights, both already in use; this file does not introduce a third. The per-page secondary
   (.goal-card__retire / .hub-card__edit — transparent, bordered, muted) and destructive-commit
   (.goal-card__retire-confirm — solid --sail-critical) treatments stay scoped where they are.
   --------------------------------------------------------------------------------------------- */

/* ===============================================================================================
   ENG-goals-landing-page: the shared PAGE HEADER, promoted here verbatim from Home.razor.css for
   exactly the reason .cc-link/.cc-refresh were promoted above.

   Goals.razor, Policies.razor and Hubs.razor have always WRITTEN this markup — `<header class=
   "cc-header sail-glass">`, `.cc-header__identity`, `.cc-header__workspace`, `.cc-header__actions` —
   but the rules lived only in Home.razor.css, so Blazor CSS isolation stamped them with Home's own
   [b-xxxxx] and none of the three received a single declaration. That is why /goals rendered an
   oversized browser-default `<h1>` with its actions stacked underneath at the left edge: not a
   different design, an unstyled one. Identical root cause to the button defect, one sheet further on.

   Home.razor.css keeps exactly one declaration of its own (`margin-bottom: var(--cc-band-gap)`) —
   that token is Command Center band geometry, not header identity, and no other page has it. Every
   other declaration is here, unchanged, so the Command Center's header is byte-for-byte the same
   treatment it was before.

   Reference.razor.css used to carry its own earlier fork of these rules, left in place because removing
   it was a separate, verifiable change. ENG-reference-page-removal deleted that page and its stylesheet
   outright, so no scoped fork of this header survives anywhere.
   =============================================================================================== */

.cc-header {
    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 {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

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

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

/* The one concise current-state statement (UX-005 §3.1) — <strong> is the sentence's own single
   decision-relevant token (a count, or the term itself when no count exists), per UX-005's
   quantity-hierarchy convention: strong typographic emphasis on the one number that matters,
   everything else quiet. */
.cc-header__statement {
    margin: 0.3rem 0 0;
    color: var(--sail-text);
    font-family: var(--sail-font-sans);
    font-size: var(--sail-text-md);
}

    .cc-header__statement strong {
        color: var(--sail-accent);
        font-weight: 700;
    }

.cc-freshness {
    margin: 0.15rem 0 0;
    color: var(--sail-text-muted);
    font-size: 0.75rem;
}

/* Page-level actions live in the header, right-aligned — .cc-header's own space-between puts this
   block at the far edge opposite the identity. A page that stacks its actions beneath the title has
   not adopted this header; it has only borrowed the class name. */
.cc-header__actions {
    display: flex;
    align-items: center;
    gap: 0.85rem;
}

/* ===============================================================================================
   ENG-settings-page-layout: the shared PAGE COLUMN, promoted here for the third time and the same
   reason as the two blocks above it.

   `.goals-page` is the construction every supporting surface writes: a centred 60rem column whose
   flex `gap` IS the band rhythm between the header card and the sections beneath it. Goals.razor,
   Hubs.razor, Policies.razor AND Settings.razor all write `<div class="goals-page">` — but the rule
   was declared three times, once each in Goals/Hubs/Policies.razor.css, byte-identical. Blazor CSS
   isolation stamped each copy with its own component's [b-xxxxx], so Settings — which never had a
   copy of its own — received no declaration at all.

   That single omission is BOTH Settings defects: with no `max-width`/`margin: 0 auto` the page ran
   the full viewport (labels and inputs at opposite ends of a wide screen), and with no flex `gap`
   the header card sat flush against the first section. One missing rule, two visible symptoms.

   Promoted rather than forked into a fourth copy: three identical copies were already three chances
   to drift, and the class is named for the page that happened to define it first, not for a concept
   only Goals owns. The three scoped copies are deleted, so this is now the only declaration. The
   rendered Goals/Hubs/Policies pages are unchanged — same six declarations, and nothing else in the
   app declares `.goals-page`, so the specificity drop from (0,2,0) to (0,1,0) resolves identically.
   =============================================================================================== */

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

/* ===============================================================================================
   ENG-production-needs-alignment: tabular figures, as a shared declaration rather than a seventh copy.

   `font-variant-numeric: tabular-nums` makes every digit the same width, so a column of numbers lines up
   by place value instead of jittering by a fraction of a character per row. Without it, right-alignment
   alone is not enough — that is exactly the defect the Command Center had to fix explicitly when its
   monospace figures were removed (Home.razor.css's own note on .cc).

   The property was already declared six times, in five scoped sheets (Home, Hubs, GoalDetail ×3,
   ProductionTreeView) — not carelessly, but because Blazor CSS isolation gives a .razor.css no way to
   share anything. This is the first declaration in the one genuinely global sheet, so a consumer can now
   opt in with a class instead of a copy. The five existing copies are left exactly as they are: each is
   correct, none is reachable from here, and converting them is its own change.
   =============================================================================================== */

.sail-tabular-figures {
    font-variant-numeric: tabular-nums;
}

/* ===============================================================================================
   ENG-button-unification: ONE button form across the whole app, colour carrying the meaning.

   The canonical treatment is the Command Center's "Open workspace" affordance
   (a.cc-work-package__action--available): an outlined pill — transparent fill, 1px solid border,
   0.4rem/0.85rem padding, 0.6rem radius, coloured text, and a 10% tint of its own colour on hover.
   Every action affordance in Sail now renders that shape.

   COLOUR IS SEMANTIC AND STAYS THAT WAY. Form is unified; meaning is not. Three roles:
     accent   — create / open / save / edit   (the default)
     critical — retire / delete / confirm-destroy
     muted    — cancel / reorder, the reversible escapes
   A destructive action is never the same colour as a create action, so the two can never be confused
   at a glance. Everything derives from --sail-button-color, so a role is one declaration.

   Applied by listing the existing class names here rather than adding a class to ~45 markup sites.
   That keeps the sweep visible in one place: this selector list IS the inventory of Sail's buttons,
   and a new button either joins a list or is deliberately left out (see the audit test).
   =============================================================================================== */

.sail-button,
.cc-refresh,
.settings__save,
.hub-card__edit,
.goal-detail__handoff,
.skills-action,
a.cc-work-package__action--available,
a.goal-card__open,
.goal-card__retire,
.goal-card__retire-confirm,
.skills-plans-manage__delete,
.skills-plans-manage__confirm-yes,
.skills-plans-manage__confirm-no,
button.cc-link {
    --sail-button-color: var(--sail-accent);
    display: inline-block;
    padding: 0.4rem 0.85rem;
    border: 1px solid var(--sail-button-color);
    border-radius: 0.6rem;
    background: transparent;
    color: var(--sail-button-color);
    font: inherit;
    font-size: 0.85rem;
    line-height: 1.2;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
    transition: background-color var(--sail-transition-fast) var(--sail-ease);
}

    /* The hover "Open workspace" already had (accent at 10%), generalised to whatever colour the button
       carries — so every button hovers in its own role's colour rather than a hard-coded blue. */
    .sail-button:hover,
    .cc-refresh:hover,
    .settings__save:hover,
    .hub-card__edit:hover,
    .goal-detail__handoff:hover,
    .skills-action:hover,
    a.cc-work-package__action--available:hover,
    a.goal-card__open:hover,
    .goal-card__retire:hover,
    .goal-card__retire-confirm:hover,
    .skills-plans-manage__delete:hover,
    .skills-plans-manage__confirm-yes:hover,
    .skills-plans-manage__confirm-no:hover,
    button.cc-link:hover {
        background: color-mix(in srgb, var(--sail-button-color) 10%, transparent);
        text-decoration: none;
    }

/* Destructive. A different colour token from every create/open action, deliberately and permanently —
   a user must never mistake Retire for Create. */
.goal-card__retire,
.goal-card__retire-confirm,
.skills-plans-manage__delete,
.skills-plans-manage__confirm-yes {
    --sail-button-color: var(--sail-critical);
}

/* Reversible escapes — Cancel, and the Up/Down reorder controls. Same form, quietest colour: neither an
   invitation to act nor a warning. Preserves the primary/secondary weight the unified form would
   otherwise flatten (a Cancel identical to Declare Goal would be worse than either). */
button.cc-link,
.skills-plans-manage__confirm-no {
    --sail-button-color: var(--sail-text-muted);
}

    .cc-refresh:disabled,
    .settings__save:disabled,
    .sail-button:disabled,
    button.cc-link:disabled {
        opacity: 0.5;
        cursor: not-allowed;
    }

/* ENG-button-disabled-state-fix: EMPHASIS — the one irreversible commit in Sail.
   Filled rather than outlined, so the button that destroys something unrecoverable carries more weight
   than "Open goal" does. Deliberately ONE control, not every destructive button: "Retire" merely opens
   the confirmation and stays outlined; this is the one that commits it.

   It keeps --sail-button-color, so it is the same critical red as the outlined destructive buttons — the
   weight is the only difference, never the meaning. Declared after the shared hover so its own filled
   hover wins; the shared 10%-tint hover would otherwise wash the fill away on pointer-over. */
.goal-card__retire-confirm {
    background: var(--sail-button-color);
    color: var(--sail-bg);
    font-weight: 600;
}

    .goal-card__retire-confirm:hover {
        background: color-mix(in srgb, var(--sail-button-color) 85%, #000);
    }

/* Still a plain text link on <a> — "Link EVE Character", the OperationalWorkspace back-links. Those are
   navigation, not action affordances, and were never buttons. */
a.cc-link {
    color: var(--sail-accent);
    font-size: 0.8rem;
    text-decoration: none;
}

    a.cc-link:hover {
        text-decoration: underline;
    }

/* ---------------------------------------------------------------------------------------------
   IMP-086: shared industrial ambient environment. No real production art exists yet (UX-005 §8 gap
   6, explicitly out of this ticket's scope to source) — an honest dark-industrial fallback built
   from layered gradients only, never fake EVE artwork, never an external hotlinked asset. The
   --sail-ambient-image custom property (default "none") is the local, replaceable asset slot.
   --------------------------------------------------------------------------------------------- */

.ambient-environment {
    position: fixed;
    inset: 0;
    z-index: var(--sail-z-ambient);
    overflow: hidden;
    pointer-events: none;
    background: var(--sail-bg-void);
}

.ambient-environment__layer {
    position: absolute;
    inset: -10%;
}

.ambient-environment__layer--asset {
    background-image: var(--sail-ambient-image);
    background-size: cover;
    background-position: center;
}

.ambient-environment__layer--base {
    background:
        radial-gradient(60% 45% at 18% 12%, rgba(79, 179, 255, 0.10), transparent 60%),
        radial-gradient(50% 40% at 85% 82%, rgba(61, 220, 151, 0.06), transparent 65%),
        linear-gradient(165deg, var(--sail-bg-void) 0%, var(--sail-bg) 55%, var(--sail-bg-elevated) 100%);
}

/* IMP-093: a dedicated dark readability veil, sitting between the asset layer and the haze/glow
   accents above it — keeps decision surfaces (glass panels, NEXT, text) legible over whatever imagery
   --sail-ambient-image supplies, without needing to keep the artwork itself unnaturally dark. Harmless
   with the "none" default asset too (a plain, very subtle vertical dark gradient over the existing
   base gradient). */
.ambient-environment__layer--veil {
    background: linear-gradient(180deg, rgba(5, 7, 10, 0.25) 0%, rgba(5, 7, 10, 0.45) 55%, rgba(5, 7, 10, 0.6) 100%);
}

.ambient-environment__layer--haze {
    background: radial-gradient(45% 35% at 50% 100%, rgba(230, 233, 239, 0.035), transparent 70%);
    opacity: 0.8;
}

.ambient-environment__layer--glow {
    background: radial-gradient(30% 22% at 78% 20%, rgba(79, 179, 255, 0.08), transparent 70%);
}

/* Area-specific modifiers reserved for future subtle per-area lighting/haze variation (IMP-086 asks
   only for the infrastructure) — currently a no-op until a real per-area design exists. */
.ambient-environment--sidebar-area .ambient-environment__layer--glow,
.ambient-environment--main-area .ambient-environment__layer--glow {
    opacity: 1;
}

/* ---------------------------------------------------------------------------------------------
   IMP-094/UX-005 §8: Command Center-specific environmental tuning around the ratified
   command-center-industrial.png artwork — supersedes IMP-093's hand-authored abstract SVG and its
   own veil/haze/glow tuning, which were built for that different composition and are not assumed
   correct here. The artwork itself is never retouched; every effect below is a decorative,
   pointer-inert overlay layered above the exact supplied image, restrained enough to read as
   "environmental light already present in the scene," never a new focal element. Establishes the
   pattern future Sail areas follow (same shared base/asset/veil infrastructure, area-specific
   tuning/activity profile below it) without building any configuration system for those areas yet.
   --------------------------------------------------------------------------------------------- */

.ambient-environment--command-center {
    --sail-ambient-image: url("/ambient/command-center-industrial.png");
}

/* Cover-style framing, deliberately tuned rather than left at background-position: center center
   (explicit ticket instruction) — biases the visible frame slightly right/down of the artwork's own
   center so the colossal ceiling structure and right-hand tower stay in view behind the main
   content column (itself offset right of the sidebar), while the artwork's single brightest element
   (the central cyan light shaft, left-of-center in the source image) lands left of that column
   rather than directly behind NEXT. inset: 0 overrides the generic layer's -10% overscan — that
   overscan exists only to give the animated gradient layers slack, and would otherwise make this
   photographic layer's cover-fit crop unpredictable across viewport sizes. */
.ambient-environment--command-center .ambient-environment__layer--asset {
    inset: 0;
    background-repeat: no-repeat;
    background-position: 62% 34%;
}

/* Narrower widths (UX-005 §6 "1024px-class"/mobile floor, verified at 1024px/768px): scene cropping
   is accepted rather than forcing the whole image into view, but the position still favors the cyan
   atmospheric depth over the darker structural edges so the environment stays perceptible even as
   more of the frame is lost off-screen. */
@media (max-width: 1279px) {
    .ambient-environment--command-center .ambient-environment__layer--asset {
        background-position: 52% 28%;
    }
}

/* Retuned readability veil (IMP-094) — the real artwork is already a dark night-interior photograph,
   so a heavy wash would crush its own spatial geometry (explicit ticket constraint: "do not blur the
   entire background so strongly that its spatial geometry disappears"). Every actual piece of
   Command Center text/decision content already lives inside its own .sail-glass panel (own
   background + 20px blur), so this veil's job is only the general edge-framing mood between panels,
   not per-glyph contrast — deliberately lighter through the center than IMP-093's flat top-to-bottom
   wash, so the scene reads as "environment behind glass," never "black wallpaper behind the UI."
   IMP-093's own veil tuning is not assumed correct for this different artwork (explicit ticket
   instruction) and is replaced here rather than layered on top of. */
.ambient-environment--command-center .ambient-environment__layer--veil {
    background:
        radial-gradient(65% 55% at 55% 42%, transparent 45%, rgba(5, 7, 10, 0.4) 100%),
        linear-gradient(180deg, rgba(5, 7, 10, 0.32) 0%, rgba(5, 7, 10, 0.08) 22%, rgba(5, 7, 10, 0.18) 60%, rgba(5, 7, 10, 0.42) 100%);
}

/* Cyan illumination breathing (IMP-094 §5) — mapped to the artwork's own large cold-light
   atmospheric shaft/haze region (upper-center-left). Reads as environmental light already present in
   the scene: opacity-only, no position travel, never communicates Sail semantic (Ready/Caution/
   Blocked) state — that remains exclusively SailBrandMark's/the badge glows' own job. */
.ambient-environment--command-center .ambient-environment__layer--cyan-illumination {
    inset: 0;
    background: radial-gradient(48% 50% at 42% 32%, rgba(120, 200, 255, 0.16), transparent 70%);
    opacity: 0.85;
}

/* Volumetric haze drift (IMP-094 §6) — retunes the shared IMP-086 haze layer's position (the
   artwork's own deep cyan middle-distance region, rather than IMP-093's lower-right SVG tuning) and,
   below, its drift timing (--sail-motion-ambient-haze, redefined above to the slower 60-90s range
   this real scene calls for, up from IMP-086's original 26s).*/
.ambient-environment--command-center .ambient-environment__layer--haze {
    inset: 0;
    background: radial-gradient(60% 40% at 48% 55%, rgba(160, 210, 255, 0.05), transparent 72%);
    opacity: 0.9;
}

/* Command Center's own generic-glow override is superseded by the dedicated utility-light/cyan/haze/
   distant-light/shadow layers below — the shared IMP-086 .ambient-environment__layer--glow keeps its
   own untouched generic default (reserved for the sidebar-area/main-area modifiers) rather than
   carrying forward tuning that was specific to the now-removed SVG's composition. */

/* Asynchronous amber utility-light flicker (IMP-094 §4) — seven zones, each placed over a concrete
   warm-light region already visible in the artwork (the two left-wall lamps, the two foreground
   walkway lamps, and the right-hand tower/archway lamps) rather than distributed uniformly across
   empty space. Three distinct keyframe variants (below) — not one shared animation shifted by delay
   alone, which would still read as a single repeating pattern — combined with per-zone
   duration/delay is what keeps the zones genuinely asynchronous. */
.ambient-environment--command-center .ambient-environment__utility-light {
    position: absolute;
    width: 1.4%;
    aspect-ratio: 1;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(255, 197, 120, 0.9), rgba(232, 179, 57, 0.25) 55%, transparent 75%);
    filter: blur(1px);
    opacity: 0.85;
}

.ambient-environment--command-center .ambient-environment__utility-light--1 { top: 31%; left: 3%; }
.ambient-environment--command-center .ambient-environment__utility-light--2 { top: 59%; left: 3.2%; }
.ambient-environment--command-center .ambient-environment__utility-light--3 { top: 87%; left: 15.5%; }
.ambient-environment--command-center .ambient-environment__utility-light--4 { top: 91%; left: 43.5%; }
.ambient-environment--command-center .ambient-environment__utility-light--5 { top: 26%; left: 75.5%; }
.ambient-environment--command-center .ambient-environment__utility-light--6 { top: 59%; left: 69%; }
.ambient-environment--command-center .ambient-environment__utility-light--7 { top: 59%; left: 92%; }

/* IMP-099 §6 "more distant utility lights": two additional zones grow the existing constellation from
   seven to nine — zone 8 is a new "occasional warm light pulse" (a slow smooth brighten-fade, distinct
   in character from the flicker/hero profiles above); zone 9 reuses the existing subtle flicker-b
   profile at a new position. Both placed over plausible new lamp positions distinct from the existing
   seven (upper-left structure, mid-lower structure) — never a random empty-space light. */
.ambient-environment--command-center .ambient-environment__utility-light--8 { top: 73%; left: 57%; }
.ambient-environment--command-center .ambient-environment__utility-light--9 { top: 19%; left: 12%; }

/* IMP-099 §6 "more independently flickering windows": three tiny, dim, cyan/white-tinted point
   lights mapped to the artwork's own distant upper/mid architecture (distinct region and color from
   the warm .ambient-environment__utility-light constellation, which reads as amber utility lamps) —
   small window-like lights deep in the structure, each on its own independent flicker timing. */
.ambient-environment--command-center .ambient-environment__window-light {
    position: absolute;
    width: 0.65%;
    aspect-ratio: 1;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(210, 235, 255, 0.85), rgba(160, 210, 255, 0.2) 55%, transparent 75%);
    filter: blur(0.5px);
    opacity: 0.55;
}

.ambient-environment--command-center .ambient-environment__window-light--1 { top: 8%; left: 36%; }
.ambient-environment--command-center .ambient-environment__window-light--2 { top: 14%; left: 58%; }
.ambient-environment--command-center .ambient-environment__window-light--3 { top: 44%; left: 52%; }

/* Distant moving utility light (IMP-094 §7) — one tiny traveling light mapped to the artwork's own
   mid-depth bridge/platform structure, implying distant activity (a service platform or maintenance
   traversal) without ever rendering a vehicle/ship/machine body. A single directional traversal with
   a long invisible interval either side, never a bounce/alternate loop — the opacity keyframes below
   keep the position "reset" invisible, so no loop seam is ever seen. */
/* IMP-095: contrast/glow raised from IMP-094's original (5px, 0.85 fill, a 6px/1px shadow) — that
   version was too faint to ever consciously register against the busy artwork over ~60s of direct
   observation. Still a tiny, distant point (never a UI-like particle): the glow radius grew, not the
   core dot, which stays small. Position/mapping (the mid-depth bridge region) is unchanged — nothing
   suggested the location itself was wrong, only its visibility. */
.ambient-environment--command-center .ambient-environment__distant-light {
    position: absolute;
    top: 39%;
    left: 27%;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: rgba(210, 236, 255, 0.92);
    box-shadow: 0 0 10px 2px rgba(170, 215, 255, 0.85), 0 0 3px 1px rgba(255, 255, 255, 0.6);
    opacity: 0;
}

/* IMP-099 §6 "tiny moving lights deep inside the station": a second distant traveling light — still
   tiny, still a single directional traversal, mapped to a different plausible deep-structure region
   (the right-hand tower/archway area) with its own duration/delay so it never reads as synchronized
   with the first. Reuses the same sail-distant-light-traverse keyframe shape (a proven, already-subtle
   motion) rather than inventing a second one. */
.ambient-environment--command-center .ambient-environment__distant-light--2 {
    position: absolute;
    top: 58%;
    left: 68%;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: rgba(200, 225, 255, 0.85);
    box-shadow: 0 0 8px 2px rgba(160, 205, 255, 0.75);
    opacity: 0;
}

/* Industrial shadow sweep (IMP-094 §8) — an extremely subtle, broad soft shadow over the artwork's
   own upper ceiling-truss structural region, implying a much larger mechanical structure moving
   outside the visible framing. No literal object is ever rendered, no rotation, no hard edge — a
   blurred linear gradient only. */
.ambient-environment--command-center .ambient-environment__industrial-shadow {
    position: absolute;
    inset: -5% -5% auto -5%;
    height: 24%;
    background: linear-gradient(180deg, rgba(0, 0, 0, 0.22), transparent 100%);
    filter: blur(18px);
}

/* Restrained ambient effects (slow pulse, haze drift, subtle flicker/breathing/traversal/sweep) —
   enabled only when the user has not requested reduced motion. Progressive enhancement, not a
   fallback branch: the static layered composition above (including every Command Center scene layer)
   is already a complete, honest presentation without any animation. */
@media (prefers-reduced-motion: no-preference) {
    .ambient-environment__layer--base {
        animation: sail-ambient-pulse var(--sail-motion-ambient-pulse) ease-in-out infinite;
    }

    .ambient-environment__layer--haze {
        animation: sail-ambient-haze-drift var(--sail-motion-ambient-haze) ease-in-out infinite;
    }

    .ambient-environment__layer--glow {
        animation: sail-ambient-flicker var(--sail-motion-ambient-flicker) ease-in-out infinite;
    }

    .ambient-environment--command-center .ambient-environment__layer--cyan-illumination {
        animation: sail-cyan-illumination-breathe var(--sail-motion-ambient-cyan-breathe) ease-in-out infinite;
    }

    .ambient-environment--command-center .ambient-environment__utility-light--1 { animation: sail-utility-flicker-a var(--sail-motion-ambient-utility-a) ease-in-out infinite; animation-delay: -2s; }
    .ambient-environment--command-center .ambient-environment__utility-light--2 { animation: sail-utility-flicker-b var(--sail-motion-ambient-utility-b) ease-in-out infinite; animation-delay: -9s; }
    /* IMP-095: zone 3 (a foreground walkway lamp, clear of NEXT/overview text) is one of the two
       "hero" zones — see sail-utility-flicker-hero-a's own doc comment. */
    .ambient-environment--command-center .ambient-environment__utility-light--3 { animation: sail-utility-flicker-hero-a var(--sail-motion-ambient-utility-hero-a) ease-in-out infinite; animation-delay: -5s; }
    .ambient-environment--command-center .ambient-environment__utility-light--4 { animation: sail-utility-flicker-a 21s ease-in-out infinite; animation-delay: -13s; }
    .ambient-environment--command-center .ambient-environment__utility-light--5 { animation: sail-utility-flicker-b 19s ease-in-out infinite; animation-delay: -6s; }
    .ambient-environment--command-center .ambient-environment__utility-light--6 { animation: sail-utility-flicker-c 25s ease-in-out infinite; animation-delay: -17s; }
    /* IMP-095: zone 7 (far right edge, outside the .cc content column) is the second "hero" zone —
       see sail-utility-flicker-hero-b's own doc comment. Deliberately a different profile/duration/
       delay from zone 3's hero-a so the two never read as one synchronized event. */
    .ambient-environment--command-center .ambient-environment__utility-light--7 { animation: sail-utility-flicker-hero-b var(--sail-motion-ambient-utility-hero-b) ease-in-out infinite; animation-delay: -14s; }
    /* IMP-099: zone 8's "occasional warm light pulse" — a slow, smooth single-hump brighten-fade,
       deliberately distinct in character from every flicker/hero profile above. */
    .ambient-environment--command-center .ambient-environment__utility-light--8 { animation: sail-utility-pulse 22s ease-in-out infinite; animation-delay: -8s; }
    .ambient-environment--command-center .ambient-environment__utility-light--9 { animation: sail-utility-flicker-b 21s ease-in-out infinite; animation-delay: -3s; }

    .ambient-environment--command-center .ambient-environment__window-light--1 { animation: sail-window-flicker-a 16s ease-in-out infinite; animation-delay: -3s; }
    .ambient-environment--command-center .ambient-environment__window-light--2 { animation: sail-window-flicker-b 20s ease-in-out infinite; animation-delay: -11s; }
    .ambient-environment--command-center .ambient-environment__window-light--3 { animation: sail-window-flicker-a 24s ease-in-out infinite; animation-delay: -7s; }

    .ambient-environment--command-center .ambient-environment__distant-light {
        animation: sail-distant-light-traverse var(--sail-motion-ambient-distant-light) linear infinite;
    }

    .ambient-environment--command-center .ambient-environment__distant-light--2 {
        animation: sail-distant-light-traverse var(--sail-motion-ambient-distant-light-2) linear infinite;
        animation-delay: -19s;
    }

    .ambient-environment--command-center .ambient-environment__industrial-shadow {
        animation: sail-industrial-shadow-sweep var(--sail-motion-ambient-shadow) ease-in-out infinite;
    }
}

@keyframes sail-ambient-pulse {
    0%, 100% { opacity: 0.85; }
    50% { opacity: 1; }
}

@keyframes sail-ambient-haze-drift {
    0% { transform: translate(-2%, 0); }
    50% { transform: translate(2%, -1%); }
    100% { transform: translate(-2%, 0); }
}

@keyframes sail-ambient-flicker {
    0%, 92%, 100% { opacity: 0.55; }
    94% { opacity: 0.75; }
    96% { opacity: 0.5; }
}

/* IMP-094: cyan illumination breathing — subtle, ~perceptual ±5% intensity range, no position travel. */
@keyframes sail-cyan-illumination-breathe {
    0%, 100% { opacity: 0.8; }
    50% { opacity: 0.9; }
}

/* IMP-094: three independent utility-light flicker profiles — most of each cycle is a long, quiet,
   stable interval; each profile differs in where/how its brief dim or double-flicker blip falls, so
   zones sharing a profile at different durations/delays still never read as one repeating pattern. */
@keyframes sail-utility-flicker-a {
    0%, 96%, 100% { opacity: 0.85; }
    97.5% { opacity: 0.5; }
    98.5% { opacity: 0.8; }
}

@keyframes sail-utility-flicker-b {
    0%, 44%, 100% { opacity: 0.82; }
    45% { opacity: 0.4; }
    46% { opacity: 0.78; }
    47% { opacity: 0.35; }
    48.5% { opacity: 0.85; }
}

@keyframes sail-utility-flicker-c {
    0%, 63%, 100% { opacity: 0.88; }
    64% { opacity: 0.6; }
    66% { opacity: 0.85; }
}

/* IMP-095: two deliberately more-active "hero" profiles (motion hierarchy §11 — exactly one local
   utility-light flicker is meant to be occasionally consciously noticeable, never all seven equally).
   Unlike a/b/c's near-instantaneous sub-second blip (invisible in peripheral vision per the ticket's
   direct user observation), these hold the dimmed value for roughly a second so the eye can register
   an actual dim-and-recover rather than a single flash frame. hero-a is a single ~32% perceptual dip
   with a hold; hero-b is a short double-flicker. Both fire once per their (~24-26s) cycle, so within
   any ~20-40s window at least one of the two zones using them has visibly happened. */
@keyframes sail-utility-flicker-hero-a {
    0%, 78%, 100% { opacity: 0.88; }
    82% { opacity: 0.6; }
    88% { opacity: 0.6; }
    93% { opacity: 0.88; }
}

@keyframes sail-utility-flicker-hero-b {
    0%, 70%, 100% { opacity: 0.86; }
    73% { opacity: 0.55; }
    76% { opacity: 0.8; }
    79% { opacity: 0.5; }
    83% { opacity: 0.86; }
}

/* IMP-099 §6 "occasional warm light pulses": a slow, smooth single-hump brighten-then-fade — unlike
   every flicker/hero profile above (a stable baseline with a brief dip), this one continuously and
   gently breathes, giving zone 8 a distinctly different rhythm/character among the utility-light
   constellation. */
@keyframes sail-utility-pulse {
    0%, 100% { opacity: 0.5; }
    50% { opacity: 0.82; }
}

/* IMP-099 §6 "more independently flickering windows": two restrained profiles for the small distant
   window lights — even quieter than the utility-light a/b/c profiles (lower baseline opacity, since
   these read as small distant windows rather than foreground utility lamps), each with its own brief
   dim so multiple zones sharing a profile at different durations/delays never look synchronized. */
@keyframes sail-window-flicker-a {
    0%, 90%, 100% { opacity: 0.6; }
    92% { opacity: 0.3; }
    94% { opacity: 0.55; }
}

@keyframes sail-window-flicker-b {
    0%, 55%, 100% { opacity: 0.55; }
    57% { opacity: 0.25; }
    59% { opacity: 0.5; }
}

/* IMP-094/095: one directional traversal per cycle with an invisible interval either side — the
   position "resets" only while opacity is already 0, so no bounce/alternate motion and no visible
   loop seam are ever seen. IMP-095 shortened the cycle (58s -> 30s, see
   --sail-motion-ambient-distant-light) and the quiet intervals so a full traversal is guaranteed to
   fall within any ~30s observation window — IMP-094's longer, slower version was real but was never
   consciously noticed over ~60s of direct user observation. */
@keyframes sail-distant-light-traverse {
    0%, 12% { opacity: 0; transform: translateX(0); }
    16% { opacity: 0.9; }
    82% { opacity: 0.9; transform: translateX(26vw); }
    88%, 100% { opacity: 0; transform: translateX(26vw); }
}

/* IMP-094: ~20-30px-equivalent displacement at wide desktop, no rotation, extremely slow. */
@keyframes sail-industrial-shadow-sweep {
    0%, 100% { transform: translateX(-0.8%); }
    50% { transform: translateX(0.8%); }
}

/* Reduced motion (accessibility): disables ambient movement entirely (the media query above already
   never applies the animation in the first place) and additionally collapses every other transition/
   animation duration app-wide to near-zero, so no future motion introduced elsewhere in the shell can
   silently bypass this preference. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
        scroll-behavior: auto !important;
    }
}

.btn-primary {
    color: #fff;
    background-color: #1b6ec2;
    border-color: #1861ac;
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
  box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}

.content {
    padding-top: 1.1rem;
}

h1:focus {
    outline: none;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid #e50000;
}

.validation-message {
    color: #e50000;
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.darker-border-checkbox.form-check-input {
    border-color: #929292;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}