/* Crownforge design tokens (DECK_BUILDER_DESIGN_SYSTEM.md §2). Hybrid "Camelot" theme: a light parchment
   body beneath a crimson + gold banner (the heraldry of Camelot), adapted from throneteki's Lannister pair. */

/* No cascade layers: every sheet is app-authored (the vendored Bootstrap the Identity pages once
   quarantined in a `vendor` layer is gone — account.css replaced it). Keep it that way; layering an
   app sheet would only LOWER its priority. See docs/CSS_CONVENTIONS.md §7. */

:root {
    /* Parchment is the shipped DEFAULT theme; a [data-theme="dark"] block below re-maps the palette.
       Pin UA-rendered widgets (scrollbars, <select> popups, autofill) to light here so a dark-mode OS
       doesn't render them dark against the light canvas; the dark block flips this to `dark`. */
    color-scheme: light;
    /* Color — light parchment canvas, crimson brand, gold accent. Gold is reserved for the dark crimson
       banner + flourishes (it can't carry text contrast on parchment); on the light body, links use crimson. */
    --cf-bg: #f4ecdd;              /* warm parchment canvas (the light "royal" body) */
    --cf-surface: #fffdf8;         /* near-white card surface */
    --cf-surface-2: #ece1cd;       /* deeper parchment — insets, inputs, badges */
    --cf-text: #2a2017;            /* warm near-black ink */
    --cf-text-muted: #6f6047;      /* warm brown-grey, secondary text */
    --cf-border: #d9ccb4;          /* warm hairline on parchment (decorative dividers) */
    --cf-border-strong: #94835f;   /* AA 3:1 non-text contrast — outlines of interactive controls */
    --cf-text-faint: #b3a587;      /* decorative flourishes ONLY — ~2.1:1, fails AA as text (placeholders
                                      and readable micro-labels use --cf-text-muted) */
    --cf-surface-hover: #e3d7bf;   /* warm hover fill for round / ghost controls on parchment */
    --cf-control-hover: #efe6d4;   /* lighter warm hover fill for ghost/inset controls (destiny slot, edit pills) */
    --cf-lane-top: #fbf6ea;        /* cost-lane vellum fill — top of the gradient (Curve board + Deck Spread) */
    --cf-lane-bottom: #f1e7d0;     /* cost-lane vellum fill — bottom of the gradient */
    --cf-lane-hatch: rgb(148 131 95 / .06); /* empty cost-lane diagonal hatch, on the parchment */
    --cf-editor-glow: #f9f3e6;     /* soft parchment glow at the top of the editor spread/curve/sim panes */
    --cf-crest-muted: #c4b491;     /* de-tinted crest in empty / not-found states */
    --cf-brand: #b01818;           /* Camelot crimson — primary CTAs, body links, the Camelot faction */
    --cf-brand-hover: #8f1414;     /* darker crimson for hover on light */
    --cf-brand-contrast: #fdf4e8;  /* label ink on a SOLID --cf-brand fill (CTA labels). Dark theme flips this
                                      to a near-black ink (the brand fill brightens there) — text that must stay
                                      cream in every theme uses --cf-cream instead. */
    --cf-cream: #fdf4e8;           /* theme-STABLE cream — ink on the fixed dark-crimson bands (app banner,
                                      editor banner, home hero) and other art surfaces that never flip */
    /* Heraldic crimson banner field (MainLayout app bar + its mobile dropdown). In light these compute to
       the exact mixes the banner always used (#9b1515 → #7b1111); the dark block deepens them to velvet so
       the banner doesn't brighten when --cf-brand lifts for dark-surface legibility. */
    --cf-banner-top: color-mix(in srgb, var(--cf-brand) 88%, var(--cf-overlay-dark));
    --cf-banner-bottom: color-mix(in srgb, var(--cf-brand) 70%, var(--cf-overlay-dark));
    --cf-accent: #c9a227;          /* Camelot gold — the crimson banner's flourishes + selection */
    --cf-accent-deep: #9c7a18;     /* deep gold — gradient stops + raised edges (== --game-gold-deep) */
    --cf-accent-contrast: #1a1206; /* on-gold text */
    --cf-gold-border: #876913;     /* darker gold edge for raised gold CTAs (banner / hero) */
    --cf-gold-hover: #d7b231;      /* brighter gold for gold-CTA hover */
    --cf-success: #15803d;
    --cf-warning: #b45309;
    --cf-danger: #b3271d;
    --cf-focus: #b01818;           /* crimson focus ring on the light body (the banner overrides to gold) */
    /* Overlays — derive every scrim/lift from one base so they track a single source instead of being
       re-typed. --cf-scrim is --cf-text at 46% (replaces the hand-typed rgba(42,32,23,.46) in the modal);
       --cf-overlay-dark/-light are pure black/white — both the scrims over the crimson banner AND the
       darken/lighten endpoints of color-mix shades (compose alpha/ratio at the use site, e.g.
       color-mix(in srgb, var(--cf-overlay-dark) 35%, transparent) or
       color-mix(in srgb, var(--cf-brand) 76%, var(--cf-overlay-dark))). */
    --cf-scrim: color-mix(in srgb, var(--cf-text) 46%, transparent);
    --cf-overlay-dark: #000;
    --cf-overlay-light: #fff;
    /* Semantic tints for TEXT on the light surfaces — dark enough to read on parchment/white. */
    --cf-success-fg: #1c7040;
    --cf-warning-fg: #8a5810;
    --cf-danger-fg: #b3271d;
    --cf-info-fg: #6f5a0e;

    /* Faction palette (§2.2) — AA-safe body tints (≈4.5:1 on parchment) from the component sheet, sourced
       from the faction art. Camelot = the brand crimson; the rest are darkened heraldic hues for crest + text. */
    --cf-faction-neutral: #5f513a;
    --cf-faction-camelot: #b01818;
    --cf-faction-theeleven: #234c9e;
    --cf-faction-lefayscircle: #6e2391;
    --cf-faction-keepersoftheoldway: #2c6420;
    --cf-faction-thesummercourt: #a8430c;
    --cf-faction-thewintercourt: #0f5e72;
    --cf-faction-saracenenvoy: #6f5408;

    /* Struggle (skill) palette — the four ARoK struggle types get stable, mutually-distinct hues
       (Combat red · Guile green · Sorcery violet · Faith blue) so a type reads by colour + shape, not
       silhouette alone (at 11–14px four monochrome glyphs blur). Values match the card-frame
       --cf-frame-skill-*-field ramp (card-frames.css) for cross-surface consistency; AA (≈4.5:1+) on parchment. */
    --cf-struggle-combat: #a82210;
    --cf-struggle-guile: #2d6a2a;
    --cf-struggle-sorcery: #5b2a73;
    --cf-struggle-faith: #1d4a8a;

    /* Struggle hues for ALWAYS-DARK islands (e.g. the board card chrome strip): the light-ink values
       the dark theme uses, promoted to first-class tokens so a dark island reads them in BOTH themes. */
    --cf-struggle-combat-ondark: #e26a55;
    --cf-struggle-guile-ondark: #6fbb62;
    --cf-struggle-sorcery-ondark: #bc85d6;
    --cf-struggle-faith-ondark: #7aa5e6;

    /* Card-type categorical palette for the type-split chart. Seeded from faction hues but independent —
       retinting a faction must not silently recolour the chart (the chart isn't about factions). */
    --cf-type-unit: #b01818;
    --cf-type-attachment: #234c9e;
    --cf-type-location: #2c6420;
    --cf-type-deed: #a8430c;

    /* Typography (§2.3) — a serif "display" voice for the royal feel (throneteki uses Georgia for names). */
    --cf-font-ui: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    --cf-font-display: "Iowan Old Style", "Palatino Linotype", Georgia, "Times New Roman", serif;
    --cf-font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;

    /* Gold-leaf palette (constant across factions) — promoted to :root so the live board's hand cards
       reuse the same struck-metal ramp as the full-size card frames (see card-frames.css). */
    --cf-frame-gold-dark: #7a531a;
    --cf-frame-gold-mid: #a06f24;
    --cf-frame-gold-warm: #c9b27d;
    --cf-frame-gold-bright: #f4d97a;
    --cf-frame-gold-lite: #f7e2a4;
    --cf-frame-gold-pale: #fff0bd;
    /* ── Game-surface shared palette ── board (css/board.css, /play) + the Moments & Broadcast overlays
       share these. Deliberately NOT --cf-*: they're physical "table" colours (felt vignette, parchment
       grain, casting gold) + the board's tighter px radii, and must NOT shift if the brand palette is
       re-themed. board.css / moments.css / broadcast.css are migrating their hand-duplicated
       per-sheet (--board-, --bcast-, --moment-) tokens onto these. */
    --game-font-display: "Cinzel", var(--cf-font-display);
    --game-font-serif: "Cormorant Garamond", "Iowan Old Style", Georgia, serif;
    --game-font-ui: var(--cf-font-ui);
    --game-radius-sm: 4px;
    --game-radius-md: 6px;          /* the board runs tighter than the --cf-radius scale */
    --game-radius-lg: 10px;
    --game-gold: var(--cf-accent);  /* board casting gold (#c9a227) */
    --game-gold-deep: #9c7a18;      /* borders / gradient stops */
    --game-gold-ink: #7a5f0f;       /* AA gold ink for sub-10px text on parchment */
    --game-felt-1: #3a2c19;         /* board vignette: mid → deep → darkest */
    --game-felt-2: #221710;
    --game-felt-3: #160f09;
    --game-parchment: #faf3e6;      /* board parchment grain highlight */
    --game-tone-crimson: #a3232b;   /* the two heraldic seat tones the board/broadcast art uses, */
    --game-tone-crimson-soft: #f3dcd7;
    --game-tone-moss: #3c6029;      /* referenced by surface-local seat tokens (you/opp · cam/kee) */
    --game-tone-moss-soft: #e2e6cf;
    --cf-text-2xs: 0.6875rem;     /* 11px — micro-labels, status chips, dense badges (below the body --xs) */
    --cf-text-xs: 0.75rem;
    --cf-text-sm: 0.875rem;
    --cf-text-md: 1rem;
    --cf-text-lg: 1.125rem;
    --cf-text-xl: 1.25rem;
    --cf-text-2xl: 1.5rem;
    --cf-text-3xl: 2rem;

    /* Spacing — 4pt grid (§2.4) */
    --cf-space-1: 4px;
    --cf-space-2: 8px;
    --cf-space-3: 12px;
    --cf-space-4: 16px;
    --cf-space-5: 20px;
    --cf-space-6: 24px;
    --cf-space-7: 28px;
    --cf-space-8: 32px;

    /* Radii (§2.5) */
    --cf-radius-sm: 4px;
    --cf-radius-md: 8px;
    --cf-radius-lg: 12px;
    --cf-radius-pill: 999px;

    /* Layout — sticky banner height, shared by panels that pin beneath it. */
    --cf-header-height: 76px;

    /* The card reader's frame scale ceiling. The reader fits its frame to the panel with a container
       query and caps it here, so this one number sets the reader's card size on every surface. THREE
       places derive from it and cannot read it themselves — change it and revisit all three:
         · CardReaderSheet.razor.css — the quest ceiling is this x 600/900 (a quest frame is 900px wide,
           a portrait one 600px, and both must land at the same on-screen size).
         · Cards.razor.css — the /cards detail track is 600px x this, plus 52px of padding and borders.
         · CardReaderSheet.razor.cs (FrameScale) — the inline value the stylesheet then overrides.
       The CSS below expresses the first two as calc() off this token so only the C# copy is by hand. */
    --cf-reader-frame-scale: 0.62;

    /* Responsive breakpoint ladder — the SINGLE source of truth for viewport media queries. CSS forbids
       var() in a media condition, so these are documented constants (stylelint-enforced), not live tokens.
       Author mobile-first (min-width); use ONLY these five values and retire the ad-hoc set (640/700/900…):
         sm 480px · md 720px · lg 960px · xl 1200px · 2xl 1440px */

    /* Elevation (§2.6) */
    --cf-shadow-1: 0 1px 2px rgb(60 42 24 / 0.10);
    --cf-shadow-2: 0 4px 10px rgb(60 42 24 / 0.12);
    --cf-shadow-3: 0 12px 28px rgb(60 42 24 / 0.16);

    /* Motion (§2.7) */
    --cf-dur-fast: 120ms;
    --cf-dur-base: 200ms;
    --cf-dur-slow: 320ms;
    --cf-ease: cubic-bezier(0.2, 0, 0, 1);

    /* Z-index (§2.8) */
    --cf-z-dropdown: 1000;
    --cf-z-sticky: 1100;
    --cf-z-modal: 1150;            /* full-screen non-dialog overlays (e.g. the lobby sheet) — above sticky, below dialog */
    --cf-z-dialog: 1200;
    --cf-z-toast: 1300;
    --cf-z-tooltip: 1400;
}

/* ═══════════════════════════ Dark theme ═══════════════════════════
   Candlelit scriptorium: the parchment manuscript at night — deep umber ink surfaces, vellum-cream text,
   the crimson lifted toward rubric vermilion so it still carries text on the dark ground. Applied via
   data-theme="dark" on <html> (set by the boot script in App.razor from localStorage 'cf.theme'; 'auto'
   resolves against prefers-color-scheme before it ever reaches CSS, so only light|dark appear here).
   Every text/surface pair below holds WCAG AA (≥4.5:1; muted text 4.6:1 on the lightest surface).
   NOT overridden on purpose: the --game-* physical-table palette (felt, parchment grain, seat tones —
   the board is a physical object; --game-gold-ink is the one exception, see below), the card-frame golds
   (card FACES keep their printed look), --cf-border-strong (the #94835f bronze outline reads ≥4.2:1 on
   these surfaces too — one outline colour across both themes), --cf-warning (white-on-amber pips need
   the deep amber), and the whole non-colour scale (space/radius/type/motion/z). */
[data-theme="dark"] {
    /* Dark canvas → let UA widgets (scrollbars, <select> popups, autofill) follow. */
    color-scheme: dark;

    /* Surfaces — umber-black room, leather-dark panels; elevation lightens. */
    --cf-bg: #16110c;              /* the candlelit room */
    --cf-surface: #201913;         /* raised panel / card surface */
    --cf-surface-2: #2b2219;       /* insets, inputs, badges — the lightest step */
    --cf-text: #eee3cf;            /* vellum-cream ink (≈13.7:1 on surface) */
    --cf-text-muted: #b3a68c;      /* warm tan, secondary text (≥4.6:1 on every surface) */
    --cf-border: #3b3125;          /* hairline on umber (decorative dividers) */
    --cf-text-faint: #665847;      /* decorative flourishes ONLY — deliberately sub-AA, like light's */
    --cf-surface-hover: #332920;   /* hover fill for round / ghost controls */
    --cf-control-hover: #2b231b;   /* subtler hover fill for ghost/inset controls */
    --cf-lane-top: #231c14;        /* cost-lane vellum, dimmed to leather */
    --cf-lane-bottom: #1b150f;
    --cf-lane-hatch: rgb(201 178 125 / 0.07); /* light hatch on the dark lane */
    --cf-editor-glow: #241a12;     /* candlelit umber lift (subtle over --cf-bg #16110c, not a cream halo) */
    --cf-crest-muted: #564a39;     /* de-tinted crest in empty states */

    /* Brand — rubric vermilion (manuscript rubrics were vermilion ink): ≥4.5:1 as link/accent text on
       every surface. Solid-brand CTAs therefore flip their label to near-black ink (below), the same
       bright-fill + ink-label construction the gold CTAs already use. */
    --cf-brand: #e1634a;
    --cf-brand-hover: #ea6d52;     /* hover BRIGHTENS on dark */
    --cf-brand-contrast: #2b0e07;  /* ink label on the lifted brand/danger fills (≈5.2:1) */
    --cf-banner-top: #7d1111;      /* the banner deepens to velvet (cream nav text ≈9.8:1) */
    --cf-banner-bottom: #560b0b;

    /* Status — in dark these base tokens are FILLS/BORDERS only (sub-AA as text on the lightest tiers);
       text goes through the -fg tints below. --cf-warning keeps its deep amber (see block comment). */
    --cf-success: #2e8a52;
    --cf-danger: #e0574a;
    --cf-focus: #e1634a;
    --cf-scrim: color-mix(in srgb, var(--cf-overlay-dark) 62%, transparent);
    --cf-success-fg: #6fbf8a;
    --cf-warning-fg: #dfa14c;
    --cf-danger-fg: #f08a7c;
    --cf-info-fg: #cdb14a;

    /* Faction tints — same heraldic hues, lifted to carry text on the dark surfaces (≥4.5:1). */
    --cf-faction-neutral: #a4936f;
    --cf-faction-camelot: #e1644e;
    --cf-faction-theeleven: #7d9fe0;
    --cf-faction-lefayscircle: #c17fe3;
    --cf-faction-keepersoftheoldway: #71b45e;
    --cf-faction-thesummercourt: #e58a54;
    --cf-faction-thewintercourt: #5cb3cc;
    --cf-faction-saracenenvoy: #c6a13c;

    /* Struggle + card-type palettes — the same lift, keeping the four hues mutually distinct. */
    --cf-struggle-combat: var(--cf-struggle-combat-ondark);
    --cf-struggle-guile: var(--cf-struggle-guile-ondark);
    --cf-struggle-sorcery: var(--cf-struggle-sorcery-ondark);
    --cf-struggle-faith: var(--cf-struggle-faith-ondark);
    --cf-type-unit: #e1644e;
    --cf-type-attachment: #7d9fe0;
    --cf-type-location: #71b45e;
    --cf-type-deed: #e58a54;

    /* The ONE --game-* exception: gold-ink is an *ink* (sub-10px text), not a physical table colour —
       its semantic is "AA gold ink on the panel behind it", and those panels are --cf-surface driven,
       so it must brighten with them (#7a5f0f would sit ≈1.8:1 on the dark panels). */
    --game-gold-ink: #d4ac35;

    /* Elevation — deeper, black-based shadows so lift still reads on the dark ground. */
    --cf-shadow-1: 0 1px 2px rgb(0 0 0 / 0.5);
    --cf-shadow-2: 0 4px 10px rgb(0 0 0 / 0.5);
    --cf-shadow-3: 0 12px 28px rgb(0 0 0 / 0.55);
}

*,
*::before,
*::after {
    box-sizing: border-box;
}

html,
body {
    margin: 0;
    padding: 0;
    min-height: 100%;
}

body {
    background: var(--cf-bg);
    color: var(--cf-text);
    font-family: var(--cf-font-ui);
    font-size: var(--cf-text-md);
    line-height: 1.5;
}

h1, h2, h3, h4 {
    font-family: var(--cf-font-display);
    line-height: 1.2;
    margin: 0 0 var(--cf-space-3);
}

a {
    color: var(--cf-brand);
    text-decoration: none;
}

a:hover {
    text-decoration: underline;
}

:focus-visible {
    outline: 2px solid var(--cf-focus);
    outline-offset: 2px;
}

/* Route-change focus targets (Blazor FocusOnNavigate moves focus to the <h1>) are focused
   programmatically for screen readers — they shouldn't paint a visible ring on every navigation. */
[tabindex="-1"]:focus,
[tabindex="-1"]:focus-visible {
    outline: none;
}

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        transition-duration: 0.01ms !important;
        animation-duration: 0.01ms !important;
        /* Without this, `infinite` spinners restart ~100k times/sec under the near-zero duration —
           visually frozen but CPU-busy and firing animation events. */
        animation-iteration-count: 1 !important;
    }
}

/* Visually hidden but available to assistive tech (a11y helper). */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
}

/* Keyboard-only skip link: lifted into view on focus, otherwise parked above the viewport. Used by
   MainLayout, BoardLayout, and EditorLayout (each renders one above its <main>). */
.cf-skip-link {
    position: absolute;
    left: var(--cf-space-2);
    top: -60px;
    z-index: var(--cf-z-tooltip);
    padding: var(--cf-space-2) var(--cf-space-3);
    background: var(--cf-accent);
    color: var(--cf-accent-contrast);
    border-radius: var(--cf-radius-sm);
    transition: top var(--cf-dur-fast) var(--cf-ease);
}
.cf-skip-link:focus { top: var(--cf-space-2); }

/* Framework error chrome (kept from the template). The old `color-scheme: light only` pin is gone:
   the bar is token-tinted (no UA-styled children), so it follows the theme like everything else. */
#blazor-error-ui {
    background: color-mix(in srgb, var(--cf-warning) 16%, var(--cf-surface));
    color: var(--cf-text);
    bottom: 0;
    box-shadow: 0 -2px 10px rgb(60 42 24 / 0.16);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem;
    position: fixed;
    width: 100%;
    z-index: var(--cf-z-toast);
}

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

.blazor-error-boundary {
    background: color-mix(in srgb, var(--cf-danger) 14%, var(--cf-surface));
    padding: 1rem;
    color: var(--cf-danger-fg);
    border: 1px solid var(--cf-danger);
    border-radius: var(--cf-radius-md);
}

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

/* ---- Circuit-reconnect overlay (js/reconnect.js builds the DOM; Blazor toggles the state classes) ----
   The element carries the framework-required id (components-reconnect-modal) and Blazor drives it purely
   by class: show/retrying/paused = reconnecting, failed = manual retry, rejected = reload-only. Hidden at
   rest and again on `hide`. The state classes are framework-owned names (allow-listed in .stylelintrc,
   like blazor-error-boundary); everything inside is cf-reconnect BEM. */
.cf-reconnect {
    display: none;
    position: fixed;
    inset: 0;
    z-index: var(--cf-z-tooltip);   /* above every app surface — nothing is interactable without a circuit */
    align-items: center;
    justify-content: center;
    padding: var(--cf-space-4);
    background: var(--cf-scrim);
    backdrop-filter: blur(2px);
}

.cf-reconnect.components-reconnect-show,
.cf-reconnect.components-reconnect-retrying,
.cf-reconnect.components-reconnect-paused,
.cf-reconnect.components-reconnect-failed,
.cf-reconnect.components-reconnect-rejected { display: flex; }

.cf-reconnect.components-reconnect-hide { display: none; }

.cf-reconnect__panel {
    max-width: 26rem;
    padding: var(--cf-space-6) var(--cf-space-7) var(--cf-space-6);
    text-align: center;
    background: linear-gradient(165deg, var(--cf-surface), var(--cf-surface-2));
    border: 1px solid color-mix(in srgb, var(--cf-accent) 55%, transparent);
    border-radius: var(--cf-radius-lg);
    box-shadow: 0 24px 60px -18px color-mix(in srgb, var(--cf-overlay-dark) 70%, transparent);
}

.cf-reconnect__crown {
    display: block;
    font-size: var(--cf-text-2xl);
    color: var(--cf-accent);
}

.cf-reconnect__spinner {
    display: block;
    width: 22px;
    height: 22px;
    margin: var(--cf-space-3) auto 0;
    border: 2px solid color-mix(in srgb, var(--cf-accent) 40%, transparent);
    border-top-color: var(--cf-brand);
    border-radius: 50%;
    animation: cf-reconnect-spin 0.9s linear infinite;
}

/* The wait glyph only belongs to the waiting states; failure states show verdict + actions instead. */
.cf-reconnect.components-reconnect-failed .cf-reconnect__spinner,
.cf-reconnect.components-reconnect-rejected .cf-reconnect__spinner { display: none; }

.cf-reconnect__title {
    margin: var(--cf-space-3) 0 0;
    font-family: var(--game-font-display);
    font-size: var(--cf-text-lg);
    font-weight: 700;
    letter-spacing: 0.04em;
    color: var(--cf-text);
}

.cf-reconnect__body {
    margin: var(--cf-space-2) 0 0;
    font-family: var(--game-font-serif);
    font-style: italic;
    font-size: var(--cf-text-md);
    color: var(--cf-text-muted);
}

.cf-reconnect__pending-action {
    margin: var(--cf-space-4) 0 0;
    padding: var(--cf-space-3) var(--cf-space-4);
    font-family: var(--game-font-display);
    font-size: var(--cf-text-sm);
    font-weight: 700;
    color: var(--cf-warning);
    background: color-mix(in srgb, var(--cf-warning) 14%, transparent);
    border: 1px solid color-mix(in srgb, var(--cf-warning) 45%, transparent);
    border-radius: var(--cf-radius-md);
}

.cf-reconnect__pending-action[hidden] { display: none; }

.cf-reconnect__actions {
    display: none;
    justify-content: center;
    gap: var(--cf-space-3);
    margin-top: var(--cf-space-5);
    flex-wrap: wrap;
}

.cf-reconnect.components-reconnect-failed .cf-reconnect__actions,
.cf-reconnect.components-reconnect-rejected .cf-reconnect__actions { display: flex; }

/* Rejected means the server dropped this circuit's state — retrying the same circuit is a lie;
   only the reload door stays. */
.cf-reconnect.components-reconnect-rejected .cf-reconnect__btn--primary { display: none; }

.cf-reconnect__btn {
    min-height: 44px;
    padding: 0 var(--cf-space-5);
    font-family: var(--game-font-display);
    font-size: var(--cf-text-sm);
    font-weight: 700;
    letter-spacing: 0.04em;
    color: var(--cf-text);
    background: var(--cf-surface);
    border: 1px solid color-mix(in srgb, var(--cf-accent) 60%, transparent);
    border-radius: var(--cf-radius-md);
    cursor: pointer;
    transition: background var(--cf-dur-fast) var(--cf-ease);
}

.cf-reconnect__btn:hover { background: var(--cf-surface-hover); }

.cf-reconnect__btn--primary {
    color: var(--cf-brand-contrast);
    background: var(--cf-brand);
    border-color: var(--cf-brand-hover);
}

.cf-reconnect__btn--primary:hover { background: var(--cf-brand-hover); }

@keyframes cf-reconnect-spin {
    to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
    .cf-reconnect__spinner { animation: none; }
    .cf-reconnect { backdrop-filter: none; }
}

/* ---- Branded status surface: the error + 404 pages (Error.razor + the <NotFound> in Routes.razor) ---- */
.cf-status {
    max-width: 34rem;
    margin: var(--cf-space-8) auto;
    padding: var(--cf-space-6);
    text-align: center;
}

.cf-status__crest {
    color: var(--cf-accent);
}

.cf-status__code {
    margin: var(--cf-space-3) 0 0;
    font-family: var(--cf-font-display);
    font-size: var(--cf-text-3xl);
    font-weight: 800;
    line-height: 1;
    letter-spacing: 0.04em;
    color: var(--cf-text-muted);
}

.cf-status__title {
    margin: var(--cf-space-3) 0 0;
    font-family: var(--cf-font-display);
    font-size: var(--cf-text-xl);
    color: var(--cf-text);
}

.cf-status__lede {
    max-width: 42ch;
    margin: var(--cf-space-3) auto 0;
    line-height: 1.6;
    color: var(--cf-text-muted);
}

.cf-status__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--cf-space-3);
    margin-top: var(--cf-space-6);
}

.cf-status__btn {
    display: inline-flex;
    align-items: center;
    height: 40px;
    padding: 0 var(--cf-space-5);
    border-radius: var(--cf-radius-md);
    border: 1px solid var(--cf-border);
    background: var(--cf-surface);
    color: var(--cf-text);
    font-weight: 600;
    text-decoration: none;
}

.cf-status__btn:hover {
    background: var(--cf-surface-hover);
    text-decoration: none;
}

.cf-status__btn--primary {
    background: var(--cf-accent);
    border-color: var(--cf-gold-border);
    color: var(--cf-accent-contrast);
}

.cf-status__btn--primary:hover {
    background: var(--cf-gold-hover);
}

.cf-status__rid {
    margin-top: var(--cf-space-5);
    font-size: var(--cf-text-xs);
    color: var(--cf-text-muted);
}

.cf-status__rid code {
    font-family: var(--cf-font-mono);
}
