/*
   Halsys Deploy — dark theme.

   Dark only. There is no light variant, so nothing here is written as an override of one.

   ── The colour problem this file solves ─────────────────────────────────────────────────────────
   The brand colour (#b92d2d) is red, and red is also this platform's danger signal: it is how an
   operator knows a tenant is PRODUCTION before deploying to it. If red were used freely it would
   stop meaning "careful" — the eye adapts to whatever it sees everywhere.

   So red is rationed, and the rationing is the design:

     * Brand red appears as small, fixed, predictable structure — the sidebar brand mark, the active
       navigation indicator, focus rings, and affirmative primary buttons. Always in a known place.
     * Danger red appears as LARGE AREA FILL — the PRODUCTION badge, a 4px row edge, a tinted panel
       with a red border. It is also a hotter, brighter red than the brand tone, so intensity as well
       as area separates "commit" from "careful".
     * TEST is cyan, not a paler red. Test versus Production is then a hue contrast, readable at a
       glance and not dependent on remembering which red meant which.
     * Body links are neutral, never red, so page content never competes with the signal.

   Redundancy beyond colour is kept from the previous theme: PRODUCTION and TEST carry uppercase text
   and a filled/hollow glyph, so the distinction survives greyscale printing and colour blindness.
   ─────────────────────────────────────────────────────────────────────────────────────────────────

   Contrast: body text, secondary text, and every badge's text on its own fill were checked against
   their actual backdrop and clear WCAG AA. The dim tone is reserved for timestamps and small-caps
   labels that repeat information available elsewhere on the row.

   Priorities are unchanged from before: data must be unambiguous; the tenant being acted on must be
   impossible to miss; destructive actions must not look like safe ones. Density and prettiness come
   second. Desktop-only by design, so there are no small-screen breakpoints beyond keeping the
   sidebar usable in a narrow window.
*/

:root {
    color-scheme: dark;

    /* --- Surfaces. A near-neutral grey with a trace of warmth, so red reads as intentional
           rather than fighting a cool blue-grey. ---------------------------------------------- */
    --halsys-bg: #131417;
    --halsys-surface: #1a1c21;
    --halsys-surface-2: #21242b;
    --halsys-surface-3: #282c34;
    --halsys-sidebar: #0d0e11;
    --halsys-well: #0b0c0f;

    --halsys-border: #2c313a;
    --halsys-border-strong: #3d4450;

    --halsys-text: #e8eaee;
    --halsys-text-muted: #a2abb8;
    --halsys-text-dim: #838d9a;

    /* --- Brand. Solid fills only: #b92d2d is too dark to use as text on this background. ------ */
    --halsys-brand: #b92d2d;
    --halsys-brand-hover: #cf3636;
    --halsys-brand-active: #9d2424;
    --halsys-brand-tint: rgba(185, 45, 45, 0.13);
    --halsys-brand-tint-strong: rgba(185, 45, 45, 0.24);
    --halsys-brand-ring: rgba(185, 45, 45, 0.45);

    /* --- Danger / production. Hotter than the brand tone on purpose. ------------------------- */
    --halsys-danger: #cc2f2f;
    --halsys-danger-hover: #dd4040;
    --halsys-danger-text: #ff7b72;
    --halsys-danger-tint: rgba(204, 47, 47, 0.11);
    --halsys-danger-border: rgba(220, 70, 70, 0.42);

    /* --- Test. Cyan, for hue contrast against production. ------------------------------------ */
    --halsys-test-text: #56c8e8;
    --halsys-test-tint: rgba(86, 200, 232, 0.12);
    --halsys-test-border: rgba(86, 200, 232, 0.34);

    --halsys-warning: #d99a2b;
    --halsys-warning-text: #f0b755;
    --halsys-warning-tint: rgba(217, 154, 43, 0.12);
    --halsys-warning-border: rgba(217, 154, 43, 0.36);

    --halsys-success: #2f9e63;
    --halsys-success-text: #5ed49a;
    --halsys-success-tint: rgba(47, 158, 99, 0.12);
    --halsys-success-border: rgba(47, 158, 99, 0.34);

    --halsys-info-text: #6fd3ff;

    --halsys-sidebar-width: 250px;
    --halsys-mono: ui-monospace, "Cascadia Mono", Consolas, "Liberation Mono", monospace;
}

/* ---------------------------------------------------------------------------------------------
   Bootstrap bridge.

   Bootstrap 5.3 is driven by custom properties, so re-pointing them themes every component at once
   — alerts, tables, forms, badges, breadcrumbs — instead of chasing each with an override. The
   `-bg-subtle` / `-border-subtle` / `-text-emphasis` triplets are what .alert-* is built from,
   which is why they are set here rather than styling alerts directly.
--------------------------------------------------------------------------------------------- */

[data-bs-theme="dark"] {
    --bs-body-bg: var(--halsys-bg);
    --bs-body-color: var(--halsys-text);
    --bs-emphasis-color: #ffffff;
    --bs-secondary-color: var(--halsys-text-muted);
    --bs-tertiary-color: var(--halsys-text-dim);
    --bs-secondary-bg: var(--halsys-surface-2);
    --bs-tertiary-bg: var(--halsys-surface);
    --bs-border-color: var(--halsys-border);
    --bs-border-color-translucent: var(--halsys-border);

    /* The -rgb triplets matter as much as the colours above them: Bootstrap's text utilities
       (.text-secondary, .text-body-secondary) are built as rgba(var(--bs-*-color-rgb), opacity) and
       ignore the plain colour property entirely. Leaving these at their defaults left
       .text-secondary — used on nearly every page — at 2.16:1 against the panel surface. */
    --bs-body-color-rgb: 232, 234, 238;
    --bs-emphasis-color-rgb: 255, 255, 255;
    --bs-secondary-color-rgb: 162, 171, 184;
    --bs-tertiary-color-rgb: 131, 141, 154;

    /* Primary is the brand: it drives .btn-primary, the affirmative action on every page. */
    --bs-primary: #b92d2d;
    --bs-primary-rgb: 185, 45, 45;
    --bs-danger: #cc2f2f;
    --bs-danger-rgb: 204, 47, 47;
    --bs-success: #2f9e63;
    --bs-success-rgb: 47, 158, 99;
    --bs-warning: #d99a2b;
    --bs-warning-rgb: 217, 154, 43;
    --bs-info: #56c8e8;
    --bs-info-rgb: 86, 200, 232;
    /* Bootstrap reads --bs-secondary-rgb for BOTH .text-secondary and .bg-secondary, so one value
       cannot serve light muted text and a dark chip fill. It is set here for the text case, which is
       used on nearly every page, and .bg-secondary is given an explicit fill further down. */
    --bs-secondary: #a2abb8;
    --bs-secondary-rgb: 162, 171, 184;

    /* Links stay neutral. Red links would compete with the production signal. */
    --bs-link-color: #cdd5e0;
    --bs-link-color-rgb: 205, 213, 224;
    --bs-link-hover-color: #ffffff;
    --bs-link-hover-color-rgb: 255, 255, 255;

    --bs-code-color: var(--halsys-warning-text);
    --bs-highlight-bg: var(--halsys-brand-tint-strong);

    --bs-danger-bg-subtle: var(--halsys-danger-tint);
    --bs-danger-border-subtle: var(--halsys-danger-border);
    --bs-danger-text-emphasis: var(--halsys-danger-text);

    --bs-warning-bg-subtle: var(--halsys-warning-tint);
    --bs-warning-border-subtle: var(--halsys-warning-border);
    --bs-warning-text-emphasis: var(--halsys-warning-text);

    --bs-success-bg-subtle: var(--halsys-success-tint);
    --bs-success-border-subtle: var(--halsys-success-border);
    --bs-success-text-emphasis: var(--halsys-success-text);

    --bs-info-bg-subtle: var(--halsys-test-tint);
    --bs-info-border-subtle: var(--halsys-test-border);
    --bs-info-text-emphasis: var(--halsys-test-text);

    --bs-secondary-bg-subtle: var(--halsys-surface-2);
    --bs-secondary-border-subtle: var(--halsys-border);
    --bs-secondary-text-emphasis: var(--halsys-text-muted);

    --bs-primary-bg-subtle: var(--halsys-brand-tint);
    --bs-primary-border-subtle: var(--halsys-brand-ring);
    --bs-primary-text-emphasis: #ff8f86;
}

html, body {
    height: 100%;
}

body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    font-size: 0.9375rem;
    color: var(--halsys-text);
    background: var(--halsys-bg);
}

::selection {
    background: var(--halsys-brand-tint-strong);
    color: #fff;
}

/* One visible focus treatment everywhere, in brand red. A keyboard operator needs to know where
   they are before pressing a button that deploys something. */
:focus-visible {
    outline: 2px solid var(--halsys-brand-hover);
    outline-offset: 2px;
}

.form-control:focus,
.form-select:focus,
.form-check-input:focus {
    border-color: var(--halsys-brand-hover);
    box-shadow: 0 0 0 0.2rem var(--halsys-brand-ring);
}

* {
    scrollbar-color: var(--halsys-border-strong) transparent;
}

::-webkit-scrollbar {
    width: 11px;
    height: 11px;
}

::-webkit-scrollbar-track {
    background: transparent;
}

::-webkit-scrollbar-thumb {
    background: var(--halsys-border-strong);
    border-radius: 6px;
    border: 2px solid transparent;
    background-clip: content-box;
}

::-webkit-scrollbar-thumb:hover {
    background: #4d5563;
    background-clip: content-box;
}

/* ---------------------------------------------------------------- shell --- */

.app-shell {
    display: flex;
    min-height: 100vh;
}

.app-main {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.app-topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.55rem 1.5rem;
    background: var(--halsys-surface);
    border-bottom: 1px solid var(--halsys-border);
}

.app-env-tag {
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--halsys-text-muted);
    background: var(--halsys-surface-2);
    border: 1px solid var(--halsys-border);
    border-radius: 999px;
    padding: 0.2rem 0.7rem;
}

.app-content {
    padding: 1.5rem;
    max-width: 1500px;
    width: 100%;
}

/* -------------------------------------------------------------- sidebar --- */

.app-sidebar {
    width: var(--halsys-sidebar-width);
    flex: 0 0 var(--halsys-sidebar-width);
    background: var(--halsys-sidebar);
    border-right: 1px solid var(--halsys-border);
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
}

.app-brand {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 1rem 1.1rem;
    text-decoration: none;
    border-bottom: 1px solid var(--halsys-border);
}

/* The Halsys wordmark: the one place the brand colour appears at full strength as an identity mark.
   The PNG is a 3.11:1 banner with roughly 19% transparent padding above and below the letters, so the
   box is always noticeably taller than the ink — sizing is by height, and the padding does the optical
   spacing work. Sized in px rather than em so the lockup does not drift if the base font size changes. */
.app-brand-logo {
    display: block;
    height: 34px;
    width: auto;
}

.app-brand-text {
    color: var(--halsys-text);
    font-weight: 600;
    font-size: 0.95rem;
    line-height: 1.15;
}

.app-nav-scroll {
    overflow-y: auto;
    padding: 0.75rem 0 2rem;
}

.app-nav-group {
    margin-bottom: 1rem;
}

.app-nav-heading {
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--halsys-text-dim);
    padding: 0.35rem 1.1rem;
}

.app-nav-link {
    display: block;
    padding: 0.45rem 1.1rem;
    color: var(--halsys-text-muted);
    text-decoration: none;
    border-left: 3px solid transparent;
    font-size: 0.9rem;
}

.app-nav-link:hover {
    background: rgba(255, 255, 255, 0.04);
    color: var(--halsys-text);
}

.app-nav-link.active {
    background: var(--halsys-brand-tint);
    border-left-color: var(--halsys-brand-hover);
    color: #fff;
    font-weight: 600;
}

/* The deploy entry is the only sidebar item that changes a customer system, so it is amber —
   distinct from both the red chrome and the neutral navigation around it. */
.app-nav-link-deploy {
    font-weight: 600;
    color: var(--halsys-warning-text);
}

.app-nav-link-deploy:hover,
.app-nav-link-deploy.active {
    color: #ffd98a;
}

/* -------------------------------------------------------- page furniture --- */

.page-header {
    margin-bottom: 1.25rem;
    padding-bottom: 0.9rem;
    border-bottom: 1px solid var(--halsys-border);
}

.page-header .breadcrumb {
    margin-bottom: 0.25rem;
    --bs-breadcrumb-divider-color: var(--halsys-text-dim);
}

.page-header h1 {
    color: #fff;
}

/* Scope banner: states which service or tenant a subordinate page is acting on. */
.scope-banner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6rem 1.25rem;
    background: var(--halsys-surface-2);
    border: 1px solid var(--halsys-border);
    border-radius: 6px;
    padding: 0.55rem 0.85rem;
    margin-top: 0.65rem;
    font-size: 0.875rem;
}

/* Production in scope: the banner itself becomes a red area, not just a red word. */
.scope-banner-production {
    background: var(--halsys-danger-tint);
    border-color: var(--halsys-danger-border);
    box-shadow: inset 0 0 0 1px rgba(220, 70, 70, 0.12);
}

.scope-item {
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
}

.scope-label {
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--halsys-text-dim);
}

.scope-value {
    font-weight: 600;
    color: var(--halsys-text);
}

/* -------------------------------------------------------------- badges --- */

.badge {
    font-weight: 600;
}

.tenant-badge {
    font-weight: 700;
    letter-spacing: 0.05em;
    border: 1px solid transparent;
}

/* Solid, high-chroma fill with a glow: the loudest thing the palette permits, reserved for this. */
.tenant-badge-production {
    background: var(--halsys-danger);
    color: #fff;
    border-color: #e05555;
    box-shadow: 0 0 0 1px rgba(220, 70, 70, 0.25), 0 1px 6px rgba(204, 47, 47, 0.4);
}

.tenant-badge-test {
    background: var(--halsys-test-tint);
    color: var(--halsys-test-text);
    border-color: var(--halsys-test-border);
}

.tenant-badge-lg {
    font-size: 0.95rem;
    padding: 0.4rem 0.75rem;
}

.badge-secret {
    background: #4b3a67;
    color: #d9c9f5;
    border: 1px solid #6a548f;
    font-weight: 600;
    letter-spacing: 0.03em;
}

/*
   Release channel. Deliberately not Bootstrap's .bg-primary: primary is the brand red, and a red
   RELEASE badge sitting beside a red PRODUCTION badge would be exactly the confusion this palette
   exists to prevent. Release is the calm default; Test is the one worth noticing.
*/
.badge-channel-release {
    background: var(--halsys-surface-3);
    color: var(--halsys-text);
    border: 1px solid var(--halsys-border-strong);
}

.badge-channel-test {
    background: var(--halsys-warning-tint);
    color: var(--halsys-warning-text);
    border: 1px solid var(--halsys-warning-border);
}

/* Run-state badges. Outlined tints rather than solid fills, so a table full of them stays readable
   and only the failures draw the eye. */
.badge-state-neutral {
    background: var(--halsys-surface-3);
    color: var(--halsys-text-muted);
    border: 1px solid var(--halsys-border-strong);
}

.badge-state-muted {
    background: transparent;
    color: var(--halsys-text-dim);
    border: 1px dashed var(--halsys-border-strong);
}

.badge-state-running {
    background: var(--halsys-test-tint);
    color: var(--halsys-test-text);
    border: 1px solid var(--halsys-test-border);
}

.badge-state-ok {
    background: var(--halsys-success-tint);
    color: var(--halsys-success-text);
    border: 1px solid var(--halsys-success-border);
}

.badge-state-warn {
    background: var(--halsys-warning-tint);
    color: var(--halsys-warning-text);
    border: 1px solid var(--halsys-warning-border);
}

/* Failure is the exception to the outlined rule: a solid fill, so it cannot be skimmed past. */
.badge-state-fail {
    background: var(--halsys-danger);
    color: #fff;
    border: 1px solid #e05555;
}

/*
   .bg-secondary is used across the app for neutral chips (ARCHIVED, required, never checked).
   Bootstrap derives it from --bs-secondary-rgb, which is set to a light muted tone so that
   .text-secondary is legible — that would make this chip a pale block with white text on it. The
   fill is therefore stated explicitly, and !important is required to beat Bootstrap's own utility.
*/
.badge.bg-secondary,
.bg-secondary {
    background-color: var(--halsys-surface-3) !important;
    color: var(--halsys-text-muted) !important;
}

.badge.bg-secondary {
    border: 1px solid var(--halsys-border-strong);
}

/* Same collision, same fix: .bg-warning / .bg-info fills pair with .text-dark in the markup, which
   assumes a pale fill. These keep that pairing working by staying genuinely pale. */
.badge.bg-warning {
    background-color: var(--halsys-warning) !important;
    color: #1a1206 !important;
}

.badge.bg-info {
    background-color: var(--halsys-info-text) !important;
    color: #06181f !important;
}

/* White on the success green measured 3.39:1 — under AA. Rather than darken the green until white
   passes, these adopt the same outlined-tint treatment as the run-state chips, which is both legible
   and consistent: every positive state in the app now looks the same. */
.badge.bg-success {
    background-color: var(--halsys-success-tint) !important;
    color: var(--halsys-success-text) !important;
    border: 1px solid var(--halsys-success-border);
}

/* .bg-danger stays a solid fill — white on it clears AA, and failure should stay loud. */
.badge.bg-danger {
    background-color: var(--halsys-danger) !important;
    color: #fff !important;
    border: 1px solid #e05555;
}

/*
   .text-danger reads --bs-danger-rgb, the same variable as the .bg-danger fill. The fill tone is too
   dark to use as text (3.25:1), so the text case is stated explicitly here instead of compromising
   the fill.
*/
.text-danger {
    color: var(--halsys-danger-text) !important;
}

/* -------------------------------------------------------------- tables --- */

.table-data {
    background: var(--halsys-surface);
    border: 1px solid var(--halsys-border);
    border-radius: 6px;
    overflow: hidden;
}

.table-data > .table {
    margin-bottom: 0;
    --bs-table-bg: transparent;
    --bs-table-color: var(--halsys-text);
    --bs-table-border-color: var(--halsys-border);
    --bs-table-hover-bg: rgba(255, 255, 255, 0.035);
    --bs-table-hover-color: var(--halsys-text);
    --bs-table-active-bg: var(--halsys-brand-tint);
    --bs-table-active-color: #fff;
}

.table-data th {
    font-size: 0.74rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--halsys-text-dim);
    background: var(--halsys-surface-2);
    white-space: nowrap;
    border-bottom: 1px solid var(--halsys-border);
}

.table-data td {
    vertical-align: middle;
}

/* A production tenant is identifiable in a long list from the row edge alone, without reading it. */
.table-data tr.row-production > td:first-child {
    box-shadow: inset 4px 0 0 var(--halsys-danger);
}

.mono {
    font-family: var(--halsys-mono);
    font-size: 0.86em;
}

.nowrap {
    white-space: nowrap;
}

code {
    background: rgba(240, 183, 85, 0.09);
    padding: 0.05em 0.3em;
    border-radius: 3px;
}

/* --------------------------------------------------- cards and panels --- */

.panel {
    background: var(--halsys-surface);
    border: 1px solid var(--halsys-border);
    border-radius: 6px;
    margin-bottom: 1.25rem;
}

.panel-head {
    padding: 0.7rem 1rem;
    border-bottom: 1px solid var(--halsys-border);
    background: var(--halsys-surface-2);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    border-radius: 6px 6px 0 0;
}

.panel-head h2, .panel-head h3 {
    margin: 0;
    font-size: 1rem;
    font-weight: 600;
    color: var(--halsys-text);
}

.panel-body {
    padding: 1rem;
}

/* Wraps anything destructive or production-affecting. Red border and red header bar, so the panel
   reads as dangerous before any of its text is read. */
.panel-danger {
    border-color: var(--halsys-danger-border);
}

.panel-danger > .panel-head {
    background: var(--halsys-danger-tint);
    border-bottom-color: var(--halsys-danger-border);
}

.panel-danger > .panel-head h2 {
    color: var(--halsys-danger-text);
}

/* Inline editor rows inside a data table. Raised rather than tinted, so it reads as "this row is
   open for editing" without borrowing a semantic colour. */
.editor-row {
    background: var(--halsys-surface-2);
    box-shadow: inset 0 1px 0 var(--halsys-border-strong), inset 0 -1px 0 var(--halsys-border-strong);
}

/* Sub-navigation within a service or tenant. */
.sub-nav {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
    border-bottom: 1px solid var(--halsys-border);
    margin-bottom: 1.25rem;
}

.sub-nav a {
    padding: 0.45rem 0.9rem;
    text-decoration: none;
    color: var(--halsys-text-muted);
    border: 1px solid transparent;
    border-bottom: none;
    border-radius: 6px 6px 0 0;
    font-size: 0.9rem;
    margin-bottom: -1px;
}

.sub-nav a:hover {
    background: var(--halsys-surface-2);
    color: var(--halsys-text);
}

.sub-nav a.active {
    background: var(--halsys-surface);
    border-color: var(--halsys-border);
    border-bottom: 1px solid var(--halsys-surface);
    color: #fff;
    font-weight: 600;
    box-shadow: inset 0 2px 0 var(--halsys-brand);
}

/* ------------------------------------------------------------- editors --- */

.form-control,
.form-select {
    background-color: var(--halsys-surface-2);
    border-color: var(--halsys-border-strong);
    color: var(--halsys-text);
}

.form-control::placeholder {
    color: var(--halsys-text-dim);
}

.form-control:disabled,
.form-select:disabled {
    background-color: var(--halsys-surface);
    color: var(--halsys-text-dim);
}

.form-label {
    font-weight: 600;
    color: var(--halsys-text);
    margin-bottom: 0.3rem;
}

.script-editor {
    font-family: var(--halsys-mono);
    font-size: 0.85rem;
    line-height: 1.45;
    tab-size: 4;
    min-height: 260px;
    white-space: pre;
    overflow-wrap: normal;
    overflow-x: auto;
    background-color: var(--halsys-well);
    color: #dfe5ec;
}

.script-preview {
    font-family: var(--halsys-mono);
    font-size: 0.82rem;
    line-height: 1.45;
    background: var(--halsys-well);
    color: #dfe5ec;
    border: 1px solid var(--halsys-border);
    border-radius: 6px;
    padding: 0.75rem 0.9rem;
    margin: 0;
    max-height: 340px;
    overflow: auto;
    white-space: pre;
}

/* One attached file in the step editor. Boxed so a step with several files stays readable as separate
   units rather than a run of unlabelled textareas. */
.attached-file {
    border: 1px solid var(--halsys-border);
    border-left: 3px solid var(--halsys-border-strong);
    border-radius: 6px;
    padding: 0.75rem;
    background: rgba(255, 255, 255, 0.015);
}

/* A file's own editor is shorter than the script's: these are usually a few dozen lines, and a tall
   box per file would push the save button off screen on a step with three of them. */
.attached-file .script-editor {
    min-height: 0;
}

.variable-reference {
    max-height: 420px;
    overflow-y: auto;
    font-size: 0.85rem;
}

.variable-reference code {
    white-space: nowrap;
}

.type-to-confirm {
    max-width: 440px;
}

/* ------------------------------------------------------------ live log --- */

.deploy-log {
    background: var(--halsys-well);
    color: #dfe5ec;
    font-family: var(--halsys-mono);
    font-size: 0.82rem;
    line-height: 1.5;
    border: 1px solid var(--halsys-border);
    border-radius: 6px;
    padding: 0.75rem 0.9rem;
    height: 60vh;
    min-height: 320px;
    overflow-y: auto;
}

.deploy-log-line {
    display: flex;
    gap: 0.75rem;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

/* Log timestamps: dim enough to recede behind the output, light enough to still be read against the
   near-black log well (the first attempt at #5d6672 measured 3.37:1). */
.deploy-log-time {
    color: #7d8794;
    flex: 0 0 auto;
    user-select: none;
}

.deploy-log-stdout { color: #dfe5ec; }
.deploy-log-stderr { color: var(--halsys-danger-text); }
.deploy-log-agent { color: var(--halsys-info-text); }
.deploy-log-platform { color: var(--halsys-warning-text); font-weight: 600; }

.deploy-step-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.deploy-step-list > li {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.4rem 0;
    border-bottom: 1px solid var(--halsys-border);
}

.deploy-step-list > li:last-child {
    border-bottom: none;
}

/* ---------------------------------------------------------------- misc --- */

/* A key or password shown exactly once. Amber, because it is neither an error nor routine: it means
   "act on this now, it will not be shown again". */
.key-reveal {
    font-family: var(--halsys-mono);
    font-size: 0.9rem;
    background: var(--halsys-well);
    border: 1px solid var(--halsys-warning-border);
    color: var(--halsys-warning-text);
    border-radius: 6px;
    padding: 0.6rem 0.8rem;
    word-break: break-all;
}

.stat-tile {
    background: var(--halsys-surface);
    border: 1px solid var(--halsys-border);
    border-radius: 6px;
    padding: 0.9rem 1rem;
    height: 100%;
}

.stat-tile .stat-value {
    font-size: 1.6rem;
    font-weight: 600;
    line-height: 1.1;
    color: #fff;
}

.stat-tile .stat-label {
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--halsys-text-dim);
    font-weight: 600;
}

.empty-state {
    background: var(--halsys-surface);
    border: 1px dashed var(--halsys-border-strong);
    border-radius: 6px;
    padding: 2rem;
    text-align: center;
    color: var(--halsys-text-muted);
}

.form-help {
    font-size: 0.82rem;
    color: var(--halsys-text-muted);
}

/*
   A label carrying background detail in its title attribute. Rationale that is useful the first time
   and noise thereafter lives here rather than as permanent text under the field, so the form stays
   readable once you know the system. The dotted underline is the only hint that there is more.
*/
.form-label.has-hint {
    text-decoration: underline dotted var(--halsys-border-strong);
    text-underline-offset: 3px;
    cursor: help;
}

.form-label.has-hint:hover {
    text-decoration-color: var(--halsys-text-muted);
}

/* Sign-in is the only page with no navigation, so it carries the brand as a wash of colour rather
   than as a single mark. */
.auth-page {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    background:
        radial-gradient(1100px 520px at 50% -12%, rgba(185, 45, 45, 0.20), transparent 70%),
        var(--halsys-bg);
    padding: 2rem;
}

.auth-brand {
    text-align: center;
    margin-bottom: 1.75rem;
}

.auth-brand-logo {
    height: 60px;
    width: auto;
    /* The baked-in transparent padding already separates the wordmark from the product name below,
       so no extra margin here. */
}

.auth-brand-product {
    color: var(--halsys-text);
    font-weight: 600;
    font-size: 1.05rem;
    letter-spacing: 0.02em;
}

.auth-card {
    background: var(--halsys-surface);
    border: 1px solid var(--halsys-border);
    border-radius: 8px;
    padding: 2rem;
    width: 100%;
    max-width: 420px;
    box-shadow: 0 18px 44px rgba(0, 0, 0, 0.55);
}

.btn-primary {
    --bs-btn-hover-bg: var(--halsys-brand-hover);
    --bs-btn-hover-border-color: var(--halsys-brand-hover);
    --bs-btn-active-bg: var(--halsys-brand-active);
    --bs-btn-active-border-color: var(--halsys-brand-active);
}

/*
   The brand tone and the danger tone are only a few percent apart in lightness, which would leave the
   deploy wizard's production button (btn-danger) looking identical to an ordinary one (btn-primary).
   A lighter ring and an outward glow make the destructive button visibly hotter without changing its
   hue — so the distinction survives even though both are red.

   Nothing safety-critical depends on this alone: the wizard also carries the PRODUCTION badge, a red
   scope banner, a red warning panel, a mandatory reason, and a typed-name confirmation.
*/
.btn-danger {
    --bs-btn-hover-bg: var(--halsys-danger-hover);
    --bs-btn-hover-border-color: var(--halsys-danger-hover);
    box-shadow: 0 0 0 1px rgba(255, 140, 130, 0.35), 0 2px 12px rgba(204, 47, 47, 0.38);
}

.btn-danger:hover {
    box-shadow: 0 0 0 1px rgba(255, 160, 150, 0.5), 0 3px 16px rgba(204, 47, 47, 0.5);
}

.btn-outline-secondary {
    --bs-btn-color: var(--halsys-text-muted);
    --bs-btn-border-color: var(--halsys-border-strong);
    --bs-btn-hover-bg: var(--halsys-surface-3);
    --bs-btn-hover-color: var(--halsys-text);
    --bs-btn-hover-border-color: var(--halsys-border-strong);
}

/* The colour is set as a property, not only as --bs-btn-color: Bootstrap's own .btn-outline-danger
   still won the `color` declaration, leaving the resting text at its default #dc3545 (3.76:1). */
.btn-outline-danger {
    --bs-btn-color: var(--halsys-danger-text);
    --bs-btn-border-color: var(--halsys-danger-border);
    --bs-btn-hover-bg: var(--halsys-danger);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-border-color: var(--halsys-danger);
    color: var(--halsys-danger-text);
    border-color: var(--halsys-danger-border);
}

.btn-outline-danger:hover,
.btn-outline-danger:focus-visible,
.btn-outline-danger:active {
    color: #fff;
    background-color: var(--halsys-danger);
    border-color: var(--halsys-danger);
}

.btn-link {
    --bs-btn-color: var(--halsys-text-muted);
    --bs-btn-hover-color: #fff;
}

.spinner-border {
    color: var(--halsys-brand-hover);
}

#blazor-error-ui {
    background: var(--halsys-danger);
    color: #fff;
    bottom: 0;
    box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.6);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1060;
}

#blazor-error-ui .reload {
    color: #fff;
    text-decoration: underline;
}

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

.blazor-error-boundary {
    background: var(--halsys-danger-tint);
    border: 1px solid var(--halsys-danger-border);
    border-radius: 6px;
    padding: 1rem;
    color: var(--halsys-danger-text);
}
