h1:focus {
    outline: none;
}

.blazor-error-boundary {
    background: #b32121;
    padding: 1rem;
    color: white;
    border-radius: 8px;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

/* ---------- Sentinel: design tokens + motion ---------- */

:root {
    /* "Night Watch" — Wardyr's single dark surface. Token names are kept from the prior theme so
       every existing .qa-* surface re-skins in place; the values are the new midnight/aurora palette. */
    --qa-cc-canvas: #0B0F1A;     /* page ground (ink) */
    --qa-cc-surface1: #141B2D;   /* cards / toolbars / menus / dialogs */
    --qa-cc-surface2: #1C2540;   /* raised / hover */
    --qa-cc-void: #05080F;       /* behind the live stream */
    --qa-cc-line: #293450;
    --qa-cc-text: #E6EDFA;
    --qa-cc-text-dim: #8A95AD;
    /* Brand / semantic */
    --qa-signal: #38E8C6;        /* ward-teal — the guardian's glow */
    --qa-signal-strong: #38E8C6;
    --qa-rune: #8B7BFF;          /* Bifröst violet (secondary) */
    --qa-emerald: #3FD98A;       /* pass */
    --qa-amber: #F6B73C;         /* healed / needs review */
    --qa-vermilion: #FF5A6E;     /* fail */
    /* Network-waterfall phase palette — the ONE sanctioned home for these hexes (validated for CVD
       separation + ≥3:1 on ink; setup phases + wait recessive, receive carries the intensity). */
    --qa-ph-dns: #5D6DA6;
    --qa-ph-conn: #8B7BFF;
    --qa-ph-tls: #C4B6FF;
    --qa-ph-wait: #4A689C;
    --qa-ph-recv: #38E8C6;
    --qa-midnight: #0B0F1A;
    --qa-deep-teal: #14223E;
    --qa-mono: 'JetBrains Mono', ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace;
}

/* Telemetry / measurements — tabular monospace ("precision instrument" signal) */
.qa-mono {
    font-family: 'JetBrains Mono', ui-monospace, 'SFMono-Regular', Menlo, monospace;
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
    letter-spacing: -0.01em;
}

/* Single-line table-cell text: ellipsize when it overflows, full text on hover (native title). Below the
   table's Sm breakpoint (600px) MudTable stacks into cards, where the summary should WRAP and show in full
   (a hover title is awkward on touch), so the nowrap/fixed-layout rules are desktop-scoped. */
.qa-cell-ellipsis {
    overflow: hidden;
    text-overflow: ellipsis;
}

@media (min-width: 600px) {
    .qa-cell-ellipsis { white-space: nowrap; }

    /* Runs list is one line per run. AUTO layout: every column sizes to its OWN content, so the pills, dates
       and durations are never truncated. Only the Summary flexes — width:100% + max-width:0 stops its text
       from widening the table, so it absorbs the width the other columns leave and ellipsizes a long message
       instead of wrapping the row or pushing the table past its panel. */
    .qa-runs-table table { width: 100%; }
    .qa-runs-table td,
    .qa-runs-table th {
        white-space: nowrap;   /* every cell one line — a date/duration can't wrap the row to two lines */
        padding-left: 10px;
        padding-right: 10px;
        width: 1%;             /* shrink every column to its own content… */
    }
    /* …except the Summary: width:100% claims the leftover the content columns don't use, and max-width:0
       lets it shrink BELOW its own (nowrap) text so the widest summary can't force the table past its panel —
       a long message clips + ellipsizes instead. The row stays one line at any width. */
    .qa-runs-table td.qa-summary-cell,
    .qa-runs-table th.qa-summary-cell {
        width: 100%;
        max-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
    }
}

/* On-watch pulse: a soft concentric ping radiating from the brand dot */
@keyframes qa-pulse {
    0%   { transform: scale(1);   opacity: .5; }
    70%  { transform: scale(2.8); opacity: 0; }
    100% { transform: scale(2.8); opacity: 0; }
}

/* Radar sweep: a rotating beam for active / connecting states */
@keyframes qa-sweep {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
}

/* One-time "armed / watching" flash when the recorder stage connects, settling to a thin ring */
@keyframes qa-arm-flash {
    0%   { box-shadow: 0 8px 40px rgba(0, 0, 0, .5), 0 0 0 0 rgba(34, 211, 197, 0); }
    35%  { box-shadow: 0 8px 40px rgba(0, 0, 0, .5), 0 0 0 3px rgba(34, 211, 197, .9); }
    100% { box-shadow: 0 8px 40px rgba(0, 0, 0, .5), 0 0 0 2px rgba(34, 211, 197, .28); }
}

/* Brand mark "on watch" pulse ring */
.qa-watch {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.qa-pulse-ring {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 12px;
    height: 12px;
    margin: -6px 0 0 -6px;
    border-radius: 50%;
    background: var(--qa-signal);
    animation: qa-pulse 3.6s ease-out infinite;
    pointer-events: none;
}

/* Radar-sweep loader (replaces the generic spinner for active states) */
.qa-radar {
    position: relative;
    width: var(--qa-radar-size, 56px);
    height: var(--qa-radar-size, 56px);
    border-radius: 50%;
    border: 1px solid var(--qa-cc-line);
    background: radial-gradient(circle, rgba(34, 211, 197, .08) 0%, transparent 72%);
    overflow: hidden;
}

    .qa-radar::after {
        content: "";
        position: absolute;
        inset: 28%;
        border-radius: 50%;
        border: 1px solid rgba(34, 211, 197, .22);
    }

.qa-radar-beam {
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: conic-gradient(from 0deg, transparent 0deg 300deg, rgba(34, 211, 197, .55) 360deg);
    animation: qa-sweep 1.8s linear infinite;
}

.qa-radar-dot {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 6px;
    height: 6px;
    margin: -3px 0 0 -3px;
    border-radius: 50%;
    background: var(--qa-signal);
    box-shadow: 0 0 8px rgba(34, 211, 197, .8);
}

@media (prefers-reduced-motion: reduce) {
    .qa-pulse-ring { animation: none; opacity: .35; }
    .qa-radar-beam { animation: none; background: conic-gradient(from 0deg, transparent 0deg 320deg, rgba(34, 211, 197, .4) 360deg); }
    .qa-frame-wrap.qa-armed { animation: none; box-shadow: 0 8px 40px rgba(0, 0, 0, .5), 0 0 0 2px rgba(34, 211, 197, .28); }
}

/* ---------- auth screens ---------- */

.qa-auth-shell {
    display: flex;
    min-height: 100vh;
    font-family: 'Inter', system-ui, sans-serif;
}

.qa-auth-brand {
    flex: 1;
    background:
        radial-gradient(110% 80% at 85% 8%, rgba(22, 181, 168, .20) 0%, transparent 55%),
        linear-gradient(160deg, #E7F5F3 0%, #F6F8F8 65%);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 48px;
    border-right: 1px solid #DEE7E7;
}

    .qa-auth-brand-inner {
        max-width: 440px;
        color: #0B1F2A;
        text-align: center;
    }

    .qa-auth-hero-img {
        width: 100%;
        max-width: 340px;
        height: auto;
        display: block;
        margin: 0 auto 20px;
        border-radius: 18px;
        box-shadow: 0 10px 30px rgba(11, 31, 42, .12);
    }

    .qa-auth-brand-word {
        display: inline-flex;
        align-items: center;
        gap: 8px;
        font-family: 'Space Grotesk', 'Inter', sans-serif;
        font-weight: 700;
        font-size: 20px;
        letter-spacing: -0.01em;
        color: #0B1F2A;
    }

    .qa-auth-brand-inner h1 {
        font-family: 'Space Grotesk', 'Inter', sans-serif;
        font-size: 32px;
        font-weight: 700;
        letter-spacing: -0.02em;
        margin: 12px 0 12px;
        color: #0B1F2A;
    }

    .qa-auth-brand-inner p {
        font-size: 16px;
        line-height: 1.6;
        color: #5A6B72;
    }

    .qa-auth-points {
        list-style: none;
        padding: 0;
        margin: 20px 0 0;
        display: inline-block;
        text-align: left;
    }

    .qa-auth-points li {
        margin: 8px 0;
        color: #334155;
        font-size: 15px;
    }

.qa-auth-form {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 32px;
    background: #F6F8F8;
}

.qa-auth-card {
    width: 100%;
    max-width: 380px;
}

.qa-auth-title {
    font-size: 24px;
    font-weight: 700;
    color: #0B1F2A;
    margin: 0 0 4px;
}

.qa-auth-sub {
    color: #5A6B72;
    margin: 0 0 24px;
}

.qa-field-label {
    display: block;
    font-size: 13px;
    font-weight: 600;
    color: #334155;
    margin: 14px 0 6px;
}

.qa-field {
    width: 100%;
    padding: 11px 13px;
    border: 1px solid #cbd5e1;
    border-radius: 8px;
    font-size: 15px;
    font-family: inherit;
    box-sizing: border-box;
}

    .qa-field:focus {
        outline: 2px solid #16B5A8;
        border-color: #16B5A8;
    }

.qa-auth-button {
    width: 100%;
    margin-top: 24px;
    background: #16B5A8;
    color: #fff;
    border: 0;
    border-radius: 8px;
    padding: 12px;
    font-size: 15px;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
}

    .qa-auth-button:hover {
        background: #0E9A8F;
    }

/* Loading state for native form-post submit buttons (wired by wwwroot/forms.js). Applies to plain
   .qa-auth-button and MudBlazor submit buttons alike; the spinner uses currentColor so it matches any
   button's text colour (dark on the teal auth button, teal on outlined, light on dark bars). */
button.qa-submitting {
    pointer-events: none;
    opacity: 0.85;
}

    button.qa-submitting::before {
        content: "";
        display: inline-block;
        width: 0.9em;
        height: 0.9em;
        margin-right: 0.5em;
        vertical-align: -0.15em;
        border: 2px solid currentColor;
        border-right-color: transparent;
        border-radius: 50%;
        animation: qa-spin 0.6s linear infinite;
    }

@keyframes qa-spin {
    to {
        transform: rotate(360deg);
    }
}

.qa-field-hint {
    font-size: 12px;
    color: #94a3b8;
    margin: 6px 0 0;
}

/* password field with an inline show/hide toggle */
.qa-field-wrap { position: relative; }

    .qa-field-wrap .qa-field { padding-right: 62px; }

.qa-field-eye {
    position: absolute;
    right: 6px;
    top: 50%;
    transform: translateY(-50%);
    border: 0;
    background: transparent;
    cursor: pointer;
    font-family: inherit;
    font-size: 12.5px;
    font-weight: 600;
    color: #334155;
    padding: 6px 8px;
    border-radius: 6px;
}

    .qa-field-eye:hover { text-decoration: underline; }

.qa-auth-error {
    background: #fef2f2;
    border: 1px solid #fecaca;
    color: #b91c1c;
    border-radius: 8px;
    padding: 10px 14px;
    font-size: 14px;
    margin-bottom: 16px;
}

.qa-auth-success {
    background: #ecfdf5;
    border: 1px solid #a7f3d0;
    color: #047857;
    border-radius: 8px;
    padding: 10px 14px;
    font-size: 14px;
    margin-bottom: 16px;
}

/* Right-aligned helper link (e.g. "Forgot password?") sitting above a field. */
.qa-field-aside {
    display: flex;
    justify-content: flex-end;
    margin: 6px 0 0;
}

    .qa-field-aside a {
        color: #16B5A8;
        font-weight: 600;
        font-size: 13px;
        text-decoration: none;
    }

.qa-auth-foot {
    margin-top: 24px;
    text-align: center;
    color: #5A6B72;
    font-size: 14px;
}

    .qa-auth-foot a {
        color: #16B5A8;
        font-weight: 600;
        text-decoration: none;
    }

/* A <button> that reads as a link — used for POST-backed actions (resend, sign out) that can't be
   plain <a> hrefs because they need an antiforgery token. */
.qa-auth-linkbtn {
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
    color: #16B5A8;
    font-weight: 600;
    font-size: 14px;
    font-family: inherit;
    text-decoration: none;
}

    .qa-auth-linkbtn:hover {
        text-decoration: underline;
    }

.validation-message {
    color: #dc2626;
    font-size: 13px;
    display: block;
    margin-top: 4px;
}

/* Horizontal metadata row (account workspace card): wraps on narrow screens. */
.qa-meta-row {
    display: flex;
    flex-wrap: wrap;
    gap: 16px 56px;
    align-items: flex-start;
}

@media (max-width: 800px) {
    .qa-auth-brand { display: none; }
    /* The brand panel is gone, so the form column carries a compact brand row (links home) —
       revealed in the LANDING v2 block at the end of this file (cascade order: its base
       display:none lives there, so the media reveal must come after it). */
    .qa-auth-form { flex-direction: column; }
}

/* ---------- marketing landing (anonymous front door) ---------- */

.qa-lp { font-family: 'Inter', system-ui, sans-serif; color: #0B1F2A; }

.qa-lp-top {
    position: sticky;
    top: 0;
    z-index: 10;
    background: #fff;
    border-bottom: 1px solid #DEE7E7;
}

.qa-lp-top-inner,
.qa-lp-hero-inner,
.qa-lp-steps,
.qa-lp-features,
.qa-lp-band-inner,
.qa-lp-foot {
    max-width: 1120px;
    margin: 0 auto;
    padding-left: 24px;
    padding-right: 24px;
}

.qa-lp-top-inner { display: flex; align-items: center; justify-content: space-between; height: 64px; }

.qa-lp-brand {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-family: 'Space Grotesk', 'Inter', sans-serif;
    font-weight: 700;
    font-size: 20px;
    letter-spacing: -0.01em;
    color: #0B1F2A;
}

.qa-lp-nav { display: flex; align-items: center; gap: 8px; }

.qa-lp-hero {
    background:
        radial-gradient(90% 70% at 92% 0%, rgba(22, 181, 168, .18) 0%, transparent 55%),
        linear-gradient(160deg, #E7F5F3 0%, #F6F8F8 60%);
}

.qa-lp-hero-inner {
    display: grid;
    grid-template-columns: 1.1fr 0.9fr;
    gap: 48px;
    align-items: center;
    padding-top: 76px;
    padding-bottom: 76px;
}

.qa-lp-eyebrow {
    text-transform: uppercase;
    letter-spacing: .08em;
    font-size: 13px;
    font-weight: 700;
    color: #0E7C72;
    margin-bottom: 12px;
}

.qa-lp-hero-copy h1 {
    font-family: 'Space Grotesk', 'Inter', sans-serif;
    font-size: 48px;
    line-height: 1.05;
    letter-spacing: -.02em;
    margin: 0 0 16px;
}

.qa-lp-hero-copy p { font-size: 18px; line-height: 1.6; color: #5A6B72; margin: 0 0 28px; max-width: 520px; }

.qa-lp-cta { display: flex; gap: 12px; flex-wrap: wrap; }

.qa-lp-band h2 {
    font-family: 'Space Grotesk', 'Inter', sans-serif;
    font-size: 30px;
    letter-spacing: -.02em;
    margin: 0 0 36px;
}

.qa-lp-band { background: linear-gradient(150deg, #0B1F2A 0%, #0E3A45 100%); color: #fff; text-align: center; }
.qa-lp-band-inner { padding-top: 64px; padding-bottom: 64px; }
.qa-lp-band h2 { color: #fff; margin-bottom: 10px; }
.qa-lp-band p { color: rgba(255, 255, 255, .82); margin: 0 0 24px; max-width: 720px; margin-left: auto; margin-right: auto; }

@media (max-width: 860px) {
    .qa-lp-hero-inner { grid-template-columns: 1fr; padding-top: 48px; padding-bottom: 48px; }
    /* Keep DOM order when stacked: headline + CTA first, the decorative arcade below (was order:-1,
       which pushed the game above the value prop and buried the CTA below the fold on phones).
       The arcade panel itself centers when stacked (it right-hugs on desktop via margin-left:auto). */
    .qa-arcade { margin-inline: auto; }
    .qa-lp-hero-copy h1 { font-size: 36px; }
}

/* ---------- live recorder ---------- */

.qa-recorder {
    position: relative;
    display: flex;
    flex-direction: column;
    height: 100vh;
    background: var(--qa-cc-canvas);
}

.qa-toolbar {
    display: flex;
    gap: 6px;
    align-items: center;
    padding: 10px 16px;
    background: var(--qa-cc-surface1);
    border-bottom: 1px solid var(--qa-cc-line);
}

.qa-urlbar {
    width: 360px;
}

    .qa-urlbar .mud-input-slot,
    .qa-urlbar input {
        color: var(--qa-cc-text) !important;
        font-size: 13px;
    }

    .qa-urlbar .mud-input-outlined-border {
        border-color: var(--qa-cc-line) !important;
    }

/* Floats over the stage so toggling assert mode never shifts the layout
   (shifting would move the stream mid-session). */
.qa-assert-banner {
    position: absolute;
    top: 72px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 5;
    display: flex;
    align-items: center;
    background: var(--qa-signal);
    color: var(--qa-midnight);
    font-size: 13px;
    font-weight: 600;
    padding: 8px 20px;
    border-radius: 999px;
    box-shadow: 0 6px 24px rgba(34, 211, 197, .45);
    pointer-events: none;
    white-space: nowrap;
}

.qa-main {
    display: flex;
    flex: 1;
    min-height: 0;
}

.qa-stage {
    flex: 1;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 16px;
    min-width: 0;
    overflow: auto;
}

.qa-frame-wrap {
    position: relative;
    /* Session-driven aspect (screen profiles): Record.razor sets --qa-frame-ar/--qa-frame-ratio inline;
       the fallbacks reproduce the desktop default exactly. width = availableHeight × (W/H) keeps the
       rendered height at (100vh - 150px) for ANY ratio — a portrait phone renders as a slim letterboxed
       column, a desktop as today's wide box; min(100%, …) keeps narrow windows width-bound. */
    aspect-ratio: var(--qa-frame-ar, 1280 / 800);
    width: min(100%, calc((100vh - 150px) * var(--qa-frame-ratio, 1.6)));
    box-shadow: 0 8px 40px rgba(0, 0, 0, .5);
    border-radius: 8px;
    overflow: hidden;
    background: var(--qa-cc-void);
}

    .qa-frame-wrap.qa-assert {
        outline: 3px solid var(--qa-signal);
    }

#qa-stream {
    width: 100%;
    height: 100%;
    display: block;
}

#qa-overlay {
    position: absolute;
    inset: 0;
    cursor: crosshair;
    outline: none;
}

/* ---- Screen-size picker (ScreenPicker.razor) — glyphs are literal viewport rectangles, never device
   silhouettes (the copy contract says emulation). ---- */
.qa-devrow {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
}

.qa-devcard {
    border: 1px solid var(--qa-cc-line);
    border-radius: 11px;
    padding: 12px 14px;
    background: var(--qa-cc-canvas);
    display: flex;
    gap: 12px;
    align-items: center;
    min-width: 150px;
    cursor: pointer;
}

    .qa-devcard:focus-visible {
        outline: 2px solid var(--qa-signal);
        outline-offset: 2px;
    }

    .qa-devcard.sel {
        border-color: rgba(56, 232, 198, .6);
        background: rgba(56, 232, 198, .06);
    }

    .qa-devcard.dense {
        padding: 8px 10px;
        min-width: 118px;
        gap: 9px;
    }

.qa-devglyph {
    border: 1.5px solid var(--qa-cc-text-dim);
    border-radius: 3px;
    flex: none;
}

.qa-devcard.sel .qa-devglyph {
    border-color: var(--qa-signal);
}

.qa-devglyph.desk { width: 34px; height: 22px; }
.qa-devglyph.tab { width: 22px; height: 28px; }
.qa-devglyph.ph { width: 14px; height: 26px; }

.qa-devname {
    color: var(--qa-cc-text);
    font-size: .86rem;
    font-weight: 600;
}

.qa-devdim {
    font-family: var(--qa-mono);
    font-size: .64rem;
    color: var(--qa-cc-text-dim);
}

/* Test-kind pill ("layout" sweep badge) — violet capability voice, distinct from status pills. */
.qa-kind-pill {
    font-family: var(--qa-mono);
    font-size: .6rem;
    letter-spacing: .08em;
    text-transform: uppercase;
    font-weight: 700;
    color: var(--qa-rune);
    border: 1px solid rgba(139, 123, 255, .45);
    border-radius: 999px;
    padding: 1px 8px;
    white-space: nowrap;
}

/* ---- Layout-sweep matrix (RunDetail) — lives inside a .qa-matrix-wrap horizontal scroller so the
   page itself never scrolls sideways. ---- */
.qa-sweep {
    width: 100%;
    border-collapse: collapse;
    min-width: 560px;
    font-family: var(--qa-mono);
    font-variant-numeric: tabular-nums;
}

    .qa-sweep th {
        font-size: .6rem;
        letter-spacing: .1em;
        text-transform: uppercase;
        color: var(--qa-cc-text-dim);
        padding: 8px 10px;
        border-bottom: 1px solid var(--qa-cc-line);
        text-align: center;
        white-space: nowrap;
    }

    .qa-sweep td {
        padding: 7px 10px;
        border-bottom: 1px solid rgba(41, 52, 80, .5);
        text-align: center;
    }

    .qa-sweep th:first-child,
    .qa-sweep td:first-child {
        text-align: left;
        position: sticky;
        left: 0;
        background: var(--qa-cc-surface1);
        font-size: .74rem;
        color: var(--qa-cc-text);
    }

.qa-swcell {
    font-family: var(--qa-mono);
    font-size: .66rem;
    font-weight: 700;
    border: 0;
    border-radius: 5px;
    padding: 2px 8px;
    background: transparent;
    cursor: pointer;
}

    .qa-swcell:focus-visible {
        outline: 2px solid var(--qa-signal);
        outline-offset: 1px;
    }

    .qa-swcell.ok {
        color: var(--qa-emerald);
        background: rgba(63, 217, 138, .1);
    }

    .qa-swcell.bad {
        color: var(--qa-vermilion);
        background: rgba(255, 90, 110, .14);
        outline: 1px solid rgba(255, 90, 110, .4);
    }

    .qa-swcell.warn {
        color: var(--qa-amber);
        background: rgba(246, 183, 60, .12);
    }

    .qa-swcell.sel {
        outline: 2px solid var(--qa-signal);
    }

/* ---- Network waterfall (RunDetail) — lives inside a .qa-matrix-wrap horizontal scroller so the page never
   scrolls sideways. Bars are STATIC (no entry animation) — evidence, not spectacle. ---- */
.qa-wf {
    --qa-wf-name-w: 340px;
    font-family: var(--qa-mono);
    font-variant-numeric: tabular-nums;
    min-width: 680px;
}

.qa-wf-axis {
    display: grid;
    grid-template-columns: var(--qa-wf-name-w) 1fr;
    font-size: .56rem;
    color: var(--qa-cc-text-dim);
    letter-spacing: .08em;
}

    .qa-wf-axis .ticks { position: relative; height: 16px; }

    .qa-wf-axis .ticks i {
        position: absolute;
        top: 0;
        font-style: normal;
        transform: translateX(-50%);
        white-space: nowrap;
    }

.qa-wf-body {
    position: relative;
    border: 1px solid var(--qa-cc-line);
    border-radius: 9px;
    background: var(--qa-cc-void);
    /* NOT overflow:hidden — a clipping ancestor would break the frozen name column's sticky positioning
       against the .qa-matrix-wrap scroller. Bars clamp to ≤100%, so nothing meaningfully overspills. */
    overflow: visible;
}

.qa-wf-grid { position: absolute; inset: 0; left: var(--qa-wf-name-w); pointer-events: none; }

    .qa-wf-gridline { position: absolute; top: 0; bottom: 0; width: 1px; background: rgba(41, 52, 80, .45); }

    /* The 0ms origin: a light baseline so the first bar reads as sitting ON zero, not floating. */
    .qa-wf-baseline { position: absolute; top: 0; bottom: 0; left: 0; width: 1px; background: rgba(138, 149, 173, .4); }

.qa-wf-marker { position: absolute; top: 0; bottom: 0; width: 1px; background: rgba(56, 232, 198, .5); }

/* ---- Step-activity track: what the test was DOING across the timeline (fills the request-gaps). ---- */
.qa-wf-steps {
    display: grid;
    grid-template-columns: var(--qa-wf-name-w) 1fr;
    margin-bottom: 5px;
}

    .qa-wf-steps-lbl {
        font-family: var(--qa-mono);
        font-size: .5rem;
        letter-spacing: .12em;
        text-transform: uppercase;
        color: var(--qa-cc-text-dim);
        display: flex;
        align-items: center;
        /* Frozen with the name column — opaque so scrolled step blocks pass under it. */
        position: sticky;
        left: 0;
        z-index: 4;
        background: var(--qa-cc-surface1);
        box-shadow: inset -1px 0 0 var(--qa-cc-line);
    }

/* The axis's empty left cell freezes too, so the "0s" tick can't scroll into the name column. */
.qa-wf-axis > div:first-child {
    position: sticky;
    left: 0;
    z-index: 4;
    background: var(--qa-cc-surface1);
    box-shadow: inset -1px 0 0 var(--qa-cc-line);
}

    .qa-wf-steps-lane { position: relative; height: 18px; }

.qa-wf-step {
    position: absolute;
    top: 0;
    height: 18px;
    display: flex;
    align-items: center;
    background: rgba(138, 149, 173, .12);
    border-left: 2px solid rgba(138, 149, 173, .55);
    border-radius: 0 3px 3px 0;
    overflow: hidden;
    box-sizing: border-box;
    /* Query container: the block's OWN rendered width decides which label shows (see the @container rules
       below), so the choice is accurate at any timeline width without a server-side pixel guess. */
    container-type: inline-size;
}

    .qa-wf-step span {
        font-family: var(--qa-mono);
        font-size: .52rem;
        letter-spacing: .04em;
        color: var(--qa-cc-text-dim);
        white-space: nowrap;
        padding: 0 6px;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    /* The bare step number shown when a block is too narrow for the full label — snug padding so "S12" fits,
       and a touch brighter since it's the only identifier in that block. */
    .qa-wf-step span.num {
        padding: 0 3px;
        letter-spacing: 0;
        color: var(--qa-cc-text);
    }

/* Label tier by the block's REAL width: full label ≥56px, else the bare number ≥24px, else title-only (never
   anonymous). Both spans render; the container query on .qa-wf-step picks — accurate at any timeline width. */
.qa-wf-step > span { display: none; }
@container (min-width: 24px) { .qa-wf-step > span.num { display: block; } }
@container (min-width: 56px) {
    .qa-wf-step > span.num { display: none; }
    .qa-wf-step > span.full { display: block; }
}

.qa-wf-row {
    display: grid;
    grid-template-columns: var(--qa-wf-name-w) 1fr;
    align-items: center;
    position: relative;
    min-height: 26px;
    border-bottom: 1px solid rgba(41, 52, 80, .35);
}

    .qa-wf-row:last-child { border-bottom: none; }
    .qa-wf-row:hover { background: rgba(28, 37, 64, .5); }
    .qa-wf-row.third .qa-wf-name { opacity: .62; }

.qa-wf-name {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 4px 10px;
    font-size: .62rem;
    color: var(--qa-cc-text);
    white-space: nowrap;
    overflow: hidden;
    /* Frozen request column: stays pinned while the timeline scrolls. Opaque (matches the body void) + above
       the lane's hover overlay (z 3) so scrolled bars disappear cleanly under it; a hairline right separator. */
    position: sticky;
    left: 0;
    z-index: 4;
    background: var(--qa-cc-void);
    box-shadow: inset -1px 0 0 var(--qa-cc-line);
}

    .qa-wf-row:hover .qa-wf-name { background: #101627; } /* the row-hover tint, solid so it stays opaque */

    .qa-wf-name .m { color: var(--qa-cc-text-dim); font-size: .56rem; width: 34px; flex: none; }
    .qa-wf-name .u { overflow: hidden; text-overflow: ellipsis; }
    .qa-wf-name .st { margin-left: auto; font-size: .56rem; color: var(--qa-cc-text-dim); flex: none; padding-left: 8px; }
    .qa-wf-name .st.bad { color: var(--qa-vermilion); }

/* Clip lane content to the timeline: an incomplete-request tag / edge flag near 100% can't overspill the
   right edge and add a spurious in-panel scrollbar on short runs (the sticky name is a sibling, not clipped). */
.qa-wf-lane { position: relative; height: 100%; min-height: 26px; overflow: hidden; }

/* ---- request hover tooltip (the phase breakdown) ---- */
.qa-wf-tip { font-family: var(--qa-mono); font-size: .68rem; max-width: 340px; }
    .qa-wf-tip-url { color: var(--qa-cc-text); word-break: break-all; margin-bottom: 2px; }
    .qa-wf-tip-meta { color: var(--qa-cc-text-dim); font-size: .62rem; margin-bottom: 6px; }
    .qa-wf-tip-note { color: var(--qa-amber); font-size: .62rem; }
    .qa-wf-tip-grid {
        display: grid;
        grid-template-columns: auto auto;
        gap: 2px 16px;
        font-variant-numeric: tabular-nums;
    }
        .qa-wf-tip-grid span { color: var(--qa-cc-text-dim); }
        .qa-wf-tip-grid b { color: var(--qa-cc-text); font-weight: 600; text-align: right; }
        .qa-wf-tip-grid .tot { border-top: 1px solid var(--qa-cc-line); padding-top: 3px; margin-top: 1px; color: var(--qa-cc-text); }

.qa-wf-bar {
    position: absolute;
    top: 7px;
    height: 12px;
    display: flex;
    border-radius: 3px;
    overflow: hidden;
    min-width: 2px;
}

    .qa-wf-bar i { display: block; height: 100%; }

.qa-ph-dns { background: var(--qa-ph-dns); }
.qa-ph-conn { background: var(--qa-ph-conn); }
.qa-ph-tls { background: var(--qa-ph-tls); }
.qa-ph-wait { background: var(--qa-ph-wait); }
.qa-ph-recv { background: var(--qa-ph-recv); }

.qa-wf-bar.failed { outline: 1px solid var(--qa-vermilion); background: rgba(255, 90, 110, .2); }
    .qa-wf-bar.failed .qa-ph-wait { background: rgba(255, 90, 110, .55); }

/* An incomplete request (no response — aborted by a navigation) has no timing to draw, so instead of an
   empty lane it shows a dim "started, did not finish" tag at its start point. The row dims to match. */
.qa-wf-row.incomplete .qa-wf-name { opacity: .7; }
.qa-wf-bar.incomplete { display: none; }
.qa-wf-pending {
    position: absolute;
    top: 6px;
    font-family: var(--qa-mono);
    font-size: .5rem;
    letter-spacing: .04em;
    white-space: nowrap;
    color: var(--qa-cc-text-dim);
    border: 1px dashed var(--qa-cc-line);
    border-radius: 3px;
    padding: 0 5px;
    transform: translateX(2px);
}

.qa-wf-flag {
    position: absolute;
    top: 5px;
    font-size: .52rem;
    letter-spacing: .06em;
    padding: 1px 6px;
    border-radius: 999px;
    white-space: nowrap;
    pointer-events: none;
}

    .qa-wf-flag.slow { color: var(--qa-amber); border: 1px solid rgba(246, 183, 60, .5); background: rgba(11, 15, 26, .85); }
    .qa-wf-flag.err { color: var(--qa-vermilion); border: 1px solid rgba(255, 90, 110, .5); background: rgba(11, 15, 26, .85); }

.qa-wf-legend {
    display: flex;
    gap: 14px;
    flex-wrap: wrap;
    align-items: center;
    font-family: var(--qa-mono);
    font-size: .56rem;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--qa-cc-text-dim);
    padding: 9px 2px 0;
}

    .qa-wf-legend b { display: inline-block; width: 14px; height: 8px; border-radius: 2px; margin-right: 5px; vertical-align: -1px; }
    .qa-wf-legend-note { margin-left: auto; }

/* The timeline's foot row: "…94 more · show all" beside "hide the timeline". Hide lives at BOTH ends —
   collapsing from the foot of a 40-row timeline otherwise strands the reader far below the band. */
.qa-wf-foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 18px;
    margin-top: 6px;
    padding-top: 2px;
    border-top: 1px dashed var(--qa-cc-line);
}

.qa-wf-more {
    font-family: var(--qa-mono);
    font-size: .6rem;
    color: var(--qa-cc-text-dim);
    padding: 8px 10px;
    background: transparent;
    border: 0;
    text-align: left;
    cursor: pointer;
}

    .qa-wf-more:hover { color: var(--qa-cc-text); }
    .qa-wf-more:focus-visible { outline: 2px solid var(--qa-signal); outline-offset: 1px; }

/* filter chips */
.qa-wf-filters { display: flex; gap: 6px; flex-wrap: wrap; }

.qa-wf-filter {
    font-family: var(--qa-mono);
    font-size: .58rem;
    letter-spacing: .08em;
    text-transform: uppercase;
    font-weight: 700;
    border: 1px solid var(--qa-cc-line);
    border-radius: 999px;
    padding: 2px 9px;
    color: var(--qa-cc-text-dim);
    background: transparent;
    cursor: pointer;
}

    .qa-wf-filter:hover { color: var(--qa-cc-text); }
    .qa-wf-filter:focus-visible { outline: 2px solid var(--qa-signal); outline-offset: 1px; }
    .qa-wf-filter.on { color: var(--qa-midnight); background: var(--qa-signal); border-color: var(--qa-signal); }

/* perf-check verdict strip (Network panel) + the checks editor rows (TestDetail) share the tag pills */
.qa-wf-checks { display: grid; gap: 8px; margin-bottom: 12px; }

/* The verdict/check rows sit OUTSIDE the waterfall's own .qa-matrix-wrap scroller, so they must never
   widen the page: the row wraps and the mono label breaks rather than pushing the layout past the
   viewport (the 320px zero-overflow standard). */
.qa-wf-check, .qa-perf-checkrow { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; font-size: .78rem; min-width: 0; }

.qa-wf-checktag, .qa-perf-checktag {
    font-family: var(--qa-mono);
    font-size: .5rem;
    letter-spacing: .1em;
    text-transform: uppercase;
    font-weight: 700;
    border-radius: 999px;
    padding: 2px 8px;
    flex: none;
}

    .qa-wf-checktag.hard { color: var(--qa-vermilion); border: 1px solid rgba(255, 90, 110, .45); }
    .qa-wf-checktag.soft { color: var(--qa-amber); border: 1px solid rgba(246, 183, 60, .45); }

.qa-wf-checklabel, .qa-perf-checktext { font-family: var(--qa-mono); font-size: .72rem; color: var(--qa-cc-text); min-width: 0; overflow-wrap: anywhere; }

/* The outcome sits right after the label so the row reads as one statement, not two ends to compare. */
.qa-wf-checkstate {
    font-family: var(--qa-mono);
    font-size: .58rem;
    letter-spacing: .06em;
    font-weight: 700;
    flex: 0 1 auto;
    min-width: 0;
    overflow-wrap: anywhere;
}

    .qa-wf-checkstate.pass { color: var(--qa-emerald); }
    .qa-wf-checkstate.soft { color: var(--qa-amber); }
    .qa-wf-checkstate.hard { color: var(--qa-vermilion); }
    .qa-wf-checkstate.skip { color: var(--qa-cc-text-dim); }

.qa-perf-checkrow .qa-perf-kind { margin-left: auto; }

/* the delta footer line — shared by the Network panel and the trends panel */
.qa-wf-delta { margin-top: 14px; padding-top: 10px; border-top: 1px solid var(--qa-cc-line); }

.qa-perf-delta { font-size: .66rem; color: var(--qa-cc-text-dim); line-height: 1.7; overflow-wrap: anywhere; }

.qa-perf-delta .lede { color: var(--qa-cc-text-dim); }
.qa-perf-delta .term { color: var(--qa-cc-text); }
.qa-perf-delta .term.fail { color: var(--qa-vermilion); }
.qa-perf-delta .term.pass { color: var(--qa-emerald); }

/* ---- Performance band (RunDetail) — the always-visible summary layer above the request timeline: the
   pre-cap digest readout with its two doors, the run's vitals, the heaviest endpoints and the native
   <details> disclosure. All of it sits OUTSIDE the waterfall's own .qa-matrix-wrap scroller, so every line
   wraps rather than widening the page (the 320px zero-overflow standard). Nothing here animates. ---- */

/* The band is the page's one scroll target — #network in the URL and the timeline's own "hide" both
   scrollIntoView it. The app bar is FIXED, so a plain block:'start' parks the "Performance" title
   underneath it; this clears the bar (the landing page's section[id] rule is the same idiom, same
   number) and is honoured by both call sites without either having to know the chrome's height. */
#network { scroll-margin-top: 76px; }

.qa-wf-readout {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    font-size: .72rem;
    line-height: 1.9;
    color: var(--qa-cc-text);
    overflow-wrap: anywhere;
}

    .qa-wf-readout .sep { color: var(--qa-cc-line); margin: 0 8px; }
    .qa-wf-readout .dim { color: var(--qa-cc-text-dim); }
    .qa-wf-readout .amber { color: var(--qa-amber); }
    .qa-wf-readout .bad { color: var(--qa-vermilion); }

/* A readout door: a real button that reads as part of the sentence, so the colour it already earned
   (amber slowest / vermilion failures) becomes the way into the filtered timeline. */
.qa-wf-door {
    font: inherit;
    background: none;
    border: 0;
    padding: 0;
    color: inherit;
    cursor: pointer;
    border-bottom: 1px dashed currentColor;
    text-align: left;
    overflow-wrap: anywhere;
}

    .qa-wf-door:hover { color: var(--qa-cc-text); }
    .qa-wf-door:focus-visible { outline: 2px solid var(--qa-signal); outline-offset: 2px; border-radius: 3px; }

/* Vitals: one recessive line, brighter labels, NO good/bad colour (a verdict at N=1 belongs to the check
   rows, not here). The middots are drawn by CSS so the markup stays one span per fact. */
.qa-wf-vitals {
    font-size: .7rem;
    color: var(--qa-cc-text-dim);
    margin-top: 8px;
    line-height: 1.9;
    overflow-wrap: anywhere;
}

    .qa-wf-vitals b { color: var(--qa-cc-text); font-weight: 600; }
    .qa-wf-vital + .qa-wf-vital::before { content: " · "; color: var(--qa-cc-line); }

/* Heaviest-endpoints mini-table — three rows, no header (the caption above is the header). It scrolls
   inside its own .qa-matrix-wrap when a long template can't fit. */
.qa-wf-endpoints {
    border-collapse: collapse;
    font-size: .68rem;
    max-width: 640px;
}

    .qa-wf-endpoints td {
        padding: 6px 8px;
        border-bottom: 1px solid rgba(41, 52, 80, .5);
        color: var(--qa-cc-text);
        white-space: nowrap;
    }

    .qa-wf-endpoints tr:last-child td { border-bottom: none; }
    .qa-wf-endpoints td.r { text-align: right; }
    .qa-wf-endpoints td.dim { color: var(--qa-cc-text-dim); }

/* The disclosure: the run page's own "Technical detail" pattern, sized for a panel. The marker is replaced
   by our own chevron; there is no height transition — the timeline appears and disappears instantly. */
.qa-wf-disc { margin-top: 12px; border-top: 1px dashed var(--qa-cc-line); }

.qa-wf-disc-summary {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 10px 2px 0;
    font-family: var(--qa-mono);
    font-size: .64rem;
    color: var(--qa-cc-text-dim);
    cursor: pointer;
    list-style: none;
}

    .qa-wf-disc-summary::-webkit-details-marker { display: none; }
    .qa-wf-disc-summary::marker { content: ""; }
    .qa-wf-disc-summary:hover { color: var(--qa-signal); }
    .qa-wf-disc-summary:focus-visible { outline: 2px solid var(--qa-signal); outline-offset: 2px; border-radius: 4px; }

.qa-wf-chev {
    width: 0;
    height: 0;
    flex: none;
    border-left: 5px solid currentColor;
    border-top: 4px solid transparent;
    border-bottom: 4px solid transparent;
}

.qa-wf-disc[open] .qa-wf-chev { transform: rotate(90deg); }

.qa-wf-timeline { margin-top: 10px; }

/* the timeline's own controls (they moved out of the panel header — they are waterfall controls) */
.qa-wf-controls {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-bottom: 10px;
}

    .qa-wf-controls .qa-wf-stepselect { margin-left: auto; }

/* the repeated axis under the rows */
.qa-wf-axis.bottom { margin-top: 4px; }

/* the amber variance hint under a timing check in the editor */
.qa-perf-hint {
    font-size: .74rem;
    color: var(--qa-cc-text-dim);
    border-left: 2px solid var(--qa-amber);
    padding: 6px 10px;
    background: rgba(246, 183, 60, .06);
    border-radius: 0 8px 8px 0;
}

    .qa-perf-hint b { color: var(--qa-amber); }

@media (max-width: 600px) {
    .qa-wf { --qa-wf-name-w: 150px; }
}

.qa-loading {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    z-index: 1;
}

.qa-rail {
    width: 340px;
    flex-shrink: 0;
    background: #fff;
    display: flex;
    flex-direction: column;
    border-left: 1px solid #DEE7E7;
}

.qa-rail-header {
    padding: 14px 16px 10px;
    border-bottom: 1px solid #DEE7E7;
}

.qa-rail-steps {
    flex: 1;
    overflow-y: auto;
}

.qa-step {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    border-bottom: 1px solid #EDF2F1;
}

    .qa-step:hover {
        background: #F6F8F8;
    }

.qa-step-text {
    flex: 1;
    min-width: 0;
    overflow-wrap: anywhere;
}

/* ---------- brand wordmark + navigation ---------- */

.qa-wordmark {
    font-family: 'Space Grotesk', 'Inter', system-ui, sans-serif;
    font-weight: 600;
    letter-spacing: -0.015em;
}

/* Active nav item: teal-tint pill with a signal left-edge */
.mud-nav-link.active {
    background-color: rgba(22, 181, 168, .12);
    border-radius: 8px;
    box-shadow: inset 3px 0 0 0 var(--qa-signal-strong);
}

/* ---------- dashboard watch-station hero (Command Center) ---------- */

.qa-hero {
    position: relative;
    overflow: hidden;
    border-radius: 14px;
    padding: 22px 26px;
    background:
        radial-gradient(120% 140% at 88% -20%, rgba(34, 211, 197, .16) 0%, transparent 55%),
        linear-gradient(135deg, var(--qa-midnight) 0%, var(--qa-cc-canvas) 100%);
    border: 1px solid var(--qa-cc-line);
    color: var(--qa-cc-text);
}

.qa-hero-verdict {
    display: flex;
    align-items: center;
    gap: 14px;
}

.qa-hero-title {
    font-family: 'Space Grotesk', 'Inter', sans-serif;
    font-weight: 600;
    font-size: 26px;
    letter-spacing: -0.02em;
    line-height: 1.1;
}

.qa-hero-sub {
    color: var(--qa-cc-text-dim);
    font-size: 13px;
    margin-top: 2px;
}

.qa-hero-dot {
    width: 12px;
    height: 12px;
    border-radius: 50%;
    flex-shrink: 0;
}

/* Verdict severity: the dark bar gets washed with the state hue + a thick coloured left edge, so the
   top of the dashboard reads red / amber / green at a glance — not just via a 12px dot. */
.qa-hero--nominal {
    background:
        radial-gradient(120% 140% at 88% -20%, rgba(16, 185, 129, .14) 0%, transparent 55%),
        linear-gradient(135deg, var(--qa-midnight) 0%, var(--qa-cc-canvas) 100%);
    box-shadow: inset 4px 0 0 0 var(--qa-emerald);
}
.qa-hero--healed {
    background:
        radial-gradient(120% 140% at 88% -20%, rgba(245, 165, 36, .20) 0%, transparent 55%),
        linear-gradient(135deg, var(--qa-midnight) 0%, var(--qa-cc-canvas) 100%);
    box-shadow: inset 4px 0 0 0 var(--qa-amber);
}
.qa-hero--alert {
    background:
        radial-gradient(120% 140% at 88% -20%, rgba(244, 81, 59, .22) 0%, transparent 55%),
        linear-gradient(135deg, var(--qa-midnight) 0%, var(--qa-cc-canvas) 100%);
    box-shadow: inset 4px 0 0 0 var(--qa-vermilion);
}

.qa-hero--nominal .qa-hero-dot { background: var(--qa-emerald); box-shadow: 0 0 0 4px rgba(16, 185, 129, .18); }
.qa-hero--healed .qa-hero-dot  { background: var(--qa-amber); box-shadow: 0 0 0 4px rgba(245, 165, 36, .18); }
.qa-hero--alert .qa-hero-dot   { background: var(--qa-vermilion); box-shadow: 0 0 0 4px rgba(244, 81, 59, .18); }

.qa-hero-stats {
    display: flex;
    flex-wrap: wrap;
    gap: 28px;
    margin-top: 18px;
    padding-top: 16px;
    border-top: 1px solid var(--qa-cc-line);
}

.qa-hero-stat-value {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-variant-numeric: tabular-nums;
    font-size: 22px;
    font-weight: 600;
    color: var(--qa-cc-text);
    line-height: 1.1;
}

.qa-hero-stat-label {
    font-size: 12px;
    color: var(--qa-cc-text-dim);
    margin-top: 2px;
}

/* Slim hero variant — reads as a status bar, not a billboard */
.qa-hero--slim { padding: 16px 22px; }
.qa-hero--slim .qa-hero-title { font-size: 22px; }
.qa-hero--slim .qa-hero-stats { margin-top: 12px; padding-top: 12px; gap: 24px; }

/* ---------- status tiles + sparkline (mission control) ---------- */

.qa-tile { transition: box-shadow .15s ease, transform .15s ease; }
.qa-tile:hover { box-shadow: 0 4px 16px rgba(11, 31, 42, .08); transform: translateY(-1px); }

.qa-tile-name {
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.qa-tile-stat {
    font-size: 15px;
    font-weight: 600;
    color: var(--qa-midnight);
    line-height: 1.1;
}

.qa-tile-lbl {
    font-size: 10.5px;
    color: var(--mud-palette-text-secondary);
    text-transform: uppercase;
    letter-spacing: .04em;
    margin-top: 1px;
}

/* Activity sparkline — stacked pass/fail bars, pure CSS */
.qa-spark {
    display: flex;
    align-items: flex-end;
    gap: 2px;
    height: 56px;
}

.qa-spark-col {
    flex: 1;
    min-width: 3px;
    height: 100%;
    display: flex;
    flex-direction: column-reverse;
}

    .qa-spark-col > span {
        display: block;
        border-radius: 1px;
        transform-origin: bottom;
        animation: qa-spark-grow .5s ease-out both;
    }

.qa-spark-pass { background: var(--qa-emerald); }
.qa-spark-heal { background: var(--qa-amber); }
.qa-spark-fail { background: var(--qa-vermilion); }
.qa-spark-other { background: #94A3B8; }
/* Neutral series for the admin dashboards' SparkBars (request rate, DAU, token spend) */
.qa-spark-a { background: #2DD4BF; }
.qa-spark-b { background: #818CF8; }
/* Unmatched-route noise (scanner/bot 404s) — deliberately quieter than pass/fail */
.qa-spark-noise { background: #64748B; }

/* ---- Performance trend (TestDetail) — bespoke journey bars + per-endpoint sparks. Bars are STATIC (no
   grow animation) and heights are max-normalized, the SparkBars idiom. ---- */
.qa-trend {
    display: flex;
    align-items: flex-end;
    gap: 3px;
    height: 74px;
    padding: 8px 6px 0;
    position: relative;
}

    .qa-trend b {
        flex: 1;
        min-width: 8px;
        border-radius: 2px 2px 0 0;
        position: relative;
        background: rgba(63, 217, 138, .6);
    }

    /* Verdict-first: a passing run is emerald, a failed run vermilion, healed amber, cancelled slate —
       a non-passing run is NEVER a green "fine" bar. The trend signal (amber slower / slate spike) rides
       only on genuinely passing runs. */
    .qa-trend b.pass { background: rgba(63, 217, 138, .6); }
    .qa-trend b.amber, .qa-trend b.heal { background: rgba(246, 183, 60, .75); }
    .qa-trend b.spike, .qa-trend b.cancelled { background: rgba(138, 149, 173, .5); }
    .qa-trend b.fail { background: rgba(255, 90, 110, .7); }

.qa-trend-base { position: absolute; left: 6px; right: 6px; border-top: 1px dashed rgba(230, 237, 250, .4); }

    .qa-trend-base s {
        position: absolute;
        right: 0;
        top: -14px;
        text-decoration: none;
        font-family: var(--qa-mono);
        font-size: .52rem;
        color: var(--qa-cc-text-dim);
        letter-spacing: .06em;
    }

.qa-trend-legend {
    display: flex;
    gap: 16px;
    flex-wrap: wrap;
    font-family: var(--qa-mono);
    font-size: .56rem;
    color: var(--qa-cc-text-dim);
    letter-spacing: .06em;
    padding: 6px 6px 0;
}

    .qa-trend-legend b { display: inline-block; width: 12px; height: 7px; border-radius: 2px; margin-right: 5px; vertical-align: -1px; }
    .qa-trend-legend b.spike { background: rgba(138, 149, 173, .5); }
    .qa-trend-legend b.amber { background: rgba(246, 183, 60, .75); }
    .qa-trend-legend b.fail { background: rgba(255, 90, 110, .7); }

.qa-perf-spark { display: inline-flex; align-items: flex-end; gap: 2px; height: 18px; vertical-align: middle; }

    .qa-perf-spark i { width: 5px; border-radius: 1px; background: rgba(63, 217, 138, .55); }
    .qa-perf-spark i.pass { background: rgba(63, 217, 138, .55); }
    .qa-perf-spark i.amber, .qa-perf-spark i.heal { background: rgba(246, 183, 60, .8); }
    .qa-perf-spark i.spike, .qa-perf-spark i.cancelled { background: rgba(138, 149, 173, .5); }
    .qa-perf-spark i.fail { background: rgba(255, 90, 110, .75); }

.qa-perf-endpoints table { font-size: .72rem; }
    .qa-perf-endpoints th { font-family: var(--qa-mono); font-size: .58rem; letter-spacing: .08em; text-transform: uppercase; color: var(--qa-cc-text-dim); }

/* Clickable status-filter rows (Runs side rail) */
.qa-filter-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    border-radius: 8px;
    cursor: pointer;
    font-size: 14px;
    color: var(--mud-palette-text-primary);
}

    .qa-filter-row:hover { background: #F0F4F3; }

.qa-filter-active {
    background: rgba(22, 181, 168, .12);
    color: var(--mud-palette-primary);
    font-weight: 600;
}

/* ---------- tags ---------- */
.qa-tags {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
}

.qa-tag {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 2px 9px;
    border-radius: 999px;
    border: 1px solid var(--mud-palette-lines-default);
    background: var(--mud-palette-background-grey, #F0F4F3);
    font-size: 12px;
    line-height: 18px;
    color: var(--mud-palette-text-primary);
    white-space: nowrap;
}

.qa-tag-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex: none;
}

.qa-tag-clickable { cursor: pointer; }
.qa-tag-clickable:hover { border-color: var(--mud-palette-primary); }

.qa-tag-active {
    background: rgba(22, 181, 168, .12);
    border-color: var(--mud-palette-primary);
    color: var(--mud-palette-primary);
    font-weight: 600;
}

.qa-tag-x {
    cursor: pointer;
    font-size: 15px;
    line-height: 1;
    color: var(--mud-palette-text-secondary);
    margin-left: 1px;
}

    .qa-tag-x:hover { color: var(--mud-palette-error); }

html[data-theme="dark"] .qa-tag { background: var(--qa-cc-surface2); }

/* ---------- inline tag input (token-input pattern) ---------- */
.qa-taginput {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    min-height: 44px;
    max-width: 520px;
    padding: 6px 8px;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 8px;
    background: var(--mud-palette-surface);
    cursor: text;
}

.qa-taginput-focus {
    border-color: var(--mud-palette-primary);
    box-shadow: 0 0 0 1px var(--mud-palette-primary);
}

.qa-taginput-field {
    flex: 1 1 120px;
    min-width: 120px;
    border: none;
    outline: none;
    background: transparent;
    color: var(--mud-palette-text-primary);
    font-size: 14px;
    padding: 4px 2px;
}

.qa-taginput-add {
    display: inline-flex;
    align-items: center;
    padding: 2px;
    border: none;
    border-radius: 6px;
    background: transparent;
    color: var(--mud-palette-primary);
    cursor: pointer;
}

    .qa-taginput-add:disabled { color: var(--mud-palette-action-disabled); cursor: default; }

.qa-taginput-menu {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    z-index: 10;
    min-width: 220px;
    max-width: 320px;
    max-height: 220px;
    overflow-y: auto;
    padding: 4px;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 8px;
    background: var(--mud-palette-surface);
    box-shadow: 0 6px 20px rgba(0, 0, 0, .15);
}

.qa-taginput-opt {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    border-radius: 6px;
    font-size: 14px;
    cursor: pointer;
}

    .qa-taginput-opt:hover { background: #F0F4F3; }

html[data-theme="dark"] .qa-taginput-opt:hover { background: var(--qa-cc-surface2); }


@keyframes qa-spark-grow { from { transform: scaleY(0); } to { transform: scaleY(1); } }

@media (prefers-reduced-motion: reduce) {
    .qa-spark-col > span { animation: none; }
}

/* ---------- dark mode (authenticated app only) ----------
   Scoped under html[data-theme="dark"] AND an authenticated-app marker (.mud-layout, recorder/tile
   classes) so the anonymous landing and the static-SSR auth pages stay light even when the attribute
   is set. MudBlazor's IsDarkMode swaps only --mud-palette-*; these rules fix custom surfaces that
   hardcode light colours, and the .mud-layout background bridges the brief pre-circuit window so the
   shell paints dark from the first frame instead of flashing white. */
html[data-theme="dark"] .mud-layout { background: var(--qa-cc-canvas); color: var(--qa-cc-text); }

/* recorder right rail — hardcoded #fff / light lines */
html[data-theme="dark"] .qa-rail { background: var(--qa-cc-surface1); border-left-color: var(--qa-cc-line); }
html[data-theme="dark"] .qa-rail-header { border-bottom-color: var(--qa-cc-line); }
html[data-theme="dark"] .qa-step { border-bottom-color: var(--qa-cc-line); }
html[data-theme="dark"] .qa-step:hover { background: var(--qa-cc-surface2); }

/* status tiles + Runs filter rows — light hovers + near-black ink that vanishes on the dark canvas */
html[data-theme="dark"] .qa-tile-stat { color: var(--qa-cc-text); }
html[data-theme="dark"] .qa-tile:hover { box-shadow: 0 4px 16px rgba(0, 0, 0, .4); }
html[data-theme="dark"] .qa-filter-row:hover { background: var(--qa-cc-surface2); }

/* ===================== NIGHT WATCH — Wardyr full-dark overrides ===================== */
/* Wardyr is dark-only. These flip the formerly light-only surfaces (global base, landing, auth) to
   the midnight/aurora palette, add the monospace wordmark identity + pixel-guardian canvas + the
   arcade panels, and force readable dark ink on the ward-teal primary. */

html, body { background: var(--qa-cc-canvas); color: var(--qa-cc-text); }

/* wordmark → guardian-console monospace */
.qa-wordmark, .qa-lp-brand, .qa-auth-brand-word {
    font-family: var(--qa-mono) !important;
    letter-spacing: .16em;
    text-transform: uppercase;
    font-weight: 700;
    color: var(--qa-cc-text);
}

/* filled primary buttons: dark ink on the ward-teal for contrast */
.mud-button-filled-primary { color: #06281f !important; font-weight: 600; }
.mud-button-filled-primary .mud-icon-root { color: #06281f !important; }

/* pixel guardian + brand-mark canvases (K1 Warden) */
.qa-guardian, .qa-mark { display: block; image-rendering: pixelated; image-rendering: crisp-edges; }
.qa-watch .qa-mark { position: relative; z-index: 1; }

/* K1 scene canvases (wardburst / arming / unposted / arcade) stay crisp like the guardian */
canvas[data-arcade], canvas[data-glyph] { image-rendering: pixelated; image-rendering: crisp-edges; }

/* the all-clear ward burst — the "What Wardyr found" panel's empty state.
   G1 "incident-card ground": same ink container material the incident cards use (never void). */
.qa-wardburst { position: relative; border: 1px solid var(--qa-cc-line); border-radius: 12px; overflow: hidden; background: var(--qa-cc-canvas); }
.qa-wardburst canvas { display: block; width: 100%; height: 240px; }

/* the zero-tests "Unposted" hero */
.qa-unposted { display: flex; justify-content: center; }

/* ---- auth split-screen → dark ---- */
.qa-auth-shell { background: var(--qa-cc-canvas); }
.qa-auth-brand {
    background:
        radial-gradient(120% 90% at 80% 6%, rgba(139, 123, 255, .18) 0%, transparent 55%),
        radial-gradient(90% 70% at 8% 100%, rgba(56, 232, 198, .10) 0%, transparent 55%),
        linear-gradient(160deg, #0E1322 0%, #0B0F1A 70%);
    border-right: 1px solid var(--qa-cc-line);
}
.qa-auth-brand-inner { color: var(--qa-cc-text); }
.qa-auth-brand-inner h1 { color: #F3F7FF; }
.qa-auth-brand-inner p { color: var(--qa-cc-text-dim); }
.qa-auth-points li { color: #B7C2D8; }
.qa-auth-form { background: var(--qa-cc-canvas); }
.qa-auth-title { color: #F3F7FF; }
.qa-auth-sub { color: var(--qa-cc-text-dim); }
.qa-field-label { color: #B7C2D8; }
.qa-field { background: #10172A; border: 1px solid var(--qa-cc-line); color: var(--qa-cc-text); }
.qa-field::placeholder { color: #56607A; }
.qa-field:focus { outline: none; border-color: var(--qa-signal); box-shadow: 0 0 0 3px rgba(56, 232, 198, .16); }
.qa-auth-button { background: var(--qa-signal); color: #06281f; }
.qa-auth-button:hover { background: #5BF0D3; }
.qa-field-hint { color: #6B7689; }
.qa-field-eye { color: var(--qa-signal); }
.qa-field-aside a, .qa-auth-foot a, .qa-auth-linkbtn { color: var(--qa-signal); }
.qa-auth-foot { color: var(--qa-cc-text-dim); }
.qa-auth-error { background: rgba(255, 90, 110, .10); border-color: rgba(255, 90, 110, .35); color: #FF97A4; }
.qa-auth-success { background: rgba(63, 217, 138, .10); border-color: rgba(63, 217, 138, .35); color: #7CE9B0; }

/* auth arcade panel */
.qa-auth-arcade {
    position: relative;
    width: 100%;
    max-width: 360px;
    aspect-ratio: 4 / 5;
    margin: 0 auto 22px;
    border: 1px solid var(--qa-cc-line);
    border-radius: 14px;
    overflow: hidden;
    background: #05080F;
}
.qa-auth-arcade canvas { width: 100%; height: 100%; display: block; }
.qa-auth-arcade::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: repeating-linear-gradient(0deg, rgba(0,0,0,0) 0 2px, rgba(0,0,0,.16) 2px 4px);
}
.qa-auth-bezel { position: absolute; inset: 0; pointer-events: none; border-radius: 14px; box-shadow: inset 0 0 80px -10px rgba(56, 232, 198, .25); }

/* ---- marketing landing → dark ---- */
.qa-lp { color: var(--qa-cc-text); background: var(--qa-cc-canvas); }
.qa-lp-top { background: rgba(11, 15, 26, .82); backdrop-filter: blur(10px); border-bottom-color: var(--qa-cc-line); }
.qa-lp-brand { color: var(--qa-cc-text); }
.qa-lp-hero {
    background:
        radial-gradient(90% 80% at 92% 0%, rgba(139, 123, 255, .18) 0%, transparent 55%),
        radial-gradient(70% 60% at 0% 10%, rgba(56, 232, 198, .10) 0%, transparent 55%),
        linear-gradient(160deg, #0E1322 0%, #0B0F1A 60%);
}
.qa-lp-eyebrow { color: var(--qa-signal); }
.qa-lp-hero-copy h1 { color: #F3F7FF; }
.qa-lp-hero-copy p { color: var(--qa-cc-text-dim); }
.qa-lp-band h2 { color: #F3F7FF; }
.qa-lp-band { background: radial-gradient(600px 300px at 50% 0, rgba(139, 123, 255, .18), transparent 65%), var(--qa-cc-surface1); }

/* landing hero arcade panel */
.qa-arcade { position: relative; width: 100%; max-width: 440px; margin-left: auto; aspect-ratio: 4 / 5;
    border: 1px solid var(--qa-cc-line); border-radius: 16px; overflow: hidden; background: #05080F; }
.qa-arcade canvas { width: 100%; height: 100%; display: block; }
.qa-arcade::after { content: ""; position: absolute; inset: 0; pointer-events: none;
    background: repeating-linear-gradient(0deg, rgba(0,0,0,0) 0 2px, rgba(0,0,0,.16) 2px 4px); }

@media (max-width: 800px) { .qa-auth-arcade { max-width: 280px; } }

/* ---- circuit reconnect overlay (Night Watch) ---- */
#components-reconnect-modal { display: none; }
#components-reconnect-modal.components-reconnect-show,
#components-reconnect-modal.components-reconnect-failed,
#components-reconnect-modal.components-reconnect-rejected {
    display: flex;
    position: fixed;
    inset: 0;
    z-index: 3000;
    align-items: center;
    justify-content: center;
}
#components-reconnect-modal .nw-reconnect-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(5, 8, 15, .72);
    backdrop-filter: blur(3px);
}
#components-reconnect-modal .nw-reconnect-card {
    position: relative;
    z-index: 1;
    width: min(92vw, 380px);
    background: var(--qa-cc-surface1);
    border: 1px solid var(--qa-cc-line);
    border-radius: 14px;
    padding: 30px 28px;
    text-align: center;
    color: var(--qa-cc-text);
    box-shadow: 0 30px 80px -30px rgba(0, 0, 0, .85);
    display: flex;
    flex-direction: column;
    align-items: center;
}
#components-reconnect-modal canvas[data-arcade="arming"] { display: block; margin: 0 auto 16px; }
#components-reconnect-modal h3 { font-size: 1.12rem; margin: 0; color: #F3F7FF; }
#components-reconnect-modal p { font-size: .9rem; color: var(--qa-cc-text-dim); margin: 8px 0 0; max-width: 30ch; }
#components-reconnect-modal button {
    margin-top: 18px;
    font-family: var(--qa-mono);
    font-weight: 700;
    font-size: .78rem;
    letter-spacing: .06em;
    text-transform: uppercase;
    padding: 11px 22px;
    border: 0;
    cursor: pointer;
    background: var(--qa-signal);
    color: #06281f;
    border-radius: 9px;
}
#components-reconnect-modal button:hover { background: #5BF0D3; }
/* show only the message block that matches Blazor's current state class */
#components-reconnect-modal .nw-reconnect-show,
#components-reconnect-modal .nw-reconnect-failed,
#components-reconnect-modal .nw-reconnect-rejected { display: none; }
#components-reconnect-modal.components-reconnect-show .nw-reconnect-show { display: block; }
#components-reconnect-modal.components-reconnect-failed .nw-reconnect-failed { display: block; }
#components-reconnect-modal.components-reconnect-rejected .nw-reconnect-rejected { display: block; }
/* (once rejected, wardyr.js closes the guardian's eyes and stops the sweep — the scene reacts to
   the same components-reconnect-* classes, no CSS needed) */

/* ---- dashboard "watch-station" HUD typography ---- */
.qa-hud { font-family: var(--qa-mono) !important; text-transform: uppercase; letter-spacing: .14em; font-weight: 700; }
/* one canonical page-title treatment — every section page's top heading reads as a watch-station readout */
.qa-page-title { font-family: var(--qa-mono) !important; text-transform: uppercase; letter-spacing: .13em; font-weight: 700; color: #F3F7FF; }
/* one canonical width for the bounded (non-data) pages — account, members, notifications, pricing — so they
   read as one consistent column instead of each picking its own max-width. Centered within the layout
   container; data/list pages (tests, sites, runs) deliberately stay full-width and don't use this. */
.qa-bounded-page { max-width: 1200px; margin-inline: auto; }

/* ---- account settings shell — rail (≥960) / wrapping strip (<960) ---- */
/* The /account/* pages share one sub-navigated shell (AccountShell.razor): a sticky left rail with the
   WORKSPACE / YOU groups on desktop that flattens into a wrapping button strip on tablet/phone. All
   colours ride existing tokens; the active item is a filled-primary MudButton so the global
   dark-ink-on-teal contrast rule applies untouched. */
.qa-account-shell { display: grid; grid-template-columns: 210px minmax(0, 1fr); gap: 24px; align-items: start; }
.qa-account-rail { position: sticky; top: 80px; display: flex; flex-direction: column; gap: 4px; background: var(--qa-cc-surface1); border: 1px solid var(--qa-cc-line); border-radius: 13px; padding: 10px; }
.qa-account-rail-head { display: flex; flex-direction: column; gap: 2px; padding: 4px 10px 10px; border-bottom: 1px solid var(--qa-cc-line); margin-bottom: 6px; min-width: 0; }
.qa-account-rail-ws { font-weight: 600; font-size: .86rem; color: var(--qa-cc-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.qa-account-rail-group { font-family: var(--qa-mono); font-size: .6rem; letter-spacing: .14em; text-transform: uppercase; color: var(--qa-cc-text-dim); padding: 8px 10px 2px; }
.qa-account-rail-item { justify-content: flex-start !important; text-transform: none !important; }
@media (max-width: 959.98px) {
    /* Below the drawer breakpoint the rail becomes a wrapping strip above the content — flex-wrap with
       no fixed widths is what keeps 320px at zero horizontal overflow. */
    .qa-account-shell { display: block; }
    .qa-account-rail { position: static; flex-direction: row; flex-wrap: wrap; align-items: center; gap: 4px 6px; margin-bottom: 16px; }
    .qa-account-rail-head { flex-direction: row; align-items: baseline; gap: 10px; border-bottom: 0; padding: 4px 10px 4px 6px; margin: 0; flex: 0 1 auto; }
    .qa-account-rail-group { display: none; }
}
.qa-tile-lbl { font-family: var(--qa-mono); text-transform: uppercase; letter-spacing: .1em; font-size: .62rem; color: var(--qa-cc-text-dim); }
.qa-tile-stat { font-variant-numeric: tabular-nums; }
.qa-hero-stat-label { font-family: var(--qa-mono); text-transform: uppercase; letter-spacing: .14em; }
.qa-hero-stat-value { font-variant-numeric: tabular-nums; }

/* status pills — the watch-station status chips */
.qa-pill { font-family: var(--qa-mono); font-size: .62rem; letter-spacing: .1em; text-transform: uppercase; font-weight: 700; padding: 3px 9px; border-radius: 999px; display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; line-height: 1.5; }
.qa-pill::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }
.qa-pill.pass { color: var(--qa-emerald); background: rgba(63, 217, 138, .13); }
.qa-pill.healed { color: var(--qa-amber); background: rgba(246, 183, 60, .14); }
.qa-pill.fail { color: var(--qa-vermilion); background: rgba(255, 90, 110, .14); }
.qa-pill.run { color: var(--qa-signal); background: rgba(56, 232, 198, .13); }
.qa-pill.wait { color: var(--qa-cc-text-dim); background: rgba(138, 149, 173, .12); }
/* held by the monthly run allowance — a billing state, deliberately amber (never vermilion: red stays
   reserved for real test failures). Filled, unlike the tinted pills: it marks something NOT running. */
.qa-pill.held { color: #3a2b07; background: var(--qa-amber); }
.qa-pill.held::before { display: none; } /* the ❚❚ glyph in the text carries the "paused" shape */
/* stopped by a PLAN gate (downgrade/trial end) — unlike held it does NOT self-resume, so it reads a
   notch firmer: rune-violet, the plan/entitlement hue (still never vermilion — nothing failed). */
.qa-pill.stopped { color: #17102e; background: var(--qa-rune); }
.qa-pill.stopped::before { display: none; } /* the ■ glyph carries the "stopped" shape */
/* a run a person deliberately stopped (Cancelled) — a verdict-less neutral slate, visually distinct
   from Queued's wait pill (they used to share one) and never green or red: nobody's verdict. */
.qa-pill.neutral { color: #aab4cc; background: rgba(126, 138, 166, .16); border: 1px solid rgba(126, 138, 166, .35); }

/* NOW/HISTORY clock bands — every dashboard number belongs to exactly one clock, and the band says
   which: NOW = each journey's latest run (any age); HISTORY = runs in the selected 24h/7d/30d window. */
.qa-band { display: flex; align-items: center; gap: 10px; }
.qa-band-lbl { font-family: var(--qa-mono); font-size: .6rem; letter-spacing: .18em; text-transform: uppercase; font-weight: 700; color: var(--qa-cc-text-dim); white-space: nowrap; }
.qa-band-rule { flex: 1 1 auto; height: 1px; background: var(--qa-cc-line); }

/* dashboard stat tiles row (watch-station) — five current-state tiles */
/* Flex (not a fixed-column grid) so conditional tiles — Snoozed, the wide "Runs this month" meter —
   stay on ONE row while there's space and wrap gracefully below it, instead of a fixed 5-column grid
   banishing the 6th tile to its own row. */
.qa-statrow { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 14px; }
.qa-stat { background: var(--qa-cc-surface1); border: 1px solid var(--qa-cc-line); border-radius: 12px; padding: 14px 16px; flex: 1 1 140px; min-width: 0; }
.qa-stat--runs { flex: 1.8 1 250px; }
.qa-stat--runs .k { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.qa-stat .k { font-family: var(--qa-mono); font-size: .6rem; letter-spacing: .12em; text-transform: uppercase; color: var(--qa-cc-text-dim); }
.qa-stat .v { font-family: var(--qa-mono); font-size: 1.7rem; font-weight: 700; color: #F3F7FF; margin-top: 6px; font-variant-numeric: tabular-nums; display: flex; align-items: baseline; gap: 8px; }
.qa-stat .v small { font-size: .78rem; color: var(--qa-emerald); font-weight: 700; }
.qa-stat .v small.warn { color: var(--qa-amber); }
.qa-stat .v small.dim { color: var(--qa-cc-text-dim); }

/* "suite" chip on suite-child run rows — links the child run back to its parent suite run. Violet (the
   secondary accent), never a status colour, so it can't be misread as pass/fail. */
.qa-suitechip { font-family: var(--qa-mono); font-size: .56rem; letter-spacing: .08em; text-transform: uppercase; font-weight: 700; color: var(--qa-rune) !important; border: 1px solid rgba(139, 123, 255, .4); border-radius: 5px; padding: 1px 6px; white-space: nowrap; text-decoration: none; }
.qa-suitechip:hover { background: rgba(139, 123, 255, .12); text-decoration: none; }

/* verdict card — guardian (left) · pill + headline + impact (mid) · failing-since meta (right) */
.qa-verdict {
    display: grid;
    grid-template-columns: auto 1fr auto;
    gap: 22px;
    align-items: center;
    border: 1px solid var(--qa-cc-line);
    border-left: 3px solid var(--qa-vermilion);
    border-radius: 13px;
    padding: 18px 24px;
    background: linear-gradient(120deg, rgba(255, 90, 110, .12), var(--qa-cc-surface1) 60%);
}
.qa-verdict--healed { border-left-color: var(--qa-amber); background: linear-gradient(120deg, rgba(246, 183, 60, .12), var(--qa-cc-surface1) 60%); }
.qa-verdict--nominal { border-left-color: var(--qa-emerald); background: linear-gradient(120deg, rgba(63, 217, 138, .10), var(--qa-cc-surface1) 60%); }
.qa-verdict--standby { border-left-color: var(--qa-cc-line); background: var(--qa-cc-surface1); }
.qa-verdict .qa-guardian { width: 84px; height: 84px; flex: none; }
.qa-verdict-title { font-size: 1.2rem; font-weight: 700; color: #F3F7FF; margin-top: 8px; }
.qa-verdict-sub { color: var(--qa-cc-text-dim); font-size: .9rem; margin-top: 4px; max-width: 72ch; }
.qa-verdict-meta { text-align: right; font-family: var(--qa-mono); font-size: .72rem; color: var(--qa-cc-text-dim); letter-spacing: .06em; white-space: nowrap; align-self: center; }
.qa-verdict-meta b { display: block; color: var(--qa-cc-text); font-size: 1rem; margin: 2px 0; }
@media (max-width: 760px) {
    .qa-verdict { grid-template-columns: auto 1fr; }
    .qa-verdict-meta { grid-column: 1 / -1; text-align: left; }
}

/* dashboard journeys table */
.qa-jtable-wrap { overflow-x: auto; border: 1px solid var(--qa-cc-line); border-radius: 13px; background: var(--qa-cc-surface1); }
.qa-jtable { width: 100%; border-collapse: collapse; }
.qa-jtable thead th { font-family: var(--qa-mono); font-size: .6rem; letter-spacing: .12em; text-transform: uppercase; color: var(--qa-cc-text-dim); text-align: left; padding: 11px 16px; font-weight: 600; }
.qa-jtable tbody td { padding: 12px 16px; border-top: 1px solid var(--qa-cc-line); font-size: .9rem; vertical-align: middle; }
.qa-jtable tbody tr:hover { background: var(--qa-cc-surface2); }
.qa-jname b { display: block; color: #F3F7FF; font-weight: 600; }
.qa-jname span { font-family: var(--qa-mono); font-size: .68rem; color: var(--qa-cc-text-dim); }
.qa-jtable td.num { font-family: var(--qa-mono); font-variant-numeric: tabular-nums; color: var(--qa-cc-text); white-space: nowrap; }
.qa-jdots { display: inline-flex; gap: 3px; }
.qa-jdots i { width: 7px; height: 7px; border-radius: 2px; display: block; background: var(--qa-cc-line); }
.qa-jdots i.p { background: var(--qa-emerald); }
.qa-jdots i.h { background: var(--qa-amber); }
.qa-jdots i.f { background: var(--qa-vermilion); }
/* Larger, linkable strip cells (suite tiles + expanded member rows) — same colours, bigger hit target. */
.qa-jdots a { width: 9px; height: 9px; border-radius: 2px; display: block; background: var(--qa-cc-line); }
.qa-jdots a.p { background: var(--qa-emerald); }
.qa-jdots a.h { background: var(--qa-amber); }
.qa-jdots a.f { background: var(--qa-vermilion); }
.qa-jdots a:focus-visible { outline: 2px solid var(--qa-signal); outline-offset: 1px; }
@media (max-width: 760px) { .qa-stat { flex-basis: calc(50% - 7px); } .qa-stat--runs { flex-basis: 100%; } }

/* Step-editor deep link (run page's "Open step N in the editor"): the target step row flashes once so
   the eye lands on the right step after the jump. */
.qa-step-flash { animation: qa-step-flash 2.4s ease-out 1; border-radius: 6px; }
@keyframes qa-step-flash { 0% { background: rgba(246, 183, 60, .3); } 100% { background: transparent; } }
@media (prefers-reduced-motion: reduce) { .qa-step-flash { animation: none; background: rgba(246, 183, 60, .18); } }

/* Suite member-history matrix (SuiteDetail "Member history" + shared SuiteMatrix component): rows =
   member tests, columns = the last N suite runs. Scrolls horizontally inside its panel, never the page. */
.qa-matrix-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.qa-matrix { border-collapse: collapse; font-family: var(--qa-mono); font-variant-numeric: tabular-nums; }
.qa-matrix th { font-size: .6rem; letter-spacing: .08em; text-transform: uppercase; color: var(--qa-cc-text-dim); font-weight: 600; padding: 8px 9px; text-align: center; white-space: nowrap; }
.qa-matrix th.qa-matrix-rowh, .qa-matrix td.qa-matrix-rowh { text-align: left; font-family: var(--qa-sans, Inter, sans-serif); letter-spacing: 0; text-transform: none; font-size: .86rem; color: var(--qa-cc-text); min-width: 160px; position: sticky; left: 0; background: var(--qa-cc-surface1); }
.qa-matrix td { padding: 6px 9px; text-align: center; border-top: 1px solid rgba(41, 52, 80, .5); }
.qa-matrix td.qa-matrix-rowh.gone { color: var(--qa-cc-text-dim); font-style: italic; }
.qa-matrix .qa-cell { width: 15px; height: 15px; border-radius: 3px; display: inline-block; background: var(--qa-cc-line); }
.qa-matrix a.qa-cell:focus-visible { outline: 2px solid var(--qa-signal); outline-offset: 1px; }
.qa-matrix .qa-cell.p { background: var(--qa-emerald); }
.qa-matrix .qa-cell.h { background: var(--qa-amber); }
.qa-matrix .qa-cell.f { background: var(--qa-vermilion); }
.qa-matrix .qa-cell-none { color: var(--qa-cc-text-dim); font-size: .7rem; }

/* dashboard panels (Journeys / What Wardyr found) */
.qa-panel { background: var(--qa-cc-surface1); border: 1px solid var(--qa-cc-line); border-radius: 13px; overflow: hidden; }
.qa-panel-h { display: flex; align-items: center; gap: 10px; padding: 13px 18px; border-bottom: 1px solid var(--qa-cc-line); }
.qa-panel-b { padding: 8px 10px; }
.qa-panel .qa-jtable-wrap { border: 0; border-radius: 0; background: transparent; }

/* Dashboard body: Suites (top-left) + History (bottom-left) share the LEFT column as independent-height
   blocks; the incidents panel floats in the RIGHT column beside them. Deliberately FLOATS, not a grid:
   a grid row-span makes a very tall incidents list balloon the shared left rows and strand History in a
   large dead gap. With floats, History clears below Suites (contiguous, ~24px apart) and a taller
   incidents column simply overflows past History instead of pushing it down. DOM order is
   Suites → incidents → History, so on mobile (floats off) they stack in that order — incidents stays
   SECOND. Panels manage their own inner overflow, so wide tables still scroll rather than break the float. */
.qa-dash-cols::after { content: ""; display: block; clear: both; }
.qa-col-a    { float: left; width: 58%; }
.qa-col-b    { float: left; width: 58%; clear: left; margin-top: 24px; }
.qa-col-side { float: right; width: 40%; }
@media (max-width: 959.98px) {
    .qa-col-a, .qa-col-b, .qa-col-side { float: none; width: auto; clear: none; }
    .qa-col-side, .qa-col-b { margin-top: 24px; }
}
/* RCA "What Wardyr found" — three labelled segments */
.qa-rca { border: 1px solid var(--qa-cc-line); border-radius: 10px; overflow: hidden; margin-top: 8px; }
.qa-rca-seg { padding: 11px 14px; border-bottom: 1px solid var(--qa-cc-line); }
.qa-rca-seg:last-child { border-bottom: 0; }
.qa-rca-lbl { font-family: var(--qa-mono); font-size: .6rem; letter-spacing: .12em; text-transform: uppercase; margin-bottom: 6px; display: flex; align-items: center; gap: 7px; }
.qa-rca-lbl::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.qa-rca-lbl.biz { color: var(--qa-amber); }
.qa-rca-lbl.tech { color: var(--qa-rune); }
.qa-rca-lbl.fix { color: var(--qa-signal); }
.qa-rca-seg p { font-size: .88rem; color: var(--qa-cc-text); margin: 0; line-height: 1.5; }
/* incident action row: whole buttons wrap (never mid-word), left-aligned */
.qa-inc-actions { row-gap: 6px; }
.qa-inc-actions .mud-button-root { white-space: nowrap; }

/* ===================== RESPONSIVE — mobile audit fixes (desktop → 320px) ===================== */

/* Show/hide swaps by width. Only ever set display:none, so the shown element keeps its natural
   display (works for MudButton/MudMenu/MudText alike, no flash — pure CSS, no server round-trip). */
@media (min-width: 600px)   { .qa-show-narrow { display: none !important; } }
@media (max-width: 599.98px) { .qa-hide-narrow { display: none !important; } }

/* A row of controls/buttons that should stack full-width on phones (invite row, account sub-nav,
   plan "add scenario" inputs, plan author bar). Overrides MudStack's row direction. */
@media (max-width: 599.98px) {
    .qa-stack-narrow { flex-direction: column !important; align-items: stretch !important; width: 100% !important; }
    .qa-stack-narrow > * { width: 100% !important; }
}

/* app-bar: keep the workspace-menu label from ballooning; it truncates instead of forcing overflow.
   overflow:clip (not hidden) + a clip-margin so the flex row's AccountCircle icon — which slightly
   exceeds the text line-box — is never shaved, while a long workspace name still clips near 40vw. */
.qa-orgmenu .mud-button-label { max-width: 40vw; overflow: clip; overflow-clip-margin: 8px; text-overflow: ellipsis; }

/* Live recorder: wrap the toolbar and stack the step rail under the stage on tablet/phone, so the
   fixed 828px toolbar + fixed 340px rail no longer overflow the viewport. */
@media (max-width: 960px) {
    .qa-toolbar { flex-wrap: wrap; }
    .qa-toolbar .mud-button-group-root { flex-wrap: wrap; }
    .qa-urlbar { flex: 1 1 160px; width: auto; min-width: 0; }
    .qa-main { flex-direction: column; }
    .qa-rail { width: 100%; flex-shrink: 1; max-height: 44vh; border-left: 0; border-top: 1px solid var(--qa-cc-line); }
    .qa-assert-banner { white-space: normal; max-width: 92vw; text-align: center; }
}

/* Dashboard stat tiles: collapse 2-per-row → 1-per-row on small phones (was stuck at 2 below 760). */
@media (max-width: 480px) {
    .qa-stat { flex-basis: 100%; }
}

/* Landing top nav: tighten padding/gap on the smallest phones so Sign in + Get started fit. */
@media (max-width: 400px) {
    /* Long single-word page titles (e.g. "NOTIFICATIONS") are uppercase + letter-spaced and can't wrap;
       shrink them so they fit the smallest phones. */
    .qa-page-title { font-size: 1.45rem !important; letter-spacing: .05em; }
    .qa-lp-top-inner { padding-left: 14px; padding-right: 14px; }
    .qa-lp-nav { gap: 6px; }
    .qa-lp-nav .mud-button-root { padding-left: 10px; padding-right: 10px; }
}

/* Responsive MudTables (Runs / Suite runs / Suite-run children / Test runs / Members): when the
   table stacks into per-row cards below Sm, let long values (email, summary, date) wrap instead of
   being clipped behind overflow:hidden or a fixed cell width. */
@media (max-width: 599.98px) {
    .mud-table-container td[data-label] { white-space: normal !important; overflow-wrap: anywhere; height: auto; }
    /* keep the row label (::before) on one line; only the value wraps */
    .mud-table-container td[data-label]::before { white-space: nowrap; padding-right: 12px; }
}

/* Dialogs: cap height and scroll the content on phones so tall modals (e.g. the 3-option New-test
   chooser) never clip their last option / actions off the bottom of the screen. */
@media (max-width: 599.98px) {
    .mud-dialog { max-height: 92vh; }
    .mud-dialog .mud-dialog-content { overflow-y: auto; }
}

/* Branded error page (plain HTML — no MudBlazor providers needed). */
.qa-error-page { max-width: 540px; margin: 12vh auto 0; padding: 32px 24px; text-align: center;
    font-family: 'Inter', system-ui, sans-serif; }
.qa-error-mark { width: 56px; height: 56px; margin: 0 auto 20px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: 28px;
    color: var(--qa-vermilion); background: rgba(255, 90, 110, .12); border: 1px solid rgba(255, 90, 110, .35); }
.qa-error-page h1 { font-family: var(--qa-mono); text-transform: uppercase; letter-spacing: .12em;
    color: #F3F7FF; font-size: 1.5rem; margin: 0; }
.qa-error-page p { color: var(--qa-cc-text-dim); margin: 16px auto 0; line-height: 1.6; max-width: 46ch; }
.qa-error-ref { font-family: var(--qa-mono); font-size: .72rem; }
.qa-error-btn { display: inline-block; margin-top: 28px; background: var(--qa-signal); color: #06281f;
    font-weight: 600; text-decoration: none; padding: 11px 24px; border-radius: 9px; }
.qa-error-btn:hover { background: #5BF0D3; }

/* Branded full-viewport error scene (404 "radar" / 500 "watch down") — the wardyr.js arcade canvas in a
   cabinet frame above the plain-HTML copy block. Reuses .qa-error-page type/CTA classes above; no MudBlazor. */
.qa-error-scene { min-height: 100dvh; display: flex; flex-direction: column; align-items: center;
    justify-content: center; gap: 26px; padding: 40px 20px; }
.qa-error-scene .qa-error-page { margin: 0 auto; }
.qa-error-arcade { position: relative; width: 100%; max-width: min(320px, 44vh); aspect-ratio: 4 / 5;
    border: 1px solid var(--qa-cc-line); border-radius: 16px; overflow: hidden; background: #05080F; }
.qa-error-arcade canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.qa-error-arcade::after { content: ""; position: absolute; inset: 0; pointer-events: none;
    background: repeating-linear-gradient(0deg, rgba(0,0,0,0) 0 2px, rgba(0,0,0,.16) 2px 4px); }
.qa-error-bezel { position: absolute; inset: 0; pointer-events: none; border-radius: 16px; }
.qa-error-arcade.tone-teal .qa-error-bezel { box-shadow: inset 0 0 80px -10px rgba(56, 232, 198, .28); }
.qa-error-arcade.tone-red .qa-error-bezel { box-shadow: inset 0 0 80px -8px rgba(255, 90, 110, .30); }

/* Mobile bottom quick-bar (triage on the go): Dashboard · Incidents · Runs. The full nav stays in the
   drawer; this is just fast thumb-reach for the pages people actually check on a phone. Shown <600px
   (via .qa-show-narrow), fixed to the bottom with an iOS safe-area inset. */
.qa-bottomnav {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 1100;
    display: flex; background: var(--qa-cc-surface1);
    border-top: 1px solid var(--qa-cc-line);
    padding-bottom: env(safe-area-inset-bottom, 0px);
}
.qa-bottomnav .mud-nav-item { flex: 1; }
.qa-bottomnav .mud-nav-link {
    flex-direction: column; align-items: center; justify-content: center; text-align: center;
    gap: 3px; min-height: 56px; padding: 7px 4px; border-radius: 0;
    font-size: 11px; font-weight: 600; color: var(--qa-cc-text-dim);
}
.qa-bottomnav .mud-nav-link .mud-nav-link-icon { margin: 0 !important; min-width: 0; }
/* center the label under the icon (MudNavLink defaults to a row layout: left margin + stretched, left-aligned text) */
.qa-bottomnav .mud-nav-link .mud-nav-link-text { margin: 0 !important; flex: 0 0 auto; width: auto; text-align: center; }
.qa-bottomnav .mud-nav-link.active {
    color: var(--qa-signal); background: transparent;
    box-shadow: inset 0 2px 0 0 var(--qa-signal);
}
@media (max-width: 599.98px) {
    /* clear the fixed bar so page content (and the last card) isn't hidden behind it */
    .mud-main-content { padding-bottom: 72px; }
    /* lift transient toasts above the bar (MudBlazor snackbars default to the bottom) */
    .mud-snackbar { margin-bottom: 60px; }
}

/* ===================== LANDING v2 + public shell — dark-native (tokens only) =====================
   New marketing sections (wedge / honesty / how / proof / pricing strip / FAQ / footer) and the
   shared PublicTopBar/PublicFooter. Written once for the Night Watch dark surface — deliberately
   NOT part of the legacy light-base + dark-override double layer above. */

/* anchor targets clear the sticky top bar */
.qa-lp section[id] { scroll-margin-top: 76px; }

/* brand cells are links now (top bar + footer + the auth split-screen wordmark) */
a.qa-lp-brand, a.qa-auth-brand-word { text-decoration: none; }
a.qa-lp-brand:hover, a.qa-auth-brand-word:hover { color: var(--qa-signal); }
a.qa-lp-brand:focus-visible, a.qa-auth-brand-word:focus-visible, .qa-auth-mobilebrand:focus-visible,
.qa-lp-footer-cols a:focus-visible, .qa-lp-packnote a:focus-visible {
    outline: 2px solid var(--qa-signal); outline-offset: 3px; border-radius: 4px;
}

/* top-bar anchor nav (desktop wayfinding; the sections stack obviously on mobile) */
.qa-lp-anchors { display: inline-flex; gap: 22px; margin-right: 10px; }
.qa-lp-anchors a { color: var(--qa-cc-text-dim); text-decoration: none; font-size: 14.5px; }
.qa-lp-anchors a:hover { color: var(--qa-cc-text); }
.qa-lp-anchors a:focus-visible { outline: 2px solid var(--qa-signal); outline-offset: 3px; border-radius: 4px; }

/* hero extras */
.qa-lp-ghostlink { align-self: center; color: var(--qa-signal); text-decoration: none; font-size: 15px; padding: 8px 10px; }
.qa-lp-ghostlink:hover { text-decoration: underline; }
.qa-lp-ghostlink:focus-visible { outline: 2px solid var(--qa-signal); outline-offset: 2px; border-radius: 4px; }
.qa-lp-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 22px; }
.qa-lp-chips span {
    font-family: var(--qa-mono); font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase;
    color: var(--qa-cc-text-dim); border: 1px solid var(--qa-cc-line); border-radius: 999px;
    padding: 5px 12px; background: rgba(20, 27, 45, .6);
}
.qa-lp-arcade-cap {
    font-size: 9.5px; letter-spacing: .18em; color: var(--qa-cc-text-dim);
    text-align: center; margin: 10px 0 0; max-width: 440px; margin-left: auto;
}

/* hero verdict pills (#106): the product's status language shown before the first scroll. Reuses the
   .qa-pill trio; the --hero modifier only tightens spacing under the CTA row. Double class beats the
   base .qa-lp-pillrow margin (24px) regardless of source order. */
.qa-lp-pillrow.qa-lp-pillrow--hero { margin-top: 18px; }
.qa-lp-pill-lbl {
    font-family: var(--qa-mono); font-size: 9.5px; letter-spacing: .14em; text-transform: uppercase;
    color: var(--qa-cc-text-dim); align-self: center;
}
.qa-lp-hero-copy p b { color: var(--qa-cc-text); font-weight: 640; }

/* section shells */
.qa-lp-band2 { border-top: 1px solid var(--qa-cc-line); }
.qa-lp-band2--tint { background: var(--qa-cc-surface1); }
.qa-lp-band2--vio { background: radial-gradient(620px 300px at 50% 0, rgba(139, 123, 255, .16), transparent 65%), var(--qa-cc-surface1); }
.qa-lp-sec { max-width: 1120px; margin: 0 auto; padding: 60px 24px 64px; }
/* h1 twin: the anonymous /pricing page's top heading is an h1 (its own document, same visual rank) */
.qa-lp-band2 h1, .qa-lp-band2 h2 {
    font-family: 'Space Grotesk', 'Inter', sans-serif; font-size: 30px; letter-spacing: -.02em;
    color: #F3F7FF; margin: 0 0 10px;
}
.qa-lp-kicker {
    font-family: var(--qa-mono); font-size: 11px; letter-spacing: .22em; text-transform: uppercase;
    font-weight: 700; color: var(--qa-signal); margin: 0 0 12px;
}
.qa-lp-kicker--vio { color: var(--qa-rune); }
.qa-lp-lede { color: var(--qa-cc-text-dim); font-size: 16px; line-height: 1.6; max-width: 66ch; margin: 0 0 28px; }

/* 3-up cards (wedge + honesty) */
.qa-lp-cards3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.qa-lp-card { border: 1px solid var(--qa-cc-line); border-radius: 12px; padding: 20px; background: rgba(11, 15, 26, .55); }
.qa-lp-card h3 { margin: 12px 0 6px; font-size: 17px; color: var(--qa-cc-text); }
.qa-lp-card > h3:first-child { margin-top: 0; }
.qa-lp-card p { margin: 0; color: var(--qa-cc-text-dim); line-height: 1.55; font-size: 14.5px; }
.qa-lp-card p b { color: var(--qa-cc-text); }

/* mono statement strips */
.qa-lp-strip {
    margin: 24px 0 0; border: 1px solid rgba(56, 232, 198, .35); border-radius: 10px;
    background: rgba(56, 232, 198, .06); padding: 14px 18px;
    font-family: var(--qa-mono); font-size: 11.5px; letter-spacing: .1em; text-transform: uppercase;
    color: var(--qa-cc-text); line-height: 1.7;
}
.qa-lp-strip--dash { border-style: dashed; border-color: var(--qa-cc-line); background: transparent; color: var(--qa-cc-text-dim); text-align: center; }

.qa-lp-pillrow { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 24px; }

/* two-path how-it-works */
.qa-lp-paths { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 24px; }
.qa-lp-path { border: 1px solid var(--qa-cc-line); border-radius: 12px; background: rgba(11, 15, 26, .55); padding: 20px; }
.qa-lp-path-t { font-size: 11px; color: var(--qa-signal); margin: 0 0 12px; }
.qa-lp-path-ai {
    color: var(--qa-rune); border: 1px solid rgba(139, 123, 255, .45); border-radius: 4px;
    padding: 1px 6px; margin-left: 6px; font-size: 9.5px;
}
.qa-lp-path ol { margin: 0; padding-left: 20px; color: var(--qa-cc-text-dim); font-size: 14.5px; }
.qa-lp-path li { margin: 9px 0; line-height: 1.5; }
.qa-lp-path li b { color: var(--qa-cc-text); }

/* product-proof vignette (mocked watch-station — sample data, honest statuses) */
.qa-lp-proof { border: 1px solid var(--qa-cc-line); border-radius: 14px; overflow: hidden; background: var(--qa-cc-canvas); }
.qa-lp-proof-verdict {
    display: flex; gap: 18px; align-items: center; padding: 18px 22px;
    border-left: 3px solid var(--qa-vermilion);
    background: linear-gradient(90deg, rgba(255, 90, 110, .09), transparent 55%);
}
.qa-lp-proof-copy { flex: 1; min-width: 0; }
.qa-lp-proof-copy h3 { margin: 0 0 4px; font-size: 17px; color: #F3F7FF; }
.qa-lp-proof-copy p { margin: 0; font-size: 13px; color: var(--qa-cc-text-dim); }
.qa-lp-proof-meta { display: flex; flex-direction: column; gap: 4px; text-align: right; font-size: 9.5px; letter-spacing: .1em; color: var(--qa-cc-text-dim); font-weight: 500; }
.qa-lp-proof-since { color: var(--qa-vermilion); font-weight: 700; }
.qa-lp-proof-row {
    display: grid; grid-template-columns: minmax(110px, .8fr) auto 2fr; gap: 14px; align-items: center;
    padding: 12px 22px; border-top: 1px solid var(--qa-cc-line); font-size: 14px;
}
.qa-lp-proof-name { color: var(--qa-cc-text); font-weight: 600; }
.qa-lp-proof-det { color: var(--qa-cc-text-dim); font-size: 13px; }
.qa-lp-proof-amber { color: var(--qa-amber); font-weight: 600; }
.qa-lp-proof-red { color: var(--qa-vermilion); font-weight: 600; }
.qa-lp-proof-cap {
    margin: 0; padding: 10px 22px; border-top: 1px solid var(--qa-cc-line); background: var(--qa-cc-surface1);
    font-size: 9px; letter-spacing: .16em; color: var(--qa-cc-text-dim); font-weight: 500;
}

/* toolkit strip */
.qa-lp-toolkit { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin-top: 22px; }
.qa-lp-tool {
    display: flex; gap: 10px; align-items: flex-start; border: 1px solid var(--qa-cc-line);
    border-radius: 10px; padding: 12px 14px; background: rgba(11, 15, 26, .55);
}
.qa-lp-tool canvas { flex-shrink: 0; margin-top: 2px; }
.qa-lp-tool b { display: block; font-size: 13.5px; color: var(--qa-cc-text); margin-bottom: 2px; }
.qa-lp-tool span { display: block; font-size: 12px; color: var(--qa-cc-text-dim); line-height: 1.45; }

/* pricing strip */
.qa-lp-tiers { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-top: 24px; }
.qa-lp-tier { border: 1px solid var(--qa-cc-line); border-radius: 12px; background: rgba(11, 15, 26, .55); padding: 20px; }
.qa-lp-tier--hot { border-color: rgba(56, 232, 198, .5); }
.qa-lp-tier-name { font-size: 10px; letter-spacing: .18em; color: var(--qa-cc-text-dim); margin: 0; }
.qa-lp-tier--hot .qa-lp-tier-name { color: var(--qa-signal); }
.qa-lp-tier-price {
    font-family: 'Space Grotesk', 'Inter', sans-serif; font-size: 28px; font-weight: 700;
    color: #F3F7FF; margin: 8px 0 4px;
}
.qa-lp-tier ul { margin: 10px 0 0; padding-left: 17px; color: var(--qa-cc-text-dim); font-size: 13.5px; }
.qa-lp-tier li { margin: 6px 0; }
/* the anonymous /pricing cards carry the full catalog copy (tagline + billing captions) */
.qa-lp-tier-sub { margin: 2px 0 0; color: var(--qa-cc-text-dim); font-size: 12px; }
.qa-lp-tier-tag { margin: 8px 0 14px; color: var(--qa-cc-text-dim); font-size: 13.5px; min-height: 2.6em; }
.qa-lp-tier .mud-button-root { margin-bottom: 4px; }
.qa-lp-tier-trial {
    display: inline-block; margin-top: 12px; font-size: 9px; letter-spacing: .12em;
    color: var(--qa-amber); border: 1px solid rgba(246, 183, 60, .4); border-radius: 4px;
    background: rgba(246, 183, 60, .1); padding: 3px 8px;
}
.qa-lp-packnote { margin: 16px 0 0; color: var(--qa-cc-text-dim); font-size: 14px; }
.qa-lp-packnote a { color: var(--qa-signal); text-decoration: none; }
.qa-lp-packnote a:hover { text-decoration: underline; }

/* FAQ */
.qa-lp-faq { max-width: 760px; }
.qa-lp-faq details { border: 1px solid var(--qa-cc-line); border-radius: 10px; background: rgba(11, 15, 26, .55); margin-bottom: 10px; padding: 0 18px; }
.qa-lp-faq summary { cursor: pointer; font-size: 15px; font-weight: 600; color: var(--qa-cc-text); padding: 14px 0; }
.qa-lp-faq summary:focus-visible { outline: 2px solid var(--qa-signal); outline-offset: 2px; border-radius: 4px; }
.qa-lp-faq details p { margin: 0 0 16px; color: var(--qa-cc-text-dim); font-size: 14px; line-height: 1.55; }

/* footer (destinations only) */
.qa-lp-footer { border-top: 1px solid var(--qa-cc-line); background: var(--qa-cc-void); }
.qa-lp-footer-cols {
    max-width: 1120px; margin: 0 auto; padding: 38px 24px 26px;
    display: grid; grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: 24px;
}
.qa-lp-footer-brand p { margin: 12px 0 0; color: var(--qa-cc-text-dim); font-size: 13.5px; max-width: 32ch; }
.qa-lp-footer-head {
    font-family: var(--qa-mono); font-size: 10px; letter-spacing: .2em; text-transform: uppercase;
    color: var(--qa-cc-text-dim); margin: 0 0 10px;
}
.qa-lp-footer-cols a:not(.qa-lp-brand) { display: block; color: var(--qa-cc-text-dim); text-decoration: none; font-size: 13.5px; margin: 7px 0; }
.qa-lp-footer-cols a:not(.qa-lp-brand):hover { color: var(--qa-signal); }
.qa-lp-footer-bottom {
    max-width: 1120px; margin: 0 auto; padding: 16px 24px 30px;
    border-top: 1px solid var(--qa-cc-line);
    display: flex; justify-content: space-between; gap: 14px; flex-wrap: wrap;
    color: var(--qa-cc-text-dim); font-size: 12.5px;
}
.qa-lp-footer-wink { font-size: 9.5px; letter-spacing: .18em; color: var(--qa-cc-text-dim); font-weight: 500; }

/* auth mobile brand row (shown <800px via the auth media block above) */
.qa-auth-mobilebrand {
    display: none; align-items: center; gap: 9px; align-self: flex-start;
    margin: 0 0 20px; text-decoration: none;
    font-family: var(--qa-mono); font-weight: 600; font-size: 13px;
    letter-spacing: .28em; text-transform: uppercase; color: var(--qa-cc-text);
}
.qa-auth-mobilebrand:hover { color: var(--qa-signal); }
@media (max-width: 800px) {
    /* the auth brand panel hides at this width (rule near the top of the file) — the compact
       row takes over as the page's only brand mark + route home */
    .qa-auth-mobilebrand { display: inline-flex; }
}

/* responsive collapses for the new sections */
@media (max-width: 860px) {
    .qa-lp-anchors { display: none; }
    .qa-lp-cards3, .qa-lp-paths, .qa-lp-tiers { grid-template-columns: 1fr; }
    .qa-lp-toolkit { grid-template-columns: 1fr 1fr; }
    .qa-lp-arcade-cap { margin-right: auto; }
}
@media (max-width: 600px) {
    .qa-lp-sec { padding: 44px 16px 48px; }
    .qa-lp-footer-cols { grid-template-columns: 1fr; gap: 20px; }
    .qa-lp-proof-verdict { flex-wrap: wrap; }
    .qa-lp-proof-meta { text-align: left; }
    .qa-lp-proof-row { grid-template-columns: 1fr auto; }
    .qa-lp-proof-det { grid-column: 1 / -1; }
}
@media (max-width: 480px) {
    .qa-lp-toolkit { grid-template-columns: 1fr; }
    .qa-lp-band2 h1, .qa-lp-band2 h2 { font-size: 25px; }
}

/* ============================================================================
   Legal pages (privacy / terms / etc.) + sign-up consent — Night Watch prose.
   .qa-legal-body styles long-form prose that the marketing .qa-lp-* primitives
   don't cover. Appended last so its (0,1,1) heading rules win the tie vs
   .qa-lp-band2 h2 inside the anonymous marketing shell.
   ============================================================================ */

/* register consent checkbox row */
.qa-field-check {
    display: flex; align-items: flex-start; gap: 10px; margin: 6px 0 2px;
    font-size: 13.5px; line-height: 1.5; color: var(--qa-cc-text-dim);
}
.qa-field-check input[type="checkbox"] {
    margin-top: 2px; width: 16px; height: 16px; flex: 0 0 auto; accent-color: var(--qa-signal);
}
.qa-field-check a { color: var(--qa-signal); text-decoration: none; }
.qa-field-check a:hover { text-decoration: underline; }

/* DRAFT — not in force banner (amber, matches the design-doc disclaimer) */
.qa-legal-draft {
    display: flex; gap: 12px; align-items: flex-start;
    margin: 0 0 30px; padding: 14px 16px; border-radius: 10px; max-width: 74ch;
    border: 1px solid rgba(246, 183, 60, .42);
    background: linear-gradient(180deg, rgba(246, 183, 60, .10), rgba(246, 183, 60, .04));
    color: #f4ecd8; font-size: 14px; line-height: 1.55;
}
.qa-legal-draft strong { color: #ffe8b0; }
.qa-legal-draft-tag {
    flex: 0 0 auto; font-family: var(--qa-mono); font-size: 10px; font-weight: 700;
    letter-spacing: .16em; text-transform: uppercase; color: var(--qa-amber);
    border: 1px solid rgba(246, 183, 60, .5); border-radius: 999px; padding: 4px 9px;
}

/* long-form legal prose */
.qa-legal-body { max-width: 74ch; color: var(--qa-cc-text-dim); font-size: 15px; line-height: 1.7; }
.qa-legal-body > p:first-child { margin-top: 0; }
.qa-legal-body .qa-legal-lead { color: var(--qa-cc-text); font-size: 16px; }
.qa-legal-body h2 {
    font-family: var(--qa-mono); font-size: 13px; letter-spacing: .12em; text-transform: uppercase;
    font-weight: 700; color: var(--qa-cc-text); margin: 38px 0 12px;
    padding-bottom: 8px; border-bottom: 1px solid var(--qa-cc-line);
}
.qa-legal-body h3 { font-size: 16px; color: var(--qa-cc-text); margin: 24px 0 8px; font-weight: 600; }
.qa-legal-body p { margin: 12px 0; }
.qa-legal-body ul, .qa-legal-body ol { margin: 12px 0; padding-left: 22px; }
.qa-legal-body li { margin: 6px 0; }
.qa-legal-body a { color: var(--qa-signal); text-decoration: none; border-bottom: 1px solid rgba(56, 232, 198, .3); }
.qa-legal-body a:hover { border-bottom-color: var(--qa-signal); }
.qa-legal-body strong { color: var(--qa-cc-text); font-weight: 600; }
.qa-legal-body hr { border: none; border-top: 1px solid var(--qa-cc-line); margin: 30px 0; }
.qa-legal-body code {
    font-family: var(--qa-mono); font-size: .86em; color: #bfe9df;
    background: rgba(56, 232, 198, .08); border: 1px solid rgba(56, 232, 198, .16);
    padding: 1px 6px; border-radius: 5px;
}
/* inline [DECISION NEEDED] / [VERIFY] markers — honest blanks a lawyer/founder must fill */
.qa-legal-decision {
    font-family: var(--qa-mono); font-size: 12px; letter-spacing: .02em; color: var(--qa-amber);
    background: rgba(246, 183, 60, .09); border: 1px solid rgba(246, 183, 60, .32);
    padding: 1px 7px; border-radius: 5px;
}
/* tables (e.g. the sub-processor list) scroll rather than overflow the page on mobile */
.qa-legal-body table {
    border-collapse: collapse; width: 100%; margin: 18px 0; font-size: 13.5px;
    display: block; overflow-x: auto; -webkit-overflow-scrolling: touch;
}
.qa-legal-body th {
    text-align: left; font-family: var(--qa-mono); font-size: 10.5px; letter-spacing: .08em;
    text-transform: uppercase; color: var(--qa-cc-text-dim); padding: 10px 12px;
    border-bottom: 1px solid var(--qa-cc-line); background: var(--qa-cc-void); white-space: nowrap;
}
.qa-legal-body td { padding: 10px 12px; border-bottom: 1px solid var(--qa-cc-line); color: var(--qa-cc-text-dim); vertical-align: top; }
.qa-legal-body td strong { color: var(--qa-cc-text); }
