/* The two Systemkarta faces (DESIGN.md): Hanken Grotesk carries the UI, Fragment Mono carries
   everything that reads as data (hostnames, env vars, SEK, timestamps, section labels). Both
   OFL-licensed and self-hosted — no font CDN in the portal. Variable weight file for Hanken
   (headings run 800); Fragment Mono ships 400 only, so bold data text is a defect, not a font. */
@font-face {
    font-family: 'Hanken Grotesk';
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url('/fonts/hanken-grotesk/hanken-grotesk-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'Hanken Grotesk';
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url('/fonts/hanken-grotesk/hanken-grotesk-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: 'Fragment Mono';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('/fonts/fragment-mono/fragment-mono-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'Fragment Mono';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('/fonts/fragment-mono/fragment-mono-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* Hostport design tokens — the Systemkarta slate family (DESIGN.md; owner-pinned
   #23303f / #2d3e50 / #6e92c0, 2026-08-06). The panels and text ramp were already this
   family; the re-anchor moved the grounds up to it and swapped the state trio. */

:root {
    /* Brand */

--hp-primary: #6e92c0;
--hp-primary-dark: #5579a7;
--hp-primary-light: #88a8cf;
--hp-primary-accent: #a6bfe0;
--hp-primary-muted: rgba(110, 146, 192, 0.18);

/* Backgrounds. deepest = DESIGN's --deep (header/nav/log wells), dark = --gnd (the page
   ground the content area shows). base has no DESIGN counterpart — it is the interpolated
   step between ground and surface so the ladder stays monotonic. */

--hp-bg-deepest: #1b2634;
--hp-bg-dark: #23303f;
--hp-bg-base: #243241;

--hp-surface: #263444;
--hp-surface-raised: #2d3e50;
--hp-surface-overlay: #34495d;
--hp-surface-highlight: #3e566d;
/* Translucent rather than flat: it backs table headers that sit on several different
   surface steps, so it must tint whatever is underneath instead of picking one. */
--hp-surface-muted: rgba(110, 146, 192, 0.06);
/* The hover wash on transparent controls (menu rows, disclosures). Same reason as above: these
   sit on the rail, on cards and inside alerts, so it lifts whatever is behind it. */
--hp-surface-hover: rgba(255, 255, 255, 0.06);

/* Borders */

--hp-border: rgba(110, 146, 192, 0.28);
--hp-border-subtle: rgba(110, 146, 192, 0.14);

/* Text */

--hp-text: #edf2f8;
--hp-text-secondary: #d6e0ec;
--hp-text-muted: #b8c7d8;
/* Disabled controls only (WCAG exempts them): 4.19:1 on --hp-surface-raised, under the
   4.5:1 floor — readable text, however dim (state words, the register TYPE column),
   takes --hp-text-muted instead. */
--hp-text-disabled: #8fa2b8;

/* Semantic — the Systemkarta state trio. Computed pairs (WCAG):
   success 6.4:1 on --hp-bg-dark, 5.2:1 on --hp-surface-raised — text-safe where state
   words render; warning 7.2:1 / 5.9:1 — text-safe everywhere it appears.
   danger #e5655a is pinned by DESIGN.md but measures 3.3–4.1:1 on the surfaces — a UI
   color (borders, fills, icons ≥3:1; stat values are large text), NEVER small text.
   Small danger text takes --hp-danger-light: same hue lightened until it clears 4.5:1
   on every surface it sits on, including --hp-surface-overlay (4.8:1), where the old
   value shipped at 3.56:1. */

--hp-success: #45c98f;
--hp-warning: #f0b429;
--hp-danger: #e5655a;
--hp-danger-light: #f1a89f;
/* Badge text follows the danger-light precedent: the state hue lightened until 12 px text clears
   4.5:1 on its own tint over every surface, --hp-surface-overlay included (success 4.7:1, warning
   4.6:1); the pinned state colours measured 4.4:1 there on --hp-surface-raised and 3.8:1 on the overlay. */
--hp-success-light: #7dd9b1;
--hp-warning-light: #f4ca69;
--hp-info: var(--hp-primary-light);

/* Env-var names on attachment chips (DESIGN.md): 9.1:1 on --hp-surface-raised, 12.6:1 on
   the chip's own dark well. */
--hp-attachment-label: #ffe9a8;

/* Filled-button fills. The pinned state trio are UI colours: #edf2f8 on them measures 3.2:1
   (primary), 2.1:1 (success) and 3.3:1 (danger), so every filled button takes a darker shade of
   the same hue — the precedent --hp-gradient-primary set for the primary button. Computed with
   --hp-text: primary 5.4:1, success 4.7:1, danger 5.0:1; the hover shades 6.3 / 6.2 / 6.3. */
--hp-primary-fill-hover: #3f5a7f;
--hp-success-fill: #1f7a54;
--hp-success-fill-hover: #196545;
--hp-danger-fill: #b83d33;
--hp-danger-fill-hover: #9e332b;

/* Terminal — log wells sit on DESIGN's --deep, same as header/nav */

--hp-terminal-bg: #1b2634;
--hp-terminal-text: #d4d4d4;
--hp-terminal-muted: #8d94a0;
--hp-terminal-border: rgba(110, 146, 192, 0.35);
--hp-terminal-error: var(--hp-danger);
--hp-terminal-warn: var(--hp-warning);
--hp-terminal-info: var(--hp-primary-accent);

/* Surface fills. The -gradient- names are historical: every value went flat in the 2026-08-05
   minimal pass (owner brief: clean, no gradients), and keeping the names meant zero consumer
   churn across four stylesheets. */

--hp-gradient-brand: #23303f;

/* At or above 4.5:1 against --hp-text: the old #6e92c0 gradient stop put the PRIMARY
   BUTTON's label at 2.8:1. Brightness for the brand lives in accents and links, not
   under text. */
--hp-gradient-primary: #46648c;

--hp-gradient-header: #5579a7;

--hp-gradient-content: #23303f;

--hp-gradient-shell: var(--hp-gradient-content);

/* Effects */

--hp-glow: rgba(110,146,192,.20);
--hp-glow-subtle: rgba(110,146,192,.12);

--hp-shadow: 0 1px 3px rgba(5,10,18,.50);

--hp-shadow-sm: 0 1px 2px rgba(5,10,18,.35);

--hp-shadow-md: 0 2px 6px rgba(5,10,18,.40);

--hp-focus-ring:
    0 0 0 3px rgba(110,146,192,.32);

/* Radius
   These were referenced 59 times across Hostport and Lib/Ui while being defined only in
   Cupo — so 52 declarations computed to border-radius: 0, including .hp-card. Every card
   built on the shared primitive rendered square next to every raw RadzenCard at 4px.
   Never reintroduce a var(--hp-radius*, <literal>) fallback: the seven that existed
   disagreed with each other (8/10/12/16px), which is what kept the gap invisible. */

--hp-radius-xs: 3px;
--hp-radius-sm: 4px;
--hp-radius: 6px;
--hp-radius-lg: 8px;
--hp-radius-pill: 999px;
--hp-radius-round: 50%;

/* Stated, not inherited: Radzen's own default is 4px, and binding it here is what keeps
   RadzenCard and HpCard visually indistinguishable. */
--rz-border-radius: var(--hp-radius-xs);

/* Systemkarta glyph metrics (HpServiceGlyph in Lib/Ui). Defined here and not in hp-ui.css
   because Lib/Ui is frozen at zero literals; Cupo must define these before it renders
   glyphs. Values are the approved comps' px at scale 1; --hp-glyph-scale multiplies every
   glyph dimension and is overridden inline by the component. */

--hp-glyph-scale: 1;
--hp-glyph-tile-radius: 9px;
--hp-glyph-cyl-rx: 16px;
--hp-glyph-cyl-ry: 9px;
--hp-glyph-hero-rx: 48px;
--hp-glyph-hero-ry: 26px;
--hp-glyph-torso-radius-top: 7px;
--hp-glyph-torso-radius-bottom: 2px;
--hp-glyph-font-mark: 13px;
--hp-glyph-font-arrow: 14px;
/* Type floor (2026-09-01): the comps were drawn at 2000px and their 8.5–10px labels rendered
   unreadable on a phone. Nothing prints under 10px; the section grammar sits at 11px. */
--hp-glyph-font-name: 11.5px;
--hp-glyph-font-meta: 10px;
--hp-glyph-font-hero-name: 13px;
--hp-glyph-font-hero-meta: 10.5px;

/* Systemkarta map metrics (HpSystemMap) */

--hp-map-zone-radius: 14px;
--hp-map-font-chip: 10px;
--hp-map-font-zone: 11px;
--hp-map-font-zone-sub: 10px;
--hp-map-font-legend: 10px;

/* Systemkarta registry/table + SEK panel type (comp 18's "tables everywhere" grammar) */

--hp-sk-font-label: 11px;
--hp-sk-font-ty: 10px;
--hp-sk-font-row: 13.5px;
--hp-sk-font-data: 12px;
--hp-sk-font-state: 11px;
--hp-sk-font-big: 30px;
--hp-sk-font-state-line: 15px;
--hp-rail-font-label: 10px;

/* Type scale — fixed rem, never clamp()/vw.
   Radzen's own heading scale is fluid, so before this bridge existed the portal ran two
   scales at once: a RadzenText H6 (clamp(1rem, 1.667vw, 1.25rem)) rendered 25% LARGER on a
   wide screen than the HpSection <h2> above it (1rem), inverting the hierarchy as the
   browser widened and contradicting the DOM order. Restating Radzen's tokens on this scale
   is the only fix that does not touch 678 RadzenText call sites. */

--hp-font-3xs: 0.625rem;
--hp-font-2xs: 0.75rem;
--hp-font-xs: 0.8125rem;
--hp-font-sm: 0.875rem;
--hp-font-md: 1rem;
--hp-font-lg: 1.125rem;
--hp-font-xl: 1.25rem;
--hp-font-2xl: 1.5rem;
--hp-font-3xl: 1.75rem;
--hp-font-4xl: 2rem;
--hp-font-5xl: 2.25rem;
--hp-font-6xl: 2.5rem;

/* Radzen bridge. Body/subtitle/caption/overline are restated, not changed — Radzen's
   values are already identical to this scale, so those (the large majority of call sites)
   move by exactly 0px. Only the six heading steps actually change. H4 lands on the same
   1.75rem as HpPageHeader so the RadzenText page titles that still exist match the
   design-system header instead of out-sizing it. */
--rz-text-h1-font-size: var(--hp-font-6xl);
--rz-text-h2-font-size: var(--hp-font-5xl);
--rz-text-h3-font-size: var(--hp-font-4xl);
--rz-text-h4-font-size: var(--hp-font-3xl);
--rz-text-h5-font-size: var(--hp-font-xl);
--rz-text-h6-font-size: var(--hp-font-md);
--rz-text-body1-font-size: var(--hp-font-md);
--rz-text-body2-font-size: var(--hp-font-sm);
--rz-text-subtitle1-font-size: var(--hp-font-md);
--rz-text-subtitle2-font-size: var(--hp-font-sm);
--rz-text-caption-font-size: var(--hp-font-2xs);
--rz-text-overline-font-size: var(--hp-font-3xs);

/* Shared Hp* component tokens (Lib/Ui, _content/Ui/hp-ui.css) — Hostport values */

--hp-page-header-gap-bottom: 1.5rem;
--hp-page-header-title-size: var(--hp-font-3xl);
--hp-page-header-subtitle-size: 0.95rem;

--hp-card-bg: var(--hp-surface-raised);
--hp-card-header-padding: 1.25rem 1.5rem;
/* A flat overlay, not --hp-gradient-header: the gradient's light stop rendered every accent
   card title at 2.2:1. The left-rule grammar carries the accent now. */
--hp-card-header-bg: var(--hp-surface-overlay);
--hp-card-header-font-size: var(--hp-font-md);
--hp-card-header-border: none;

--hp-stat-card-bg: var(--hp-surface-raised);
--hp-stat-value-size: var(--hp-font-2xl);
--hp-stat-label-weight: 400;
--hp-stat-label-transform: none;
--hp-stat-label-letter-spacing: normal;
--hp-stat-label-margin: 0 0 0.25rem;

--hp-empty-state-padding: 2.5rem 1.5rem;
--hp-empty-state-icon-size: 3.5rem;
--hp-empty-state-title-size: var(--hp-font-lg);
--hp-empty-state-description-size: 0.9375rem;
--hp-empty-state-actions-margin-top: 0.5rem;

--hp-section-margin-bottom: 1.5rem;
--hp-section-title-size: var(--hp-font-md);

    /* The one mono stack for everything that reads as data — previously four ad-hoc stacks plus
   literal 'monospace' (Courier on most platforms) in the build-log terminal of all places. */
--hp-font-mono: 'Fragment Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;

/* Spacing ladder, 4px base. New spacing uses a step; the 29 ad-hoc rem values already in the
   sheets migrate opportunistically as their components are touched. */
--hp-space-1: 0.25rem;
--hp-space-2: 0.5rem;
--hp-space-3: 0.75rem;
--hp-space-4: 1rem;
--hp-space-6: 1.5rem;
--hp-space-8: 2rem;
--hp-space-12: 3rem;

/* Code editor (HpCodeEditor) default height; the component overrides it per instance on its host. */
--hp-code-editor-height: 24rem;

/* Z ladder. The 20 magic values in circulation map here; the two files that disagreed about the
   skip link (10000 vs 10001) both mean --hp-z-skip-link now. */
--hp-z-raised: 30;
--hp-z-header: 1100;
--hp-z-drawer: 1300;
--hp-z-dialog: 1500;
--hp-z-palette: 2000;
--hp-z-toast: 4000;
--hp-z-skip-link: 10000;
/* Circuit-death banner and crash guard: nothing may cover the way out of a dead app. */
--hp-z-crash: 10010;
--hp-brand-font: 'Hanken Grotesk', ui-sans-serif, system-ui, sans-serif;
    /* Radzen's interactive <link> re-appends itself after this sheet at runtime, so its
       body { font-family: var(--rz-text-font-family) } can win the cascade — remapping the
       token is what holds regardless of stylesheet order. */
    --rz-text-font-family: var(--hp-brand-font);

    --rz-primary: var(--hp-primary);
    --rz-primary-light: var(--hp-primary-light);
    --rz-primary-lighter: var(--hp-primary-muted);
    --rz-primary-dark: var(--hp-primary-dark);
    --rz-primary-darker: #3a555b;

    /* Radzen disables by dropping the whole button to 20% opacity, which on this dark ground
       flattens a primary button to 1.56:1 label-on-fill — invisible, not disabled. The state is
       authored explicitly further down instead. */
    --rz-button-disabled-opacity: 1;
    --rz-body-background-color: var(--hp-bg-dark);
    --rz-base-background-color: var(--hp-surface);

    --rz-base-50: #e8f0f2;
    --rz-base-100: #e8f0f2;
    --rz-base-200: #dce8eb;
    --rz-base-300: #d4e3e6;
    --rz-base-400: #c5d8dc;
    --rz-base-500: #a8bcc1;
    --rz-base-600: #9fb4b9;
    --rz-base-700: var(--hp-surface-highlight);
    --rz-base-800: var(--hp-surface-raised);
    --rz-base-900: var(--hp-surface);
    --rz-base-dark: var(--hp-bg-base);
    --rz-base-darker: var(--hp-bg-dark);

    --rz-text-color: var(--hp-text);
    --rz-text-title-color: var(--hp-text);
    --rz-text-secondary-color: var(--hp-text-secondary);
    --rz-text-tertiary-color: var(--hp-text-muted);
    --rz-text-disabled-color: var(--hp-text-disabled);
    --rz-text-contrast-color: var(--hp-text);

    --rz-input-value-color: var(--hp-text);
    --rz-input-placeholder-color: var(--hp-text-muted);
    --rz-input-disabled-color: var(--hp-text-disabled);
    --rz-form-field-label-color: var(--hp-text-secondary);
    --rz-form-field-label-focus-color: var(--hp-primary-accent);

    --rz-grid-header-color: var(--hp-text-secondary);
    --rz-grid-cell-color: var(--hp-text);
    --rz-grid-footer-color: var(--hp-text-muted);

    --rz-breadcrumb-item-color: var(--hp-text-muted);
    --rz-breadcrumb-item-active-color: var(--hp-text);
    --rz-breadcrumb-item-hover-color: var(--hp-text-secondary);

    --rz-panel-menu-item-color: var(--hp-text-secondary);
    --rz-panel-menu-item-background-color: transparent;
    --rz-panel-menu-item-hover-color: var(--hp-text);
    --rz-panel-menu-item-hover-background-color: var(--hp-primary-muted);
    --rz-panel-menu-item-active-color: var(--hp-primary-accent);
    --rz-panel-menu-item-active-background-color: var(--hp-primary-muted);
    --rz-panel-menu-item-2nd-level-color: var(--hp-text-muted);
    --rz-panel-menu-item-2nd-level-background-color: transparent;
    --rz-panel-menu-item-2nd-level-hover-color: var(--hp-text);
    --rz-panel-menu-item-2nd-level-hover-background-color: var(--hp-primary-muted);
    --rz-panel-menu-item-2nd-level-active-color: var(--hp-primary-accent);
    --rz-panel-menu-item-2nd-level-active-background-color: var(--hp-primary-muted);

    --rz-listbox-item-color: var(--hp-text-secondary);

    --rz-menu-item-color: var(--hp-text-secondary);
    --rz-menu-item-icon-color: var(--hp-text-muted);
    --rz-menu-top-item-color: var(--hp-text-secondary);

    --rz-pager-summary-color: var(--hp-text-muted);
    --rz-pager-numeric-button-color: var(--hp-text-secondary);
    --rz-steps-title-color: var(--hp-text-muted);
    --rz-steps-number-color: var(--hp-text-secondary);

    --hp-alert-surface: var(--hp-surface-raised);
    --hp-alert-info-bg: color-mix(in srgb, var(--hp-primary) 22%, transparent);
    --hp-alert-success-bg: color-mix(in srgb, var(--hp-success) 16%, transparent);
    --hp-alert-warning-bg: color-mix(in srgb, var(--hp-warning) 16%, transparent);
    --hp-alert-danger-bg: color-mix(in srgb, var(--hp-danger) 16%, transparent);

    --rz-success: var(--hp-success);
    --rz-success-lighter: var(--hp-alert-success-bg);
    --rz-warning: var(--hp-warning);
    --rz-warning-lighter: var(--hp-alert-warning-bg);
    --rz-danger: var(--hp-danger);
    --rz-danger-lighter: var(--hp-alert-danger-bg);
    --rz-info: var(--hp-info);
    --rz-info-lighter: var(--hp-alert-info-bg);

    --rz-on-success-lighter: var(--hp-text);
    --rz-on-warning-lighter: var(--hp-text);
    --rz-on-danger-lighter: var(--hp-text);
    --rz-on-info-lighter: var(--hp-text);
    --rz-on-primary-lighter: var(--hp-text);

    --rz-alert-background-color: var(--hp-alert-surface);
    --rz-alert-color: var(--hp-text);
    --rz-alert-title-color: var(--hp-text);
    --rz-alert-icon-color: var(--hp-text-secondary);

    --rz-dialog-background-color: var(--hp-surface-raised);
    --rz-dialog-title-background-color: var(--hp-surface);
    --rz-dialog-title-color: var(--hp-text);
    --rz-dialog-close-color: var(--hp-text-muted);
    --rz-dialog-close-hover-color: var(--hp-text);
    --rz-dialog-mask-background-color: rgba(8, 18, 20, 0.72);
    --rz-dialog-shadow: var(--hp-shadow);
    --rz-dialog-border-radius: var(--hp-radius);

    --rz-notification-shadow: var(--hp-shadow-sm);
    --rz-notification-border-radius: var(--hp-radius-sm);
    --rz-notification-success-background-color: var(--hp-surface-raised);
    --rz-notification-success-color: var(--hp-text);
    --rz-notification-success-icon-color: var(--hp-success);
    --rz-notification-warning-background-color: var(--hp-surface-raised);
    --rz-notification-warning-color: var(--hp-text);
    --rz-notification-warning-icon-color: var(--hp-warning);
    --rz-notification-error-background-color: var(--hp-surface-raised);
    --rz-notification-error-color: var(--hp-text);
    --rz-notification-error-icon-color: var(--hp-danger);
    --rz-notification-info-background-color: var(--hp-surface-raised);
    --rz-notification-info-color: var(--hp-text);
    --rz-notification-info-icon-color: var(--hp-primary-accent);

    /* danger-light, not danger: validator messages are small text on panel surfaces, where the
       pinned #e5655a sits under 4.5:1 (see the state-trio comment). */
    --rz-form-error-color: var(--hp-danger-light);
    --rz-validator-background-color: var(--hp-surface-overlay);
    --rz-validator-color: var(--hp-text);

    --rz-tooltip-background-color: var(--hp-surface-overlay);
    --rz-tooltip-color: var(--hp-text);

    --rz-outline-color: var(--hp-primary-accent);
    --rz-link-color: var(--hp-primary-accent);
    --rz-focus-outline-color: var(--hp-primary);

    /* SK-9 state sweep. Every hover/selected state below rides Radzen's --rz-secondary teal (or
       its base ramp) until pinned, and --rz-secondary itself must stay stock — it doubles as the
       .rz-color-secondary TEXT colour (see the secondary-button rule). So the pinning happens at
       the component-variable level, one state at a time. */

    /* Inputs: an authored well. software-dark's fill is its own palette's, and the hairline
       family becomes the periwinkle --line ramp (DESIGN.md) everywhere a border-normal renders. */
    --rz-input-background-color: var(--hp-bg-deepest);
    --rz-input-disabled-background-color: var(--hp-surface-overlay);
    --rz-border-normal: 1px solid var(--hp-border);
    --rz-border-hover: 1px solid var(--hp-primary);
    --rz-border-focus: 1px solid var(--hp-primary);
    --rz-border-disabled: 1px solid var(--hp-border-subtle);

    --rz-dropdown-open-background-color: var(--hp-surface-raised);
    --rz-dropdown-panel-shadow: var(--hp-shadow-md);
    --rz-dropdown-item-hover-background-color: var(--hp-surface-hover);
    --rz-dropdown-item-hover-color: var(--hp-text);
    --rz-dropdown-item-selected-background-color: var(--hp-primary-muted);
    --rz-dropdown-item-selected-color: var(--hp-primary-accent);
    --rz-dropdown-item-selected-hover-background-color: color-mix(in srgb, var(--hp-primary) 30%, transparent);
    --rz-dropdown-item-selected-hover-color: var(--hp-text);

    /* SplitButton popups and menus share the menu-item family. */
    --rz-menu-background-color: var(--hp-surface-raised);
    --rz-menu-border: 1px solid var(--hp-border);
    --rz-menu-item-hover-background-color: var(--hp-surface-hover);
    --rz-menu-item-hover-color: var(--hp-text);
    --rz-menu-item-icon-hover-color: var(--hp-text);
    --rz-menu-item-selected-color: var(--hp-primary-accent);
    --rz-menu-top-item-hover-color: var(--hp-text);
    --rz-menu-top-item-icon-hover-color: var(--hp-text);
    --rz-menu-top-item-selected-color: var(--hp-primary-accent);
    --rz-splitbutton-menu-shadow: var(--hp-shadow-md);

    /* Selected day fill is the primary BUTTON fill, not --hp-primary: the day number is small
       text and #6e92c0 puts it at 2.4:1. Same reasoning as --hp-gradient-primary's own comment. */
    --rz-datepicker-panel-background-color: var(--hp-surface-raised);
    --rz-datepicker-panel-border: 1px solid var(--hp-border);
    --rz-datepicker-panel-shadow: var(--hp-shadow-md);
    --rz-datepicker-header-background-color: var(--hp-surface-raised);
    --rz-datepicker-calendar-hover-background-color: var(--hp-surface-hover);
    --rz-datepicker-calendar-hover-color: var(--hp-text);
    --rz-datepicker-calendar-selected-background-color: var(--hp-gradient-primary);
    --rz-datepicker-calendar-selected-color: var(--hp-text);
    --rz-datepicker-calendar-selected-hover-background-color: var(--hp-primary-dark);
    --rz-datepicker-calendar-selected-hover-color: var(--hp-text);
    --rz-datepicker-calendar-today-color: var(--hp-primary-accent);

    --rz-accordion-hover-color: var(--hp-primary-accent);
    --rz-accordion-selected-color: var(--hp-primary-accent);

    /* Pager: quiet register furniture — transparent chrome, the active page carries the state. */
    --rz-pager-background-color: transparent;
    --rz-pager-back-button-background-color: transparent;
    --rz-pager-next-button-background-color: transparent;
    --rz-pager-numeric-button-background-color: transparent;
    --rz-pager-numeric-button-hover-background-color: var(--hp-surface-hover);
    --rz-pager-numeric-button-hover-color: var(--hp-text);
    --rz-pager-numeric-button-selected-background-color: var(--hp-primary-muted);
    --rz-pager-numeric-button-selected-color: var(--hp-primary-accent);
    --rz-pager-numeric-button-selected-border: 1px solid var(--hp-border);

    --rz-selectbar-background-color: transparent;
    --rz-selectbar-border: 1px solid var(--hp-border);
    --rz-selectbar-selected-background-color: var(--hp-primary-muted);
    --rz-selectbar-selected-color: var(--hp-primary-accent);
    --rz-selectbar-selected-border: 1px solid var(--hp-primary);

    /* No zebra: Radzen alternates rows on its base ramp, which read as a lighter second palette
       on Members, Access control and Sessions. Rows are separated by their hairline. */
    --rz-grid-stripe-background-color: transparent;
    --rz-grid-stripe-odd-background-color: transparent;
    --rz-grid-sort-icon-color: var(--hp-text-muted);
    --rz-grid-header-sorted-background-color: var(--hp-surface-muted);
    --rz-grid-cell-focus-background-color: var(--hp-primary-muted);
    --rz-grid-cell-focus-color: var(--hp-primary-accent);
    --rz-grid-filter-background-color: var(--hp-surface-raised);
    --rz-grid-filter-buttons-background-color: var(--hp-surface-raised);
    --rz-grid-filter-focus-color: var(--hp-primary-accent);
}

html,
body {
    background: var(--hp-bg-deepest);
    color: var(--hp-text);
    font-family: var(--hp-brand-font);
}

.hostport-layout.rz-layout {
    background: var(--hp-gradient-shell);
    min-height: 100vh;
}

.hp-app-header.rz-header > .rz-stack,
.hp-app-header.rz-header > div {
    width: 100%;
}

.hostport-main.rz-body {
    background: transparent;
    /* The nav column is part of the frame (comp 18): it runs flush to the viewport edge, so the
       page gutter lives on .hp-shell-main, not on the body around both. */
    padding: 0;
    /* Radzen promotes the body with translateZ(0), which makes it the containing block for
       every position:fixed descendant — the mobile nav drawer and its backdrop rendered inset
       inside the body's box instead of flush to the viewport. */
    transform: none;
}

/* The surfaces the browser draws itself still carry the design. */

::selection {
    background: color-mix(in srgb, var(--hp-primary) 45%, transparent);
    color: var(--hp-text);
}

:root {
    accent-color: var(--hp-primary);
    scrollbar-color: var(--hp-surface-highlight) transparent;
}

input,
textarea {
    caret-color: var(--hp-primary-accent);
}

.hp-site-footer {
    padding: 1rem 1.5rem 1.25rem;
    text-align: center;
    border-top: 1px solid rgba(255, 255, 255, 0.06);
}

.hp-site-footer-nav {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.8125rem;
}

.hp-site-footer-nav .rz-link {
    color: var(--hp-text-muted);
}

.hp-site-footer-nav .rz-link:hover {
    color: var(--hp-text);
}

.hp-site-footer-sep {
    color: var(--hp-text-muted);
    user-select: none;
}

.main-content {
    position: relative;
    isolation: isolate;
}

.text-muted,
.hp-text-muted {
    color: var(--hp-text-muted) !important;
}

.hp-text-secondary {
    color: var(--hp-text-secondary);
}

/* Dialogs must cover the sticky app header below (z-index 1100) — Radzen's default wrapper
   z-index (1001) left the header painted over modal titles on desktop, and on mobile it sat on
   top of the dialog's close button entirely. Kept under the feedback drawer (1300). Do NOT give
   .rz-dialog-mask a z-index: DialogContainer renders the mask INSIDE the wrapper, after
   .rz-dialog, so its z-index competes with the dialog's own 1001 (--rz-dialog-zindex) in the
   wrapper's local stacking context — any wrapper-scale value dims the dialog itself, which is
   how two releases shipped a mask covering the very dialog it belonged to. The theme default
   (--rz-dialog-mask-zindex: 1000) already sits below the dialog. */
.rz-dialog-wrapper,
.rz-dialog-side-wrapper {
    z-index: 1250;
}

/* A dialog opened from inside a drawer (the publish confirm in the analytics settings drawer, a
   rollback confirm in the deployments drawer) must sit above that drawer's backdrop (1300) and
   panel (1310), or its buttons cannot be reached with the pointer. Scoped to "a drawer is open"
   so the default stacking above still holds when no drawer is up. */
body:has(.hp-drawer-portal .hp-workflow-drawer, .hp-drawer-portal .hp-feedback-drawer) .rz-dialog-wrapper,
body:has(.hp-drawer-portal .hp-workflow-drawer, .hp-drawer-portal .hp-feedback-drawer) .rz-dialog-side-wrapper {
    z-index: 1320;
}

/* App shell header */

.hp-app-header.rz-header {
    position: sticky;
    top: 0;
    z-index: 1100;
    overflow: visible;
    background: var(--hp-bg-deepest);
    border-bottom: 1px solid var(--hp-border);
    box-shadow:
        0 1px 0 color-mix(in srgb, var(--hp-primary) 10%, transparent),
        0 4px 16px rgba(8, 18, 20, 0.22);
    padding: 0;
    min-height: auto;
}

.hp-app-header.rz-header::after {
    content: "";
    position: absolute;
    inset: auto 0 0 0;
    height: 1px;
    background: var(--hp-border-subtle);
    opacity: 0.45;
    pointer-events: none;
}

/* 1fr auto 1fr, not flex: the side clusters differ in width, and search must sit at the TRUE
   center of the header, not the center of whatever space the wider side left over. */
.hp-header-inner {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 1rem;
    width: 100%;
    min-height: 3.5rem;
    padding: 0.5rem 1.25rem;
    box-sizing: border-box;
    overflow: visible;
}

.hp-header-start {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    justify-self: start;
}

.hp-brand-link {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    text-decoration: none;
    color: var(--hp-text);
}

.hp-brand-logo {
    display: block;
    /* Comp 18's header is a slim frame; the wordmark sits small inside 56px, not filling it. */
    height: 1.6rem;
    width: auto;
}

.hp-brand-logo-lg {
    height: 3.4rem;
}

/* The middle zone exists to hold exactly one thing: the search affordance, centered. */
.hp-header-center {
    display: flex;
    justify-content: center;
    min-width: 0;
}

.hp-header-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    justify-self: end;
}

@media (max-width: 1024px) {
    .hp-header-inner {
        padding: 0.5rem 1rem;
    }
}

@media (max-width: 640px) {
    .hp-header-action-label,
    .hp-header-action-chevron,
    .hp-live-chip {
        display: none;
    }

    .hp-header-inner {
        /* auto columns, not 1fr auto 1fr: with fixed thirds the action cluster overflowed the
           right edge on phones — grid items refuse to shrink below their content. */
        grid-template-columns: auto minmax(0, 1fr) auto;
        gap: 0.5rem;
        padding-inline: 0.75rem;
    }

    .hp-header-actions {
        gap: 0.25rem;
    }

    .hp-header-action-btn {
        min-height: 2.5rem;
        min-width: 2.5rem;
        justify-content: center;
    }
}

/* RadzenStack defaults to FlexWrap.NoWrap and writes it as an inline style, so the 160+
   horizontal stacks in this app squash or clip when a phone runs out of row. Wrapping is
   the correct overflow behaviour at this size, and !important is the only way past an
   inline style. Desktop keeps each call site's own wrap choice. */
@media (max-width: 768px) {
    .rz-stack.rz-flex-row {
        flex-wrap: wrap !important;
    }
}

/* Radzen + global brand enforcement */

.rz-button.rz-button-primary,
.rz-button.rz-primary {
    background: var(--hp-gradient-primary);
    border-color: var(--hp-primary);
    color: var(--hp-text);
}

.rz-button.rz-button-primary:not(:disabled):not(.rz-state-disabled):hover,
.rz-button.rz-primary:not(:disabled):not(.rz-state-disabled):hover {
    /* Hover darkens instead of lightening: any lighter stop pushes the label back under 4.5:1. */
    background: var(--hp-primary-fill-hover);
    border-color: var(--hp-primary-light);
}

.rz-button.rz-button-primary:not(:disabled):not(.rz-state-disabled):active,
.rz-button.rz-primary:not(:disabled):not(.rz-state-disabled):active {
    background: var(--hp-primary-dark);
    border-color: var(--hp-primary-dark);
}

/* The rules above never painted a filled button. Radzen paints every filled button through
   .rz-button.<severity>.rz-shade-default — three classes — and its interactive <link> re-appends
   after this sheet, so a two-class rule only ever reached the border: the fill and label underneath
   stayed Radzen's own, and every primary button in the portal rendered white on the raw
   --rz-primary #6e92c0 at 3.21:1 (axe, 39 nodes on 29 pages, 2026-09-01). These match Radzen's
   own specificity and carry the authored fills. check-radzen-state-theming.sh pins them. */
.rz-button.rz-primary.rz-shade-default,
.rz-button.rz-info.rz-shade-default {
    background: var(--hp-gradient-primary);
    border-color: var(--hp-primary);
    color: var(--hp-text);
}

.rz-button.rz-primary.rz-shade-default:not(:disabled):not(.rz-state-disabled):hover,
.rz-button.rz-info.rz-shade-default:not(:disabled):not(.rz-state-disabled):hover {
    background: var(--hp-primary-fill-hover);
    border-color: var(--hp-primary-light);
    color: var(--hp-text);
}

.rz-button.rz-success.rz-shade-default {
    background: var(--hp-success-fill);
    border-color: var(--hp-success-fill);
    color: var(--hp-text);
}

.rz-button.rz-success.rz-shade-default:not(:disabled):not(.rz-state-disabled):hover {
    background: var(--hp-success-fill-hover);
    border-color: var(--hp-success-fill-hover);
    color: var(--hp-text);
}

.rz-button.rz-danger.rz-shade-default {
    background: var(--hp-danger-fill);
    border-color: var(--hp-danger-fill);
    color: var(--hp-text);
}

.rz-button.rz-danger.rz-shade-default:not(:disabled):not(.rz-state-disabled):hover {
    background: var(--hp-danger-fill-hover);
    border-color: var(--hp-danger-fill-hover);
    color: var(--hp-text);
}

/* Warning is the one state whose pinned value carries dark text (8.2:1). */
.rz-button.rz-warning.rz-shade-default {
    background: var(--hp-warning);
    border-color: var(--hp-warning);
    color: var(--hp-bg-deepest);
}

/* Outlined and text variants keep the state as the label colour. Danger goes on the light ramp:
   the pinned #e5655a is 4.0:1 on the page ground and 2.3:1 on a hovered table row. The four-class
   selectors are Radzen's own for these variants. */
.rz-button.rz-variant-outlined.rz-danger.rz-shade-default,
.rz-button.rz-variant-text.rz-danger.rz-shade-default,
.rz-button.rz-variant-flat.rz-danger.rz-shade-default {
    background: transparent;
    border-color: var(--hp-danger);
    color: var(--hp-danger-light);
}

.rz-button.rz-variant-outlined.rz-danger.rz-shade-default:not(:disabled):not(.rz-state-disabled):hover,
.rz-button.rz-variant-text.rz-danger.rz-shade-default:not(:disabled):not(.rz-state-disabled):hover,
.rz-button.rz-variant-flat.rz-danger.rz-shade-default:not(:disabled):not(.rz-state-disabled):hover {
    background: color-mix(in srgb, var(--hp-danger) 14%, transparent);
    border-color: var(--hp-danger-light);
    color: var(--hp-danger-light);
}

.rz-button.rz-variant-outlined.rz-success.rz-shade-default,
.rz-button.rz-variant-text.rz-success.rz-shade-default,
.rz-button.rz-variant-flat.rz-success.rz-shade-default {
    background: transparent;
    border-color: var(--hp-success);
    color: var(--hp-success);
}

.rz-button.rz-variant-outlined.rz-success.rz-shade-default:not(:disabled):not(.rz-state-disabled):hover,
.rz-button.rz-variant-text.rz-success.rz-shade-default:not(:disabled):not(.rz-state-disabled):hover,
.rz-button.rz-variant-flat.rz-success.rz-shade-default:not(:disabled):not(.rz-state-disabled):hover {
    background: color-mix(in srgb, var(--hp-success) 14%, transparent);
    color: var(--hp-success);
}

.rz-button.rz-variant-outlined.rz-primary.rz-shade-default,
.rz-button.rz-variant-text.rz-primary.rz-shade-default,
.rz-button.rz-variant-flat.rz-primary.rz-shade-default {
    background: transparent;
    border-color: var(--hp-primary);
    color: var(--hp-primary-accent);
}

.rz-button.rz-variant-outlined.rz-primary.rz-shade-default:not(:disabled):not(.rz-state-disabled):hover,
.rz-button.rz-variant-text.rz-primary.rz-shade-default:not(:disabled):not(.rz-state-disabled):hover,
.rz-button.rz-variant-flat.rz-primary.rz-shade-default:not(:disabled):not(.rz-state-disabled):hover {
    background: var(--hp-primary-muted);
    color: var(--hp-primary-accent);
}

/* Radzen's stock secondary is a pale teal from its own palette (2.01:1 for the label it ships
   with), and the old override set only border and text — so that fill went on rendering. It has
   to be fixed HERE and not by remapping --rz-secondary: that variable is also the text colour
   behind .rz-color-secondary, so tinting it fades body copy across the app (the onboarding
   banner's subtitle, first). The doubled class outranks Radzen's .rz-button.rz-secondary
   .rz-shade-default, which a two-class selector would lose to. */
.rz-button.rz-button-secondary,
.rz-button.rz-secondary.rz-secondary {
    /* Tint alone is too quiet to bound the control on a warning alert; the border carries the
       boundary at 3.5:1 against every surface a secondary button lands on. */
    background: color-mix(in srgb, var(--hp-primary) 22%, transparent);
    border-color: var(--hp-primary);
    color: var(--hp-text);
}

.rz-button.rz-button-secondary:not(:disabled):not(.rz-state-disabled):hover,
.rz-button.rz-secondary.rz-secondary:not(:disabled):not(.rz-state-disabled):hover {
    background: color-mix(in srgb, var(--hp-primary) 34%, transparent);
    border-color: var(--hp-primary-light);
    color: var(--hp-text);
}

/* Disabled, authored. The repeated class is deliberate: the authored fills above sit at four
   classes (variant + severity + shade), so the disabled state needs five to outrank them whatever
   the order. Inert flatness carries the state, not illegibility. */
.rz-button.rz-state-disabled.rz-state-disabled.rz-state-disabled.rz-state-disabled,
.rz-button.rz-state-disabled.rz-state-disabled.rz-state-disabled.rz-state-disabled:hover,
.rz-button:disabled:disabled:disabled:disabled {
    background: var(--hp-surface-overlay);
    border-color: var(--hp-border-subtle);
    color: var(--hp-text-muted);
    cursor: not-allowed;
    box-shadow: none;
}

/* Radzen's software theme hovers every button with a 3px white inset line along the bottom
   edge — another palette's affordance. Hover feedback here is the fill change, not a stripe. */
.rz-button:not(:disabled):not(.rz-state-disabled):hover {
    box-shadow: none;
}

.rz-button.rz-button-light:not(:disabled):not(.rz-state-disabled):hover,
.rz-button.rz-light.rz-light:not(:disabled):not(.rz-state-disabled):hover {
    background: var(--hp-surface-highlight);
}

/* RadzenBadge severities on the HpBadge grammar (tinted fill, same-hue light text, tinted
   border) — Radzen's own solid fills put small white labels on the raw state colours, where
   danger measures 3.1:1. Secondary/base ride the neutral pair for the same reason the
   secondary button does: --rz-secondary is another palette's teal. */
.rz-badge.rz-badge-success {
    color: var(--hp-success);
    background: color-mix(in srgb, var(--hp-success) 16%, transparent);
    border: 1px solid color-mix(in srgb, var(--hp-success) 30%, transparent);
}

.rz-badge.rz-badge-warning {
    color: var(--hp-warning);
    background: color-mix(in srgb, var(--hp-warning) 16%, transparent);
    border: 1px solid color-mix(in srgb, var(--hp-warning) 30%, transparent);
}

.rz-badge.rz-badge-danger,
.rz-badge.rz-badge-error {
    color: var(--hp-danger-light);
    background: color-mix(in srgb, var(--hp-danger) 16%, transparent);
    border: 1px solid color-mix(in srgb, var(--hp-danger) 30%, transparent);
}

.rz-badge.rz-badge-info,
.rz-badge.rz-badge-primary {
    color: var(--hp-primary-accent);
    background: var(--hp-primary-muted);
    border: 1px solid var(--hp-border);
}

.rz-badge.rz-badge-secondary,
.rz-badge.rz-badge-base,
.rz-badge.rz-badge-light {
    color: var(--hp-text-secondary);
    background: var(--hp-surface-overlay);
    border: 1px solid var(--hp-border-subtle);
}

.rz-link,
a.rz-link {
    color: var(--hp-primary-accent);
}

/* A bare <a> in customer copy (the support drawer's docs link, the access-control "Members"
   sentence) rendered the browser's own #0000ee on slate at 1.01:1. Unclassed anchors read as
   links of the product wherever they render — the drawers portal to <body>, outside the shell
   element, so this is not scoped to it. Radzen's own components carry their classes. */
a:not([class]) {
    color: var(--hp-primary-accent);
    text-decoration: underline;
    text-underline-offset: 0.15em;
}

a:not([class]):hover {
    color: var(--hp-primary-light);
}

.rz-link:hover,
a.rz-link:hover {
    color: var(--hp-primary-light);
}

.rz-steps-item.rz-state-highlight .rz-steps-number {
    background: var(--hp-gradient-primary);
    border-color: var(--hp-primary);
    color: var(--hp-text);
}

.rz-steps-number {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
    padding: 0;
    box-sizing: border-box;
}

.rz-steps-item.rz-state-highlight .rz-steps-title {
    color: var(--hp-primary-accent);
}

.rz-steps-item.rz-state-complete .rz-steps-number {
    background: var(--hp-primary-dark);
    border-color: var(--hp-primary-dark);
}

.rz-progressbar-value {
    background: var(--hp-gradient-primary);
}

.rz-progressbar-circular-value {
    stroke: var(--hp-primary);
}

.rz-checkbox-checked .rz-checkbox-box,
.rz-radiobutton-checked .rz-radiobutton-circle {
    background: var(--hp-primary);
    border-color: var(--hp-primary);
}

.rz-switch-checked .rz-switch-circle {
    background: var(--hp-primary);
}

.rz-slider-handle,
.rz-slider-range {
    background: var(--hp-primary);
}

.rz-panel-menu-item-link.rz-state-active {
    background: var(--hp-primary-muted);
    color: var(--hp-primary-accent);
}

.rz-listbox .rz-listbox-item.rz-state-highlight {
    background: var(--hp-primary-muted);
    color: var(--hp-primary-accent);
}

.rz-datepicker-calendar td .rz-state-active,
.rz-datepicker-calendar td .rz-state-highlight {
    /* Button fill, not --hp-primary: the day number is small text and #6e92c0 puts it at 2.4:1. */
    background: var(--hp-gradient-primary);
    color: var(--hp-text);
}

.rz-chkbox-box.rz-state-active,
.rz-chkbox-box.rz-state-focused {
    border-color: var(--hp-primary);
}

/* RadzenSelectBarItem renders its icon inside a button Radzen classes as text-only, which has no
   icon/text spacing — "</>GitHub repo" ran together. */
.rz-selectbar .rz-button > .rz-button-icon-left {
    margin-inline-end: 0.4rem;
}

*:focus-visible {
    outline: 2px solid var(--hp-primary-accent);
    outline-offset: 2px;
}

.rz-card,
.rz-dialog,
.rz-panel {
    background-color: var(--hp-surface);
    border-color: var(--hp-border-subtle);
}

.rz-datatable,
.rz-grid-table {
    background-color: var(--hp-surface);
}


.hostport-layout .rz-data-grid-data tr:not(.rz-expanded-row-content):hover > td,
.hostport-layout .rz-datatable-data tr:not(.rz-expanded-row-content):hover > td {
    background-color: var(--hp-primary-muted) !important;
}

.hostport-layout .rz-data-grid-data tr.rz-state-highlight:not(.rz-expanded-row-content) > td,
.hostport-layout .rz-datatable-data tr.rz-state-highlight:not(.rz-expanded-row-content) > td {
    background-color: color-mix(in srgb, var(--hp-primary) 32%, transparent) !important;
    color: var(--hp-primary-accent);
}

.hostport-layout .rz-text-body1,
.hostport-layout .rz-text-body2,
.hostport-layout .rz-text-caption,
.hostport-layout .rz-text-overline,
.hostport-layout .rz-text-subtitle1,
.hostport-layout .rz-text-subtitle2 {
    color: var(--hp-text);
}

.hostport-layout .rz-form-field-label,
.hostport-layout .rz-label,
.hostport-layout .rz-chkbox-label,
.hostport-layout .rz-radiobutton-label {
    color: var(--hp-text-secondary);
}

.rz-form-field-content > .rz-dropdown > .rz-dropdown-panel,
.rz-form-field-content > .rz-multiselect > .rz-multiselect-panel {
    display: none !important;
}

.hostport-layout .rz-inputtext,
.hostport-layout .rz-textarea,
.hostport-layout .rz-numeric,
.hostport-layout .rz-colorpicker,
.hostport-layout .rz-autocomplete-input {
    color: var(--hp-text);
}

.hostport-layout .rz-inputtext::placeholder,
.hostport-layout .rz-textarea::placeholder {
    color: var(--hp-text-muted);
    opacity: 1;
}

.hostport-layout .rz-data-grid-data td,
.hostport-layout .rz-data-grid-data .rz-cell-data,
.hostport-layout .rz-datatable-data td,
.hostport-layout .rz-datatable-data .rz-cell-data {
    color: var(--hp-text);
}

.hostport-layout .rz-grid-table thead th,
.hostport-layout .rz-data-grid-header .rz-column-title,
.hostport-layout .rz-datatable-thead th {
    color: var(--hp-text-secondary);
}

.hostport-layout .rz-breadcrumb-item,
.hostport-layout .rz-breadcrumb-item a {
    color: var(--hp-text-muted);
}

.hostport-layout .rz-breadcrumb-item.rz-state-active,
.hostport-layout .rz-breadcrumb-item.rz-state-active a {
    color: var(--hp-text);
}

.hostport-layout .rz-listbox .rz-listbox-item {
    color: var(--hp-text-secondary);
}

.hostport-layout .rz-listbox .rz-listbox-item:hover {
    color: var(--hp-text);
}

.hostport-layout .rz-panel-menu .rz-navigation-item-text,
.hostport-layout .rz-panel-menu .rz-navigation-item-link {
    color: var(--hp-text-secondary);
}

.hostport-layout .rz-panel-menu .rz-navigation-item-link:hover {
    color: var(--hp-text);
}

.hostport-layout .rz-panel-menu .rz-navigation-item-link.rz-state-active {
    color: var(--hp-primary-accent);
}

.hostport-layout .rz-pager-summary,
.hostport-layout .rz-pager-pages .rz-pager-page {
    color: var(--hp-text-muted);
}

.hostport-layout .rz-steps-title {
    color: var(--hp-text-muted);
}

.hostport-layout .rz-steps-item.rz-state-highlight .rz-steps-title {
    color: var(--hp-text);
}

.hostport-layout .rz-fieldset-legend-text {
    color: var(--hp-text-secondary);
}

.hostport-layout .rz-dialog-title,
.hostport-layout .rz-sidebar-title {
    color: var(--hp-text);
}

.hostport-layout .rz-notification-content,
.hostport-layout .rz-alert-content {
    color: var(--hp-text);
}

/* Alerts, dialogs, notifications — global (Radzen portals to body) */

.rz-alert {
    border: 1px solid var(--hp-border-subtle);
}

.rz-alert .rz-alert-title {
    color: var(--hp-text);
    font-weight: 600;
}

/* A readable measure: alert copy used to run the full content width (~190 characters on a wide
   screen), which read as a wall rather than a message. */
.rz-alert .rz-alert-message,
.rz-alert .rz-alert-content {
    max-width: 82ch;
    color: var(--hp-text-secondary);
}

.rz-alert .rz-alert-icon {
    color: var(--hp-text-secondary);
}

/* The close button inside an alert is a text button in the alert's severity at Radzen's
   "darker" shade — a stock teal on every info alert. It is furniture; it takes the text ramp. */
.rz-alert .rz-button.rz-variant-text.rz-shade-darker {
    color: var(--hp-text-secondary);
}

.rz-alert .rz-button.rz-variant-text.rz-shade-darker:not(:disabled):hover {
    color: var(--hp-text);
    background: var(--hp-surface-hover);
}

.rz-alert.rz-info,
.rz-alert.rz-info.rz-shade-lighter,
.rz-alert.rz-info.rz-shade-light {
    background: var(--hp-alert-info-bg);
    border-color: color-mix(in srgb, var(--hp-primary) 42%, transparent);
    border-inline-start: 2px solid var(--hp-primary-accent);
    color: var(--hp-text);
}

/* The icon keeps the accent (a UI colour); the title is small text and the accent measures
   4.39:1 on the info tint. */
.rz-alert.rz-info .rz-alert-icon {
    color: var(--hp-primary-accent);
}

.rz-alert.rz-info .rz-alert-title {
    color: var(--hp-text);
}

.rz-alert.rz-info .rz-alert-message,
.rz-alert.rz-info .rz-alert-content {
    color: var(--hp-text);
}

.rz-alert.rz-success,
.rz-alert.rz-success.rz-shade-lighter,
.rz-alert.rz-success.rz-shade-light {
    background: var(--hp-alert-success-bg);
    border-color: color-mix(in srgb, var(--hp-success) 35%, transparent);
    border-inline-start: 2px solid var(--hp-success);
    color: var(--hp-text);
}

.rz-alert.rz-success .rz-alert-title,
.rz-alert.rz-success .rz-alert-icon {
    color: var(--hp-success);
}

.rz-alert.rz-success .rz-alert-message,
.rz-alert.rz-success .rz-alert-content {
    color: var(--hp-text);
}

.rz-alert.rz-warning,
.rz-alert.rz-warning.rz-shade-lighter,
.rz-alert.rz-warning.rz-shade-light {
    background: var(--hp-alert-warning-bg);
    border-color: color-mix(in srgb, var(--hp-warning) 35%, transparent);
    border-inline-start: 2px solid var(--hp-warning);
    color: var(--hp-text);
}

.rz-alert.rz-warning .rz-alert-title,
.rz-alert.rz-warning .rz-alert-icon {
    color: var(--hp-warning);
}

.rz-alert.rz-warning .rz-alert-message,
.rz-alert.rz-warning .rz-alert-content {
    color: var(--hp-text);
}

.rz-alert.rz-danger,
.rz-alert.rz-error,
.rz-alert.rz-danger.rz-shade-lighter,
.rz-alert.rz-error.rz-shade-lighter,
.rz-alert.rz-danger.rz-shade-light,
.rz-alert.rz-error.rz-shade-light {
    background: var(--hp-alert-danger-bg);
    border-color: color-mix(in srgb, var(--hp-danger) 35%, transparent);
    border-inline-start: 2px solid var(--hp-danger);
    color: var(--hp-text);
}

/* danger-light: the pinned danger measures 2.8:1 on the alert's own tinted background. */
.rz-alert.rz-danger .rz-alert-title,
.rz-alert.rz-error .rz-alert-title,
.rz-alert.rz-danger .rz-alert-icon,
.rz-alert.rz-error .rz-alert-icon {
    color: var(--hp-danger-light);
}

.rz-alert.rz-danger .rz-alert-message,
.rz-alert.rz-error .rz-alert-message,
.rz-alert.rz-danger .rz-alert-content,
.rz-alert.rz-error .rz-alert-content {
    color: var(--hp-text);
}

.rz-alert.rz-light,
.rz-alert.rz-base {
    background: var(--hp-surface);
    border-color: var(--hp-border);
    color: var(--hp-text);
}

.rz-alert.rz-light .rz-alert-title,
.rz-alert.rz-light .rz-alert-message,
.rz-alert.rz-light .rz-alert-content,
.rz-alert.rz-light .rz-alert-icon {
    color: var(--hp-text);
}

.rz-notification {
    inset-block-start: auto;
    inset-block-end: 1rem;
}

.rz-notification-item {
    border: 1px solid var(--hp-border-subtle);
    border-radius: var(--hp-radius-sm);
    box-shadow: var(--hp-shadow-sm);
}

.rz-notification-success .rz-notification-item {
    border-inline-start: 2px solid var(--hp-success);
}

.rz-notification-warn .rz-notification-item {
    border-inline-start: 2px solid var(--hp-warning);
}

.rz-notification-error .rz-notification-item {
    border-inline-start: 2px solid var(--hp-danger);
}

.rz-notification-info .rz-notification-item {
    border-inline-start: 2px solid var(--hp-primary-accent);
}

.rz-notification-content {
    color: var(--hp-text);
}

.rz-notification-close {
    color: var(--hp-text-muted);
}

.rz-notification-close:hover {
    color: var(--hp-text);
}

.rz-dialog,
.rz-dialog-side {
    background: var(--hp-surface-raised);
    border: 1px solid var(--hp-border);
    color: var(--hp-text);
}

.rz-dialog-titlebar,
.rz-dialog-side-titlebar {
    background: var(--hp-surface);
    border-block-end: 1px solid var(--hp-border-subtle);
}

.rz-dialog-title,
.rz-dialog-side-title {
    color: var(--hp-text);
}

.rz-dialog-content,
.rz-dialog-side-content {
    color: var(--hp-text);
    background: var(--hp-surface-raised);
}

.rz-dialog-content .rz-text-body1,
.rz-dialog-content .rz-text-body2,
.rz-dialog-content .rz-text-caption,
.rz-dialog-content .rz-label,
.rz-dialog-content .rz-form-field-label {
    color: var(--hp-text-secondary);
}

.rz-dialog-content .rz-text-subtitle1,
.rz-dialog-content .rz-text-subtitle2,
.rz-dialog-content .rz-text-h6 {
    color: var(--hp-text);
}

.rz-dialog-mask {
    background-color: rgba(8, 18, 20, 0.72);
    opacity: 1;
}

.rz-dialog-confirm-message,
.rz-dialog-alert-message {
    color: var(--hp-text-secondary);
}

.rz-dialog-confirm .rz-button.rz-button-light,
.rz-dialog-alert .rz-button.rz-button-light {
    color: var(--hp-text-secondary);
    border-color: var(--hp-border);
    background: rgba(255, 255, 255, 0.04);
}

.rz-message-popup,
.rz-form-field-error,
.rz-validator {
    background: var(--hp-surface-overlay);
    color: var(--hp-text);
    border: 1px solid var(--hp-border);
}

/* danger-light, not danger: these sit on --hp-surface-overlay, where #e5655a is 2.8:1. */
.rz-form-field-error-message,
.rz-validator-text {
    color: var(--hp-danger-light);
}

.rz-tooltip {
    background: var(--hp-surface-overlay);
    color: var(--hp-text);
    border: 1px solid var(--hp-border);
}

/* Skip link + reduced-motion live in hostport-a11y.css alone — this file used to carry a second
   copy that disagreed about the border and z-index, and always lost (a11y loads last). */

/* ==========================================================================
   Web-app service page — Release rail
   The one-line manifest under the page header (Services/Components/ReleaseRail.razor)
   and the page's single animated element.
   ========================================================================== */

.hp-release-rail {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem 0.6rem;
    padding: 0.625rem 1rem;
    background: var(--hp-surface-raised);
    border: 1px solid var(--hp-border-subtle);
    border-radius: var(--hp-radius);
    font-size: var(--hp-font-sm);
    color: var(--hp-text);
}

.hp-release-rail-seg {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    min-width: 0;
}

.hp-release-rail-seg code {
    font-size: var(--hp-font-xs);
    color: var(--hp-text);
    background: none;
    padding: 0;
}

.hp-release-rail-link {
    border: none;
    background: none;
    padding: 0.1rem 0.15rem;
    margin: 0;
    font: inherit;
    color: inherit;
    cursor: pointer;
    border-radius: var(--hp-radius-xs);
}

.hp-release-rail-link:hover {
    color: var(--hp-primary-accent);
}

.hp-release-rail-link:hover code {
    color: var(--hp-primary-accent);
}

.hp-release-rail-status {
    font-weight: 600;
}

.hp-release-rail-muted {
    color: var(--hp-text-muted);
}

.hp-release-rail-sep {
    color: var(--hp-text-disabled);
    user-select: none;
}

.hp-release-rail-problem,
.hp-release-rail-problem:hover {
    color: var(--hp-danger-light);
}

.hp-release-rail-url {
    gap: 0.3rem;
}

.hp-release-rail-url code {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 20rem;
}

.hp-release-dot {
    position: relative;
    width: 0.625rem;
    height: 0.625rem;
    border-radius: var(--hp-radius-round);
    flex-shrink: 0;
    background: var(--hp-text-disabled);
}

.hp-release-dot-success { background: var(--hp-success); }
.hp-release-dot-warning { background: var(--hp-warning); }
.hp-release-dot-danger  { background: var(--hp-danger); }
.hp-release-dot-neutral { background: var(--hp-text-disabled); }

/* background: inherit lets one ping ring pick up whichever state color the dot has. */
.hp-release-dot-pulse::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: var(--hp-radius-round);
    background: inherit;
    animation: hp-release-pulse 2.6s ease-out infinite;
}

@keyframes hp-release-pulse {
    0%   { transform: scale(1);    opacity: 0.55; }
    70%  { transform: scale(2.4);  opacity: 0; }
    100% { transform: scale(2.4);  opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
    .hp-release-dot-pulse::after {
        display: none;
    }
}

@media (max-width: 640px) {
    .hp-release-rail-url code {
        max-width: 12rem;
    }
}

/* Screen-reader-only text (e.g. the deployment table's unlabeled actions column). */
.hp-visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}
