/* AUTO-GENERATED by scripts/export_tokens_css.py from design_tokens/css.py.
 * Do not edit this generated token stylesheet directly.
 * -----------------------------------------------------------------------
 * tokens.css — design tokens (:root), base resets.
 */
:root {
    color-scheme: light;
    /* Light surfaces: warm cream and near-white cards. */
    --bg-page: #F7F4EF;
    --bg-card: #FFFEFC;
    /* Primary navigation — navy with high contrast labels. */
    --bg-sidebar: #0D2742;
    --bg-sidebar-hover: rgba(76,102,130,0.16);
    --bg-sidebar-active: rgba(76,102,130,0.30);
    --sidebar-text: #FFFEFC;
    --sidebar-text-muted: rgba(247,244,239,0.72);
    --sidebar-icon: #F7F4EF;
    --sidebar-border: rgba(247,244,239,0.22);
    --bg-topbar: rgba(255,254,252,0.92);
    --bg-page-header: #F7F4EF;
    /* Brand identity — navy. --brand-blue remains a semantic alias. */
    --brand-blue: #0D2742;
    --brand-blue-bright: #4C6682;
    --brand-slate: #4C6682;
    --brand-terracotta: #B96549;
    --brand-peach: #F2B49F;
    --brand-cream: #F7F4EF;
    --terracotta-rgb: 185,101,73;
    --navy-rgb: 13,39,66;
    --card-rgb: 255,254,252;
    --overlay-scrim: rgba(13,39,66,0.38);
    /* Information and AI cues share slate; navy remains the action color. */
    --brand-info: #4C6682;
    --brand-info-bright: #4C6682;
    /* Muted status colors; use high-contrast labels beside status cues. */
    --brand-amber: #8A7046;
    --brand-amber-bright: #8A7046;
    --brand-amber-text: #0D2742;
    --brand-green: #557565;
    --brand-red: #98645E;
    --border-subtle: rgba(76,102,130,0.18);
    /* Text — navy primary with slate support copy. */
    --text-primary: #0D2742;
    --text-secondary: #4C6682;
    --text-muted: #4C6682;
    --text-on-dark: #FFFEFC;
    --text-on-dark-muted: rgba(247,244,239,0.72);
    --border: #E6DED5;
    --border-cool: #E6DED5;
    --border-strong: rgba(76,102,130,0.38);
    /* Alpha tints derive from shared slate and status colors. */
    --tint-blue: rgba(76,102,130,0.10);   /* cool brand tint */
    --tint-info: rgba(76,102,130,0.10);   /* restrained slate information tint */
    --tint-amber: rgba(138,112,70,0.10);
    --tint-green: rgba(85,117,101,0.10);
    --tint-red: rgba(152,100,94,0.10);
    --tint-slate: rgba(76,102,130,0.08);
    /* Quiet navy shadows. */
    --shadow-sm: 0 1px 2px rgba(13,39,66,0.04);
    --shadow-md: 0 2px 6px rgba(13,39,66,0.05), 0 1px 2px rgba(13,39,66,0.04);
    --shadow-lg: 0 12px 32px -12px rgba(13,39,66,0.12), 0 2px 6px rgba(13,39,66,0.04);
    --shadow-xl: 0 20px 60px rgba(13,39,66,0.16);
    --radius-sm: 6px;
    --radius-md: 8px;
    --radius-lg: 10px;
    --radius-xl: 12px;
    --radius-card: 12px;
    /* Dual-ring focus (Osperan identity) — inner ring matches card bg, outer ring
       uses the terracotta focus cue, visible against either light surface. */
    --focus-ring: 0 0 0 2px var(--bg-card), 0 0 0 4px rgba(185,101,73,0.82);
    /* Instrument Serif display, Manrope work typography, Space Grotesk mono. */
    --font-display: 'Instrument Serif', Georgia, serif;
    --font-body:    'Manrope', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
    --font-mono:    'Space Grotesk', ui-monospace, 'Cascadia Mono', monospace;
    /* Typography scale */
    --text-xs:   0.72rem;
    --text-sm:   0.82rem;
    --text-base: 0.95rem;
    --text-md:   1.05rem;
    --text-lg:   1.25rem;
    --text-xl:   clamp(1.25rem, 1.5vw, 1.75rem);
    --text-2xl:  clamp(1.75rem, 2vw,   2.5rem);
    --text-hero: clamp(2.5rem,  3.5vw, 4rem);
    /* Extended radius tokens */
    --radius-xs:   4px;
    --radius-pill: 999px;
    /* Spacing tokens */
    --card-padding-sm: 12px 16px;
    --card-padding-md: 16px 20px;
    --card-padding-lg: 20px 24px;
    /* Plan 72: numeric spacing scale (4px base) so views stop free-typing
       '10px 16px' / 'gap:12px' / 'margin-top:10px'. */
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 20px;
    --space-6: 24px;
    --space-7: 32px;
    --space-8: 40px;
    /* Plan 72: canonical workspace width (was hardcoded max-w-[1600px] in
       layout.page_root). */
    --page-max-width: 1600px;
    /* Plan 72: table-density tokens — row vertical padding + cell horizontal
       padding for data tables. */
    --table-row-py: 10px;
    --table-cell-px: 16px;
    /* Font weight tokens */
    --font-weight-display: 400;
    /* Motion tokens — durations + easings used by global
       transitions, .lift/.press utilities, and page/component keyframes. */
    --motion-fast: 120ms;
    --motion-base: 180ms;
    --motion-slow: 280ms;
    --ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);
    /* AI surfaces use slate; primary actions use navy. */
    --brand-ai:       #4C6682;
    --brand-ai-hover: #0D2742;
    --brand-ai-light: #F2B49F; /* gradient end-stop for .forge-btn--ai; change in lockstep */
    --brand-ai-tint:  rgba(76,102,130,0.12);
    --brand-ai-glow:  rgba(76,102,130,0.45); /* pulse ring + focus affordance for AI controls */
    /* Legacy color aliases retained for current CSS callers. */
    --tint-violet:    rgba(76,102,130,0.12);
    --brand-violet:   #4C6682;
    /* Extended navy palette for hover/active states. */
    --brand-blue-dark:   #0D2742;
    /* Surface utility tokens — used in components that need layered bg levels */
    --bg-soft:     rgba(76,102,130,0.08);             /* subtle inset / pill backgrounds */
    --bg-elevated: var(--bg-card);      /* floated elements above bg-card */
    --bg-subtle:   var(--bg-page);      /* section dividers, even lighter */
    --bg-hover:    rgba(76,102,130,0.08);             /* hover state tint on warm cream */
    --border-default: var(--border-cool); /* alias for border-cool */
    /* Warm white card surface role. */
    --color-white: #FFFEFC;
    /* High-contrast ink for danger-state text. */
    --brand-red-dark: #0D2742;
    /* Navy text on status backgrounds preserves contrast. */
    --brand-green-dark: #0D2742;
    /* Warm peach accent alias. */
    --brand-orange: #F2B49F;
    /* KPI tile tinted borders — paired with matching --tint- backgrounds */
    --kpi-border-amber: rgba(138,112,70,0.38);
    --kpi-border-red: rgba(152,100,94,0.38);
    --kpi-border-green: rgba(85,117,101,0.38);
    /* Warm accent for selected navigation and high-priority actions. */
    --sidebar-icon-accent: #B96549;
    /* Login page body text. */
    --login-text: #4C6682;
    /* Obligation tab accent colors — one per PillState kind.
       Each tab sets --oblig-accent:var(--oblig-{kind}) inline;
       CSS rules reference var(--oblig-accent) for the ring, status text, and hover. */
    --oblig-red:   var(--brand-red);
    --oblig-amber: var(--brand-amber);
    --oblig-blue:  var(--brand-blue);
    --oblig-green: var(--brand-green);
    --oblig-slate: var(--text-muted);
    /* Product page (4-stage layout) — semantic accents + tinted surfaces.
       Aliased to existing tokens where possible. */
    --brand-purple:     var(--brand-ai);
    --border-amber:     rgba(138,112,70,0.38);
    --border-green:     rgba(85,117,101,0.38);
    --bg-muted:         var(--tint-slate);
    --bg-panel:         var(--bg-card);
    --text-amber:       var(--brand-amber-text);
    --tint-amber-hover: rgba(242,180,159,0.30);
    /* Compatibility aliases for migrated CSS consumers. Values still originate
       in design_tokens so active CSS never carries fallback literals. */
    --accent-red: var(--brand-red);
    --accent: var(--brand-blue);
    --accent-blue: var(--brand-blue);
    --accent-brand: var(--brand-blue);
    --accent-ai: var(--brand-ai);
    --accent-attention: var(--sidebar-icon-accent);
    --bad-soft: var(--tint-red);
    --bad-text: var(--brand-red-dark);
    --bg: var(--bg-card);
    --bg-surface: var(--bg-soft);
    --bg-danger-subtle: var(--tint-red);
    --bg-info-subtle: var(--tint-info);
    --bg-success-subtle: var(--tint-green);
    --bg-warning-subtle: var(--tint-amber);
    --border-accent: var(--border-strong);
    --border-blue: var(--brand-blue-bright);
    --border-danger: rgba(152,100,94,0.42);
    --border-light: var(--border);
    --border-muted: var(--border-strong);
    --border-purple: rgba(76,102,130,0.24);
    --border-ui: var(--border-strong);
    --border-control-active: var(--border-strong);
    --button-primary-bg: #0D2742;
    --button-primary-bg-hover: #4C6682;
    --button-primary-bg-active: #0D2742;
    --button-primary-border: var(--button-primary-bg);
    --button-primary-text: #F7F4EF;
    --button-ai-bg: #4C6682;
    --button-ai-bg-hover: #0D2742;
    --button-ai-border: var(--button-ai-bg);
    --button-ai-text: #F7F4EF;
    --button-ai-glow: var(--brand-ai-glow);
    --button-secondary-bg: transparent;
    --button-secondary-bg-hover: #0D2742;
    --button-secondary-border: var(--border);
    --button-secondary-text: var(--text-secondary);
    --button-secondary-text-hover: var(--color-white);
    --button-danger-bg: transparent;
    --button-danger-bg-hover: var(--tint-red);
    --button-danger-border: var(--brand-red);
    --button-danger-text: #0D2742;
    --brand-amber-dark: #0D2742;
    --brand-brown: #B96549;
    --brand-danger: var(--brand-red);
    --brand-primary: var(--brand-blue);
    --brand-secondary: var(--text-secondary);
    --brand-success: var(--brand-green);
    --color-info-border: var(--brand-info-bright);
    --color-info-surface: var(--tint-info);
    --color-success: var(--brand-green);
    --color-warning-border: var(--brand-amber-bright);
    --color-warning-surface: var(--tint-amber);
    --forge-noticed-accent: var(--brand-blue);
    --lane-color: var(--brand-blue);
    --ok-soft: var(--tint-green);
    --ok-text: var(--brand-green-dark);
    --slate-500: var(--text-muted);
    --status-amber-bg: var(--tint-amber);
    --status-amber-text: var(--brand-amber-dark);
    --status-green-bg: var(--tint-green);
    --status-green-text: #0D2742;
    --status-red-bg: var(--tint-red);
    --status-red-text: #0D2742;
    --status-success: var(--brand-green);
    --status-warning: var(--brand-amber);
    --status-danger: var(--brand-red);
    --surface-accent: var(--tint-info);
    --surface-alt: var(--bg-soft);
    --surface-amber: var(--tint-amber-hover);
    --surface-control-active: var(--bg-card);
    --surface-control-hover: var(--bg-hover);
    --surface-control-selected: var(--tint-info);
    --surface-elevated: var(--bg-elevated);
    --surface-hover: var(--bg-hover);
    --surface-muted: var(--bg-muted);
    --surface-primary: var(--bg-card);
    --surface-raised: var(--bg-elevated);
    --surface-secondary: var(--bg-soft);
    --success: var(--brand-green);
    --text-body: var(--text-primary);
    --text-danger: var(--brand-red-dark);
    --text-on-brand: var(--color-white);
    --tint-danger: var(--tint-red);
    --tint-amber-fg: var(--brand-amber-text);
    --tint-green-fg: var(--brand-green-dark);
    --tint-primary: var(--tint-info);
    --tint-purple: var(--tint-violet);
    --tint-red-fg: var(--brand-red-dark);
    --tint-secondary: var(--tint-slate);
    --tint-success: var(--tint-green);
    --warning: var(--brand-amber);
    --danger: var(--brand-red);
    --warn-soft: var(--tint-amber);
    --warn-text: var(--brand-amber-dark);
}

/* Work typography uses Manrope; display headings use Instrument Serif. */
html, body, .q-page, .q-layout, input, button, textarea, select {
    font-family: "Manrope", system-ui, -apple-system, BlinkMacSystemFont,
                 "Segoe UI", Helvetica, Arial, sans-serif;
}
body { color: var(--text-primary); background: var(--bg-page-header); font-family: var(--font-body); }

/* NiceGUI/Quasar page chrome — zero padding/margin so .forge-shell +
   .forge-sidebar reach the viewport edges (top, LHS, RHS). Without this,
   Quasar's .q-page-container + NiceGUI's .nicegui-content wrapper leave
   a cream/white halo around the deep-violet sidebar, which makes the rail
   read as a floating card instead of an anchored navigation wall.
   `.nicegui-content` also defaults to align-items: start, which would
   collapse .forge-shell to content-width once it becomes a flex child
   without padding — same family of fix as the .nicegui-column override
   in components.css. Source-order specificity (this file loads after
   quasar.css and nicegui.css) is enough — no !important needed.
   min-height: 100vh on .q-page keeps short pages from exposing the body
   background below .forge-shell. */
.q-page-container,
.q-page,
.nicegui-content {
    padding: 0;
    margin: 0;
}
.q-page {
    min-height: 100vh;
}
.nicegui-content {
    align-items: stretch;
    gap: 0;
}

/* Display headings use the bundled Instrument Serif face. */
h1, h2, h3, h4 {
    font-family: var(--font-display);
    letter-spacing: -0.015em;
    font-weight: 400;
}
h1 { letter-spacing: -0.02em; }

/* ---- Display typeface ----
 * Applied to large metric numbers and page titles only.
 * Body copy, labels, and UI chrome stay in Manrope (var(--font-body)).
 */
.kpi-value,
.metric-mini .mm-value,
.forge-page-title h1,
.forge-page-title,
.render-page-header h1 {
    font-family: var(--font-display);
}

/* Tabular numerals — scoped to data elements only, not body copy */
.tabular, table td, .kpi-value, .kpi-delta,
.metric-mini .mm-value,
.cert-card .cert-count-item .num {
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum";
}

/* Accessible focus ring — suppress browser ring for pointer users only;
 * keyboard / switch users keep full focus visibility via :focus-visible. */
:focus:not(:focus-visible) { outline: none; }
button:focus-visible, a:focus-visible, select:focus-visible,
input:focus-visible, textarea:focus-visible, [role="button"]:focus-visible,
[tabindex]:focus-visible {
    box-shadow: var(--focus-ring);
    outline: none;
    border-radius: var(--radius-sm);
}

/* Global base interaction transitions — every interactive
   element shares the same colour/border transition rhythm so hovers and
   focus state changes feel consistent across the product. */
button, a, [role="button"], [role="tab"], [role="menuitem"] {
    transition:
        background-color var(--motion-base) var(--ease-out-quart),
        color            var(--motion-base) var(--ease-out-quart),
        border-color     var(--motion-base) var(--ease-out-quart);
}

/* Plan 798 — WCAG 2.1 SC 2.3.3 / 2.3.1: respect OS reduced-motion preference.
 * Suppresses page-fade, skeleton pulse, card hover transforms, and progress-bar
 * fill transitions. Component-scoped blocks (forge-btn--ai, forge-triage-pulse)
 * have their own counterparts and are not duplicated here.
 *
 * Osperan identity (Jun 2026): also disables the new .lift/.press/.row-hover/
 * .story-link transforms and underline animation, plus the page-in keyframe
 * (now a short fade). The base interaction
 * transitions remain (background/color/border) since those are non-motion. */
@media (prefers-reduced-motion: reduce) {
    .forge-page {
        animation: none !important;
    }
    .skeleton {
        animation: none !important;
        background: var(--tint-slate);
    }
    .card {
        transition: none !important;
    }
    .card:hover {
        transform: none !important;
    }
    .card:active {
        transform: none !important;
    }
    .progress-bar .fill {
        transition: none !important;
    }
    /* New utility classes (Phase 1) */
    .lift:hover, .lift:active,
    .glow-hover:hover, .glow-hover:active,
    .press:active {
        transform: none !important;
    }
    .row-hover {
        transition: none !important;
    }
    .story-link::after {
        transition: none !important;
    }
}
