/* ==========================================================================
   Servyx dashboard shell — shared, page-agnostic building blocks.
   Design tokens live in wwwroot/theme.css (loaded before this file). No
   literal colours belong here — see docs/design/theming-blueprint.md.
   ========================================================================== */

/* -- Blazor validation & error UI ------------------------------------------ */

.valid.modified:not([type=checkbox]) {
    outline: 1px solid var(--svx-success);
}

.invalid {
    outline: 1px solid var(--svx-danger);
}

.validation-message {
    color: var(--svx-danger-fg);
    font-size: var(--svx-text-xs);
}

.blazor-error-boundary {
    padding: var(--svx-space-4);
    border-radius: var(--svx-radius-md);
    border: 1px solid var(--svx-danger-border);
    background: var(--svx-danger-bg);
    color: var(--svx-danger-fg);
}

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

/* -- Page header ----------------------------------------------------------- */

.svx-page-header {
    margin-bottom: 1.25rem;
}

.svx-page-header h2 {
    margin: 0 0 0.25rem 0;
    font-size: var(--svx-text-xl);
    font-weight: var(--svx-weight-bold);
    letter-spacing: -0.01em;
    color: var(--svx-text-primary);
}

.svx-page-description {
    color: var(--svx-text-muted);
    max-width: 62ch;
    margin: 0;
}

/* -- Cards ------------------------------------------------------------------ */

.svx-card {
    background: var(--svx-bg-surface);
    border: 1px solid var(--svx-border-default);
    border-radius: var(--svx-radius-lg);
    padding: var(--svx-space-5);
    box-shadow: var(--svx-shadow-xs);
}

.svx-card + .svx-card {
    margin-top: 1rem;
}

.svx-card h3 {
    font-size: 1rem;
    font-weight: var(--svx-weight-bold);
    margin: 0 0 0.75rem 0;
}

/* -- Stat cards (dashboard summary tiles) ----------------------------------- */

.svx-stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 1rem;
    margin-bottom: 1.5rem;
}

.stat-card {
    display: flex;
    align-items: flex-start;
    gap: 0.85rem;
    background: var(--svx-bg-surface);
    border: 1px solid var(--svx-border-default);
    border-radius: var(--svx-radius-lg);
    padding: 1rem 1.1rem;
}

.stat-card-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: 0.6rem;
    background: var(--svx-accent-subtle);
    color: var(--svx-accent-on-subtle);
    flex: 0 0 auto;
}

.stat-card-body {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.stat-card-value {
    font-size: var(--svx-text-2xl);
    font-weight: var(--svx-weight-bold);
    line-height: 1.2;
    letter-spacing: -0.02em;
    color: var(--svx-text-primary);
    font-variant-numeric: tabular-nums;
}

.stat-card-title {
    text-transform: uppercase;
    font-size: var(--svx-text-2xs);
    letter-spacing: var(--svx-tracking-caps);
    color: var(--svx-text-muted);
}

.stat-card-subtext {
    font-size: 0.72rem;
    color: var(--svx-text-muted);
    margin-top: 0.1rem;
}

/* -- Badges ------------------------------------------------------------------ */

.health-badge, .state-badge, .drift-badge, .trust-badge, .foreign-badge, .binding-status-badge {
    display: inline-flex;
    align-items: center;
    gap: var(--svx-space-1);
    font-size: var(--svx-text-xs);
    font-weight: var(--svx-weight-semibold);
    letter-spacing: var(--svx-tracking-wide);
    padding: 0.1875rem var(--svx-space-2);
    border-radius: var(--svx-radius-full);
    border: 1px solid transparent;
    cursor: default;
    white-space: nowrap;
}

.svx-dot, .health-dot {
    width: 0.4375rem;
    height: 0.4375rem;
    border-radius: 50%;
    display: inline-block;
    flex: 0 0 auto;
}

.health-healthy   { background: var(--svx-success-bg); border-color: var(--svx-success-border); color: var(--svx-success-fg); }
.health-unhealthy { background: var(--svx-danger-bg);  border-color: var(--svx-danger-border);  color: var(--svx-danger-fg);  }
.health-unknown   { background: var(--svx-neutral-bg); border-color: var(--svx-neutral-border); color: var(--svx-neutral-fg); }

.health-healthy   .svx-dot, .health-healthy   .health-dot { background: var(--svx-success-solid); }
.health-unhealthy .svx-dot, .health-unhealthy .health-dot { background: var(--svx-danger-solid);  }
.health-unknown   .svx-dot, .health-unknown   .health-dot { background: var(--svx-neutral-solid); }

.state-running  { background: var(--svx-success-bg); border-color: var(--svx-success-border); color: var(--svx-success-fg); }
.state-stopped,
.state-unknown  { background: var(--svx-neutral-bg); border-color: var(--svx-neutral-border); color: var(--svx-neutral-fg); }
.state-starting,
.state-stopping { background: var(--svx-info-bg);    border-color: var(--svx-info-border);    color: var(--svx-info-fg);    }
.state-crashed  { background: var(--svx-danger-bg);  border-color: var(--svx-danger-border);  color: var(--svx-danger-fg);  }

.drift-none    { background: var(--svx-neutral-bg); border-color: var(--svx-neutral-border); color: var(--svx-neutral-fg); }
.drift-present { background: var(--svx-danger-bg);  border-color: var(--svx-danger-border);  color: var(--svx-danger-fg);  }

.foreign-badge {
    background: var(--svx-neutral-bg);
    border-color: var(--svx-neutral-border);
    color: var(--svx-neutral-fg);
}

/* A server's game-definition binding was not resolved decisively — see BindingStatusBadge.razor. Rendered
   only for the two non-Bound states; Bound is the overwhelmingly common case and shows no badge at all. */
.binding-status-ambiguous  { background: var(--svx-warning-bg); border-color: var(--svx-warning-border); color: var(--svx-warning-fg); }
.binding-status-needsrebind { background: var(--svx-danger-bg);  border-color: var(--svx-danger-border);  color: var(--svx-danger-fg);  }

.binding-status-ambiguous  .svx-dot { background: var(--svx-warning-solid); }
.binding-status-needsrebind .svx-dot { background: var(--svx-danger-solid); }

/* The fuller explanation shown on the server detail page for a non-Bound server — see ServerDetailPage.razor.
   Same visible-not-silently-dropped treatment as .game-card-fault on the Games page. */
.binding-status-notice {
    border: 1px dashed var(--svx-warning-border);
    background: var(--svx-warning-bg);
}

.binding-status-notice-needsrebind {
    border-color: var(--svx-danger-border);
    background: var(--svx-danger-wash);
}

.binding-status-notice h3 { margin-top: 0; }

/* ServerSettingsTab's per-row warning for a Rendered (INI) value that has drifted from Authoritative (.env)
   on a surface that regenerates from .env on restart — SettingState.PendingRegeneration. That drift is not
   durable: the value shown will be replaced by the .env value the next time the derived surface regenerates,
   so whatever is currently live there (an in-progress apply, or an out-of-band edit to the file itself) is
   at risk of being silently discarded. Reuses the warning tokens .binding-status-ambiguous already uses,
   rather than inventing a new severity. */
.ini-drift-warning {
    display: inline-flex;
    margin-left: 0.4rem;
    background: var(--svx-warning-bg);
    border-color: var(--svx-warning-border);
    color: var(--svx-warning-fg);
}

/* F3: .svx-cost was never declared — render cost figures with tabular numbers and semibold weight. */
.svx-cost {
    font-variant-numeric: tabular-nums;
    font-weight: var(--svx-weight-semibold);
    color: var(--svx-text-primary);
}

/* F3: .svx-cost-confidence was never declared and rode entirely on Bootstrap's .badge. */
.svx-cost-confidence {
    display: inline-flex;
    align-items: center;
    padding: 0.1875rem var(--svx-space-2);
    font-size: var(--svx-text-xs);
    font-weight: var(--svx-weight-semibold);
    border-radius: var(--svx-radius-full);
    border: 1px solid var(--svx-neutral-border);
    background: var(--svx-neutral-bg);
    color: var(--svx-neutral-fg);
}

/* -- Live/running treatment — the one "gamer" flourish ----------------------- */

.state-running .svx-dot,
.svx-connection-connected .svx-connection-dot {
    background: var(--svx-live-dot);
    box-shadow: var(--svx-live-glow);
}

.svx-dot-pulse { position: relative; }
.svx-dot-pulse::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: var(--svx-live-halo);
    animation: svx-pulse 2.4s var(--svx-ease) infinite;
}

@keyframes svx-pulse {
    0%   { transform: scale(1);   opacity: 0.7; }
    70%  { transform: scale(2.6); opacity: 0;   }
    100% { transform: scale(2.6); opacity: 0;   }
}

/* -- Gated controls (always-disabled write paths in Milestone 1) ------------- */

.gated-button {
    display: inline-flex;
    align-items: center;
    gap: var(--svx-space-2);
    padding: 0.4375rem 0.8125rem;
    font-size: var(--svx-text-base);
    border-radius: var(--svx-radius-md);
    border: 1px dashed var(--svx-border-strong);
    background: var(--svx-bg-subtle);
    color: var(--svx-text-disabled);
    box-shadow: none;
    cursor: not-allowed;
}
.gated-button:not(:disabled) {
    border: 1px solid var(--svx-accent);
    background: var(--svx-accent);
    color: var(--svx-accent-fg);
    cursor: pointer;
    box-shadow: var(--svx-shadow-xs);
}
.gated-button:not(:disabled):hover { background: var(--svx-accent-hover); border-color: var(--svx-accent-hover); }
.gated-button-compact { padding: var(--svx-space-1) var(--svx-space-2); font-size: var(--svx-text-xs); }

.gated-control {
    position: relative;
    padding: var(--svx-space-2) var(--svx-space-3) var(--svx-space-2) var(--svx-space-8);
    border: 1px dashed var(--svx-border-default);
    border-radius: var(--svx-radius-md);
    background: var(--svx-bg-inset);
}
.gated-control:not([disabled]) { border-style: solid; border-color: var(--svx-border-default); background: transparent; padding-left: var(--svx-space-3); }
.gated-control-lock { position: absolute; left: var(--svx-space-3); top: 0.7rem; color: var(--svx-text-subtle); }
.gated-control[disabled] input,
.gated-control[disabled] select,
.gated-control[disabled] textarea { background: transparent; cursor: not-allowed; }

/* -- Sparkline placeholder ---------------------------------------------------- */

.sparkline {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    color: var(--svx-accent);
}

.sparkline-svg {
    width: 100%;
    max-width: 140px;
    height: 32px;
    stroke-linecap: round;
    stroke-linejoin: round;
}

:root[data-theme="dark"] .sparkline-svg {
    filter: drop-shadow(0 0 3px var(--svx-accent-glow));
}

.sparkline-current {
    font-size: 0.8rem;
    font-weight: var(--svx-weight-bold);
    color: var(--svx-text-primary);
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.sparkline-empty {
    font-size: 0.8rem;
    color: var(--svx-text-muted);
}

/* -- Grid "table" rows (used instead of <table> so a whole row can be one
   accessible, keyboard-operable <a> without click handlers on non-interactive
   elements) --------------------------------------------------------------- */

.svx-row-grid {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.svx-row-grid-header, .svx-row-link {
    display: grid;
    align-items: center;
    gap: 0.75rem;
    padding: 0.7rem 0.9rem;
}

.svx-row-grid-header {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--svx-text-muted);
    padding-bottom: 0.35rem;
}

.svx-row-link {
    background: var(--svx-bg-surface);
    border: 1px solid var(--svx-border-default);
    border-radius: 0.6rem;
    color: inherit;
    text-decoration: none;
}

.svx-row-link:hover {
    border-color: var(--svx-accent-subtle-border);
    background: var(--svx-bg-hover);
}

.svx-row-cell-label {
    font-size: 0.7rem;
    color: var(--svx-text-muted);
    display: none;
}

.svx-ports-cell {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
}

.port-chip {
    font-size: 0.68rem;
    font-family: var(--svx-font-mono);
    background: var(--svx-bg-subtle);
    color: var(--svx-text-muted);
    border-radius: 0.35rem;
    padding: 0.15rem 0.4rem;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.port-chip.port-published {
    background: var(--svx-info-bg);
    color: var(--svx-info-fg);
}

/* -- Empty states -------------------------------------------------------------- */

.svx-empty-state {
    text-align: center;
    padding: var(--svx-space-12) var(--svx-space-6);
    color: var(--svx-text-muted);
    background: var(--svx-bg-surface);
    border: 1px dashed var(--svx-border-default);
    border-radius: var(--svx-radius-lg);
}
.svx-empty-state h3 { color: var(--svx-text-primary); margin-bottom: var(--svx-space-2); font-size: var(--svx-text-md); }
.svx-empty-state p  { max-width: 46ch; margin-left: auto; margin-right: auto; }

/* An empty server list where discovery itself failed — visually distinct from a genuinely empty one, so
   an operator can never mistake "could not be read" for "confirmed zero servers". See Home.razor and
   ServersList.razor's _discoveryFailed handling. */
.svx-empty-state-degraded {
    border: 1px dashed var(--svx-danger-strong);
    background: var(--svx-danger-wash);
    color: var(--svx-danger-fg);
}

.svx-discovery-failed-banner {
    color: var(--svx-danger-fg);
    font-weight: var(--svx-weight-medium);
}

/* Cache-backed pages (Home, ServersList) read from a background-refreshed snapshot instead of a live call;
   an aging one still renders normally, with this small, non-alarming banner rather than the danger-toned
   .svx-empty-state-degraded pattern above — a stale cache is expected, ordinary behaviour, not a fault. Uses
   the --svx-info-* tokens deliberately, never --svx-danger-*. See LiveDashboardDataService's IsStale remarks. */
.svx-stale-banner {
    display: flex;
    align-items: center;
    gap: var(--svx-space-2);
    padding: var(--svx-space-3) var(--svx-space-4);
    margin-bottom: var(--svx-space-4);
    background: var(--svx-info-bg);
    border: 1px solid var(--svx-info-border);
    border-radius: var(--svx-radius-md);
    color: var(--svx-info-fg);
    font-size: var(--svx-text-sm);
}

/* -- Tabs ----------------------------------------------------------------------- */

.svx-tablist {
    display: flex;
    gap: var(--svx-space-1);
    border-bottom: 1px solid var(--svx-border-default);
    margin-bottom: var(--svx-space-5);
    overflow-x: auto;
    scrollbar-width: none;
}

.svx-tab {
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    padding: var(--svx-space-2) var(--svx-space-3);
    margin-bottom: -1px;
    font-size: var(--svx-text-base);
    font-weight: var(--svx-weight-medium);
    color: var(--svx-text-muted);
    cursor: pointer;
    white-space: nowrap;
    transition: color var(--svx-duration-fast) var(--svx-ease);
}

.svx-tab:hover {
    color: var(--svx-text-primary);
}

.svx-tab[aria-selected="true"] {
    color: var(--svx-accent);
    border-bottom-color: var(--svx-accent);
    font-weight: var(--svx-weight-semibold);
}

/* -- Settings four-column table -------------------------------------------------- */

.settings-group {
    margin-bottom: 1.5rem;
}

.settings-group h3 {
    font-size: 0.95rem;
    font-weight: var(--svx-weight-bold);
    margin-bottom: 0.6rem;
}

.settings-grid-header, .settings-row {
    display: grid;
    grid-template-columns: 1.4fr 1fr 1fr 1fr 1fr 1.2fr;
    gap: 0.6rem;
    align-items: center;
    padding: 0.55rem 0.7rem;
}

.settings-grid-header {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--svx-text-muted);
}

.settings-row {
    background: var(--svx-bg-surface);
    border: 1px solid var(--svx-border-default);
    border-radius: 0.5rem;
    margin-bottom: 0.4rem;
}

.settings-row.has-drift {
    border-color: var(--svx-danger-border);
    background: var(--svx-danger-wash);
}

.settings-value {
    font-size: 0.85rem;
    color: var(--svx-text-primary);
    word-break: break-word;
    font-variant-numeric: tabular-nums;
}

.settings-value-muted {
    color: var(--svx-text-muted);
}

.settings-label {
    display: flex;
    flex-direction: column;
}

.settings-label-key {
    font-size: 0.72rem;
    color: var(--svx-text-muted);
    font-family: var(--svx-font-mono);
}

@media (max-width: 900px) {
    .settings-grid-header {
        display: none;
    }

    .settings-row {
        grid-template-columns: 1fr;
    }

    .settings-row > div::before {
        content: attr(data-col-label);
        display: block;
        font-size: 0.68rem;
        text-transform: uppercase;
        color: var(--svx-text-muted);
        margin-bottom: 0.1rem;
    }
}

.svx-dl {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 0.75rem 1.5rem;
    margin: 0;
}

.svx-dl > div {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.svx-dl dt {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--svx-text-muted);
}

.svx-dl dd {
    margin: 0;
    font-size: 0.9rem;
    color: var(--svx-text-primary);
}

.svx-subheading {
    font-size: 0.85rem;
    font-weight: var(--svx-weight-bold);
    margin: 1rem 0 0.5rem 0;
    color: var(--svx-text-muted);
}

.games-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: 1rem;
}

.game-card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

.game-card-header h3 {
    margin: 0;
}

.trust-badge {
    font-size: 0.68rem;
    font-weight: var(--svx-weight-bold);
    padding: 0.25rem 0.55rem;
    border-radius: var(--svx-radius-full);
}

.trust-builtin    { background: var(--svx-success-bg); border-color: var(--svx-success-border); color: var(--svx-success-fg); }
.trust-verified   { background: var(--svx-info-bg);    border-color: var(--svx-info-border);    color: var(--svx-info-fg);    }
.trust-unverified { background: var(--svx-warning-bg); border-color: var(--svx-warning-border);  color: var(--svx-warning-fg); }

.game-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    margin: 0.5rem 0;
}

.deployment-profile-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.deployment-profile-list li {
    border-left: 3px solid var(--svx-border-default);
    padding-left: 0.6rem;
}

.deployment-profile-list p {
    margin: 0.15rem 0 0 0;
    font-size: 0.8rem;
}

/* A definition that failed to load — deliberately as visible as a successful card, never silently dropped
   from the grid. See GamesPage.razor and LiveDashboardDataService.GetGameDefinitionFaultsAsync. */
.game-card-fault {
    border-color: var(--svx-danger-border);
    background: var(--svx-danger-wash);
}

.fault-badge {
    background: var(--svx-danger-bg);
    border-color: var(--svx-danger-border);
    color: var(--svx-danger-fg);
}

.fault-path {
    font-family: var(--svx-font-mono);
    font-size: 0.8rem;
    color: var(--svx-text-primary);
    word-break: break-all;
    margin: 0.5rem 0 0.25rem 0;
}

.fault-message {
    color: var(--svx-danger-fg);
    font-size: 0.85rem;
    margin: 0 0 0.25rem 0;
}

/* -- Console log viewport ------------------------------------------------------- */

.console-viewport {
    background: var(--svx-console-bg);
    color: var(--svx-console-fg);
    font-family: var(--svx-font-mono);
    font-size: 0.8rem;
    border-radius: 0.6rem;
    border: 1px solid var(--svx-console-border);
    padding: 0.85rem 1rem;
    height: 360px;
    overflow-y: auto;
}

.console-line {
    white-space: pre-wrap;
    line-height: 1.5;
}

.console-line-warn {
    color: var(--svx-console-warn);
}

.console-timestamp {
    color: var(--svx-console-dim);
    margin-right: 0.5rem;
}

@media (max-width: 768px) {
    .svx-stat-grid {
        grid-template-columns: 1fr;
    }

    .svx-row-grid-header {
        display: none;
    }

    .svx-row-link {
        grid-template-columns: 1fr !important;
        gap: 0.2rem;
    }

    .svx-row-cell-label {
        display: inline;
    }
}

/* ── Data impact ──────────────────────────────────────────────────────────────
   AtRisk and Destroyed must be unmissable: a loud border, a filled background, and a glyph — not a
   muted badge sitting in a row of muted badges. Preserved is deliberately quiet, so that the loud
   treatment keeps meaning something.

   Styled off the data-severity attribute rather than the svx-data-impact-calm/-danger classes: the
   classes still ride along in markup (DataImpactBanner.razor) but style nothing here — see F2. */

.svx-data-impact {
    display: flex;
    align-items: flex-start;
    gap: var(--svx-space-3);
    margin: var(--svx-space-3) 0;
    padding: var(--svx-space-3) var(--svx-space-4);
    border-radius: var(--svx-radius-md);
    border: 1px solid var(--svx-border-default);
    background: var(--svx-bg-subtle);
}

.svx-data-impact-glyph { font-size: 1.35rem; line-height: 1.1; }
.svx-data-impact-body { flex: 1 1 auto; min-width: 0; }
.svx-data-impact-headline { display: block; font-size: var(--svx-text-md); font-weight: var(--svx-weight-medium); }
.svx-data-impact-detail {
    margin: var(--svx-space-1) 0 0;
    font-size: var(--svx-text-base);
    color: var(--svx-text-muted);
}

.svx-data-impact[data-severity="calm"] {
    border-color: var(--svx-success-border);
    background: var(--svx-success-bg);
}
.svx-data-impact[data-severity="calm"] .svx-data-impact-headline { color: var(--svx-success-fg); }
.svx-data-impact[data-severity="calm"] .svx-data-impact-detail   { color: var(--svx-text-muted); }

.svx-data-impact[data-severity="danger"] {
    border: 2px solid var(--svx-danger-strong);
    background: var(--svx-danger-bg);
    box-shadow: inset 0 0 0 1px var(--svx-danger-wash);
}
.svx-data-impact[data-severity="danger"] .svx-data-impact-headline {
    color: var(--svx-danger-fg);
    font-weight: var(--svx-weight-bold);
    letter-spacing: var(--svx-tracking-caps);
}
.svx-data-impact[data-severity="danger"] .svx-data-impact-detail { color: var(--svx-danger-fg); }

/* ==========================================================================
   Replacement primitives for the removed Bootstrap surface.
   ========================================================================== */

.svx-btn {
    display: inline-flex; align-items: center; justify-content: center;
    gap: var(--svx-space-2);
    padding: 0.4375rem 0.8125rem;
    font-size: var(--svx-text-base);
    font-weight: var(--svx-weight-medium);
    line-height: 1.25;
    border-radius: var(--svx-radius-md);
    border: 1px solid var(--svx-border-strong);
    background: var(--svx-bg-surface);
    color: var(--svx-text-primary);
    box-shadow: var(--svx-shadow-xs);
    transition: background var(--svx-duration-fast) var(--svx-ease),
                border-color var(--svx-duration-fast) var(--svx-ease),
                color var(--svx-duration-fast) var(--svx-ease);
    white-space: nowrap;
}
.svx-btn:hover:not(:disabled) { background: var(--svx-bg-hover); }
.svx-btn:active:not(:disabled) { background: var(--svx-bg-active); box-shadow: none; }
.svx-btn:disabled { opacity: 0.55; box-shadow: none; }

.svx-btn-primary { background: var(--svx-accent); border-color: var(--svx-accent); color: var(--svx-accent-fg); }
.svx-btn-primary:hover:not(:disabled) { background: var(--svx-accent-hover); border-color: var(--svx-accent-hover); }
.svx-btn-primary:active:not(:disabled) { background: var(--svx-accent-active); border-color: var(--svx-accent-active); }

.svx-btn-danger { background: var(--svx-danger); border-color: var(--svx-danger); color: #FFFFFF; }
:root[data-theme="dark"] .svx-btn-danger { color: var(--svx-gray-1000); }

.svx-btn-ghost { background: transparent; border-color: transparent; box-shadow: none; color: var(--svx-text-muted); }
.svx-btn-ghost:hover:not(:disabled) { background: var(--svx-bg-hover); color: var(--svx-text-primary); }

.svx-btn-sm { padding: 0.25rem 0.5rem; font-size: var(--svx-text-xs); border-radius: var(--svx-radius-sm); }

.svx-btn-primary:focus-visible,
.gated-button:not(:disabled):focus-visible {
    outline-color: var(--svx-focus-ring);
    box-shadow: 0 0 0 2px var(--svx-focus-ring-inner);
}

.svx-input, .svx-select, .svx-textarea {
    width: 100%;
    padding: 0.4375rem 0.625rem;
    font-size: var(--svx-text-base);
    color: var(--svx-text-primary);
    background: var(--svx-bg-surface);
    border: 1px solid var(--svx-border-strong);
    border-radius: var(--svx-radius-md);
    transition: border-color var(--svx-duration-fast) var(--svx-ease),
                box-shadow var(--svx-duration-fast) var(--svx-ease);
}
.svx-input::placeholder, .svx-textarea::placeholder { color: var(--svx-text-subtle); }
.svx-input:hover:not(:disabled), .svx-select:hover:not(:disabled) { border-color: var(--svx-text-subtle); }
.svx-input:focus-visible, .svx-select:focus-visible, .svx-textarea:focus-visible {
    outline: none;
    border-color: var(--svx-accent);
    box-shadow: 0 0 0 3px var(--svx-accent-glow);
}
.svx-input:disabled, .svx-select:disabled, .svx-textarea:disabled {
    background: var(--svx-bg-inset);
    color: var(--svx-text-disabled);
}
.svx-input-sm { padding: 0.25rem 0.5rem; font-size: var(--svx-text-xs); border-radius: var(--svx-radius-sm); }
.svx-textarea { resize: vertical; min-height: 5rem; }

.svx-checkbox {
    width: 1rem;
    height: 1rem;
    margin: 0;
    accent-color: var(--svx-accent);
    vertical-align: middle;
    cursor: pointer;
}
.svx-checkbox:disabled { cursor: not-allowed; }
.svx-checkbox:focus-visible {
    outline: var(--svx-focus-ring-width) solid var(--svx-focus-ring);
    outline-offset: var(--svx-focus-ring-offset);
}

.svx-badge {
    display: inline-flex; align-items: center; gap: var(--svx-space-1);
    padding: 0.1875rem var(--svx-space-2);
    font-size: var(--svx-text-xs);
    font-weight: var(--svx-weight-semibold);
    line-height: 1.35;
    letter-spacing: var(--svx-tracking-wide);
    border-radius: var(--svx-radius-full);
    border: 1px solid var(--svx-neutral-border);
    background: var(--svx-neutral-bg);
    color: var(--svx-neutral-fg);
    cursor: default;
    white-space: nowrap;
}

.svx-visually-hidden {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.svx-skeleton-group { display: flex; flex-direction: column; gap: var(--svx-space-2); }
.svx-skeleton { position: relative; overflow: hidden; background: var(--svx-skeleton-base); }
.svx-skeleton::after {
    content: "";
    position: absolute;
    inset: 0;
    transform: translateX(-100%);
    background: linear-gradient(90deg, transparent, var(--svx-skeleton-sheen), transparent);
    animation: svx-shimmer 1.6s var(--svx-ease) infinite;
}
@keyframes svx-shimmer { 100% { transform: translateX(100%); } }
