/* WHSIQ Design System - Desktop Surface
 *
 * Target aesthetic: Linear/Notion — clean, high-contrast, information-dense.
 * Colour is NEVER the sole indicator of state (WCAG 2.2 AA).
 * All status indicators pair colour with icon or text label.
 */

:root {
  /* Neutral palette — dark ultra scheme, aligned with admin.css / mobile.css:
     elevated cards (#1e293b) on deep slate (#0f172a). */
  --bg-primary: #1e293b;      /* card / raised surface (admin --bg-card) */
  --bg-secondary: #0f172a;    /* page background (admin --bg) */
  --bg-tertiary: #334155;     /* elevated / hairline fill (admin --bg-elev) */
  --bg-sidebar: #0b1120;      /* deeper than the body so the rail still reads */
  --bg-sidebar-hover: #1e293b;
  --bg-sidebar-active: #334155;

  /* Text — #f8fafc on #1e293b = 14.0:1, #cbd5e1 = 9.9:1, #94a3b8 = 5.7:1 */
  --text-primary: #f8fafc;
  --text-secondary: #cbd5e1;
  --text-tertiary: #94a3b8;
  --text-inverse: #f8fafc;    /* text on the (still-dark) sidebar/toast */
  --text-sidebar: #cbd5e1;

  /* Accent — sky family shared with admin/mobile */
  --accent-primary: #38bdf8;
  --accent-primary-hover: #0ea5e9;
  --accent-success: #22c55e;
  --accent-warning: #facc15;
  --accent-danger: #dc2626;

  /* Borders */
  --border-primary: #334155;  /* admin --border-soft */
  --border-secondary: #475569; /* admin --border */

  /* KPI card states — translucent tints + light text tuned for dark cards */
  --kpi-good-bg: rgba(34, 197, 94, 0.10);
  --kpi-good-border: rgba(34, 197, 94, 0.35);
  --kpi-good-text: #22c55e;   /* 6.4:1 on #1e293b */
  --kpi-warning-bg: rgba(250, 204, 21, 0.10);
  --kpi-warning-border: rgba(250, 204, 21, 0.35);
  --kpi-warning-text: #facc15; /* 9.5:1 on #1e293b */
  --kpi-danger-bg: rgba(220, 38, 38, 0.12);
  --kpi-danger-border: rgba(248, 113, 113, 0.35);
  --kpi-danger-text: #f87171;  /* 5.3:1 on #1e293b (#dc2626 only 3.0:1) */

  /* Spacing */
  --space-xs: 4px;
  --space-sm: 8px;
  --space-md: 16px;
  --space-lg: 24px;
  --space-xl: 32px;

  /* Typography */
  --font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Inter', Roboto, sans-serif;
  --font-mono: 'SF Mono', 'Fira Code', 'Cascadia Code', monospace;

  /* Transitions */
  --transition-fast: 150ms ease;
  --transition-normal: 250ms ease;

  /* ── 2026 ULTRA tokens (additive — nothing above may be removed) ── */
  /* Refined stack: variable Inter if installed locally, else the best
     local system faces. NO external font CDNs — offline field tool. */
  --font-sans-2: "Inter var", "InterVariable", "Inter", -apple-system,
                 BlinkMacSystemFont, "Segoe UI Variable Text", "Segoe UI",
                 system-ui, Roboto, sans-serif;
  /* Channel triplets so washes/glows derive from the existing palette */
  --accent-rgb: 56, 189, 248;          /* --accent-primary  #38bdf8 */
  --success-rgb: 34, 197, 94;          /* --accent-success  #22c55e */
  --warning-rgb: 250, 204, 21;         /* --accent-warning  #facc15 */
  --danger-rgb: 220, 38, 38;           /* --accent-danger   #dc2626 */
  --ink-rgb: 248, 250, 252;            /* --text-primary — dark-theme washes
                                          are now white-alpha sheens */
  /* Tracked table headers: #94a3b8 on --bg-secondary #0f172a = 7.0:1 (AA) */
  --text-th: #94a3b8;
  /* modular type scale (values match the sizes already in use) */
  --fs-xs: 11px;
  --fs-sm: 12px;
  --fs-md: 13px;
  --fs-base: 14px;
  --fs-lg: 16px;
  --fs-xl: 18px;
  --fs-2xl: 28px;
  /* radius scale (values match the radii already in use) */
  --radius-sm: 4px;
  --radius-md: 6px;
  --radius-lg: 8px;
  --radius-xl: 12px;
  --radius-pill: 999px;
  /* layered elevation — deep black shadows tuned for dark surfaces */
  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.35), 0 1px 3px rgba(0, 0, 0, 0.25);
  --shadow-2: 0 8px 24px -8px rgba(0, 0, 0, 0.55);
  --shadow-3: 0 24px 60px -12px rgba(0, 0, 0, 0.7);
  /* motion */
  --ease-out-2: cubic-bezier(0.2, 0.7, 0.2, 1);
  --dur-1: 0.12s;
  --dur-2: 0.2s;
  --dur-3: 0.3s;
  /* gradients — sky ramp carries DARK text (#0f172a), matching the admin
     convention (.a-btn-primary is accent bg + --bg text). Darkest stop
     #0ea5e9 keeps #0f172a text at 6.4:1 (#38bdf8 = 8.3:1, #7dd3fc lighter
     still), so AA holds across the ramp */
  --grad-accent: linear-gradient(120deg, #0ea5e9 0%, #38bdf8 55%, #7dd3fc 110%);
}

/* Reset */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

body {
  font-family: var(--font-sans);
  color: var(--text-primary);
  background: var(--bg-secondary);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* Layout: sidebar + main */
.app-layout {
  display: flex;
  height: 100vh;
  overflow: hidden;
}

/* Sidebar — noun-first IA for desktop (Records, Templates, Settings) */
.sidebar {
  width: 240px;
  min-width: 240px;
  background: var(--bg-sidebar);
  color: var(--text-sidebar);
  display: flex;
  flex-direction: column;
  border-right: 1px solid rgba(255,255,255,0.06);
}

.sidebar-brand {
  padding: var(--space-lg) var(--space-md);
  font-size: 18px;
  font-weight: 700;
  color: var(--text-inverse);
  letter-spacing: -0.02em;
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

.sidebar-brand .brand-icon {
  width: 28px;
  height: 28px;
  background: var(--accent-primary);
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  color: #0f172a; /* dark glyph on sky accent (8.3:1) — admin convention */
}

.sidebar-nav {
  flex: 1;
  padding: var(--space-sm);
  overflow-y: auto;
}

.sidebar-section-label {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-tertiary);
  padding: var(--space-md) var(--space-sm) var(--space-xs);
}

.sidebar-link {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-sm) 12px;
  border-radius: 6px;
  color: var(--text-sidebar);
  text-decoration: none;
  font-size: 14px;
  cursor: pointer;
  transition: background var(--transition-fast);
  border: none;
  background: none;
  width: 100%;
  text-align: left;
}

.sidebar-link:hover { background: var(--bg-sidebar-hover); color: var(--text-inverse); }
.sidebar-link.active { background: var(--bg-sidebar-active); color: var(--text-inverse); }

.sidebar-link .link-icon {
  width: 18px;
  text-align: center;
  font-size: 14px;
  opacity: 0.7;
}

.sidebar-link .link-badge {
  margin-left: auto;
  background: var(--accent-danger);
  color: white;
  font-size: 11px;
  font-weight: 600;
  padding: 1px 6px;
  border-radius: 10px;
  min-width: 20px;
  text-align: center;
}

/* Main content area */
.main-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.page-header {
  padding: var(--space-md) var(--space-lg);
  border-bottom: 1px solid var(--border-primary);
  background: var(--bg-primary);
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 56px;
}

.page-header h1 {
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.page-body {
  flex: 1;
  overflow-y: auto;
  padding: var(--space-lg);
}

/* KPI Bar — 5 KPIs above the fold on 1366x768 */
.kpi-bar {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: var(--space-md);
  margin-bottom: var(--space-lg);
}

.kpi-card {
  background: var(--bg-primary);
  border: 1px solid var(--border-primary);
  border-radius: 8px;
  padding: var(--space-md);
  transition: border-color var(--transition-fast);
}

.kpi-card:hover { border-color: var(--border-secondary); }

.kpi-card .kpi-label {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  display: flex;
  align-items: center;
  gap: var(--space-xs);
}

.kpi-card .kpi-value {
  font-size: 28px;
  font-weight: 700;
  letter-spacing: -0.02em;
  margin-top: var(--space-xs);
}

.kpi-card .kpi-detail {
  font-size: 12px;
  color: var(--text-secondary);
  margin-top: 2px;
}

/* KPI state classes — always paired with icon/text, never colour-only */
.kpi-card.state-good { border-left: 3px solid var(--accent-success); }
.kpi-card.state-good .kpi-value { color: var(--kpi-good-text); }
.kpi-card.state-warning { border-left: 3px solid var(--accent-warning); }
.kpi-card.state-warning .kpi-value { color: var(--kpi-warning-text); }
.kpi-card.state-danger { border-left: 3px solid var(--accent-danger); }
.kpi-card.state-danger .kpi-value { color: var(--kpi-danger-text); }

.kpi-card .kpi-citation {
  font-size: 10px;
  color: var(--text-tertiary);
  margin-top: var(--space-xs);
  line-height: 1.3;
  border-top: 1px dashed var(--border-primary);
  padding-top: 4px;
}

.kpi-card .kpi-note {
  font-size: 11px;
  color: var(--accent-warning);
  margin-top: var(--space-xs);
  line-height: 1.3;
}

.kpi-card:focus {
  outline: 2px solid var(--accent-primary);
  outline-offset: 2px;
}

.kpi-meta-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--space-sm);
  font-size: 12px;
  color: var(--text-secondary);
}

.kpi-meta-actions { display: flex; gap: var(--space-xs); }

/* Print: tight layout that fits a KPI snapshot on one page.
   The screen tokens are DARK-theme (light text); printers strip backgrounds,
   so remap the tokens back to dark-on-light ink here or the printout is
   near-white text on white paper. Print-only — no effect on screen. */
@media print {
  :root {
    --bg-primary: #ffffff;
    --bg-secondary: #ffffff;
    --bg-tertiary: #f0f1f3;
    --text-primary: #111827;
    --text-secondary: #4b5563;
    --text-tertiary: #6b7280;
    --text-th: #4b5563;
    --border-primary: #d1d5db;
    --border-secondary: #9ca3af;
    --kpi-good-text: #065f46;
    --kpi-warning-text: #92400e;
    --kpi-danger-text: #991b1b;
    --accent-warning: #92400e;  /* .kpi-note ink (#facc15 is 1.65:1 on paper) */
    --ink-rgb: 17, 24, 39;      /* washes back to ink-alpha */
    --zebra-wash: rgba(17, 24, 39, 0.04);
  }
  .sidebar, .kpi-meta-actions, .page-header > div:last-child { display: none !important; }
  .main-content { margin-left: 0 !important; }
  .kpi-bar { grid-template-columns: repeat(5, 1fr) !important; page-break-inside: avoid; }
  .kpi-card { border: 1px solid #333 !important; }
  .content-grid { page-break-inside: avoid; }
  body { background: #fff !important; color: #000 !important; }
  /* classes whose light text is hard-coded (tinted bgs don't print) */
  .badge, .type-badge, .activity-icon {
    color: #111827 !important;
    background: none !important;
    border: 1px solid #9ca3af !important;
  }
  .risk-bar .segment { color: #111827 !important; }
  .field-error, .chain-invalid { color: #991b1b !important; }
  .chain-valid { color: #065f46 !important; }
  .form-draft-banner, .demo-banner { color: #7a5b00 !important; }
  /* chart axis/label text is hard-coded light in the SVG markup;
     CSS fill outranks presentation attributes */
  .card svg text { fill: #374151 !important; }
}

/* Content grid */
.content-grid {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: var(--space-lg);
}

/* Cards */
.card {
  background: var(--bg-primary);
  border: 1px solid var(--border-primary);
  border-radius: 8px;
  overflow: hidden;
}

.card-header {
  padding: var(--space-md);
  border-bottom: 1px solid var(--border-primary);
  font-size: 14px;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.card-body { padding: var(--space-md); }

/* Activity feed */
.activity-item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-sm);
  padding: var(--space-sm) 0;
  border-bottom: 1px solid var(--bg-tertiary);
  font-size: 13px;
}

.activity-item:last-child { border-bottom: none; }

.activity-icon {
  width: 28px;
  height: 28px;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  flex-shrink: 0;
}

/* dark tints: translucent colour washes over the card, light glyphs
   (every glyph ≥4.5:1 against its tinted background over #1e293b) */
.activity-icon.type-take5 { background: rgba(56, 189, 248, 0.14); color: #7dd3fc; }
.activity-icon.type-incident { background: rgba(220, 38, 38, 0.16); color: #f87171; }
.activity-icon.type-near_miss { background: rgba(250, 204, 21, 0.12); color: #facc15; }
.activity-icon.type-hazard { background: rgba(245, 158, 11, 0.14); color: #fbbf24; }
.activity-icon.type-swms { background: rgba(34, 197, 94, 0.14); color: #4ade80; }

.activity-meta {
  font-size: 12px;
  color: var(--text-tertiary);
}

/* Records table */
.records-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

.records-table th {
  text-align: left;
  padding: var(--space-sm) var(--space-md);
  font-weight: 600;
  color: var(--text-secondary);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  border-bottom: 2px solid var(--border-primary);
  background: var(--bg-secondary);
}

.records-table td {
  padding: var(--space-sm) var(--space-md);
  border-bottom: 1px solid var(--bg-tertiary);
}

.records-table tr:hover { background: var(--bg-secondary); }

/* Status badges — colour + text label (never colour-only) */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 500;
}

.badge-submitted { background: rgba(56, 189, 248, 0.14); color: #7dd3fc; }
.badge-submitted::before { content: "\25CF "; }
.badge-reviewed { background: rgba(34, 197, 94, 0.14); color: #4ade80; }
.badge-reviewed::before { content: "\2713 "; }
.badge-closed { background: var(--bg-tertiary); color: var(--text-secondary); }
.badge-closed::before { content: "\2014 "; }
.badge-open { background: rgba(56, 189, 248, 0.14); color: #7dd3fc; }
.badge-open::before { content: "\25CB "; }
.badge-overdue { background: rgba(220, 38, 38, 0.18); color: #f87171; }
.badge-overdue::before { content: "\26A0 "; }
.badge-in_progress { background: rgba(250, 204, 21, 0.12); color: #facc15; }
.badge-in_progress::before { content: "\25B6 "; }

/* Type badges */
.type-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 500;
}

.type-badge-take5 { background: rgba(56, 189, 248, 0.14); color: #7dd3fc; }
.type-badge-incident { background: rgba(220, 38, 38, 0.16); color: #f87171; }
.type-badge-near_miss { background: rgba(250, 204, 21, 0.12); color: #facc15; }
.type-badge-hazard { background: rgba(245, 158, 11, 0.14); color: #fbbf24; }
.type-badge-swms { background: rgba(34, 197, 94, 0.14); color: #4ade80; }

/* Risk distribution chart (CSS-only bar chart) */
.risk-bar {
  display: flex;
  height: 24px;
  border-radius: 4px;
  overflow: hidden;
  margin-bottom: var(--space-sm);
}

.risk-bar .segment {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 600;
  color: white;
  transition: width var(--transition-normal);
}

/* dark counts on the light green/yellow segments (7.8:1 / 11.7:1);
   the deep red segment keeps white (4.8:1) */
.risk-bar .segment-low { background: var(--accent-success); color: #0f172a; }
.risk-bar .segment-medium { background: var(--accent-warning); color: #0f172a; }
.risk-bar .segment-high { background: var(--accent-danger); }

.risk-legend {
  display: flex;
  gap: var(--space-md);
  font-size: 12px;
  color: var(--text-secondary);
}

.risk-legend-item {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
}

.risk-legend-dot {
  width: 8px;
  height: 8px;
  border-radius: 2px;
}

/* Buttons */
.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding: 6px 12px;
  border-radius: 6px;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  border: 1px solid transparent;
  transition: all var(--transition-fast);
  text-decoration: none;
}

.btn-primary {
  background: var(--accent-primary);
  color: #0f172a; /* dark label on sky (8.3:1) — matches .a-btn-primary */
  border-color: var(--accent-primary);
}

.btn-primary:hover { background: var(--accent-primary-hover); }

.btn-secondary {
  background: var(--bg-primary);
  color: var(--text-primary);
  border-color: var(--border-secondary);
}

.btn-secondary:hover { background: var(--bg-secondary); }

.btn-sm { padding: 4px 8px; font-size: 12px; }

/* Filter bar */
.filter-bar {
  display: flex;
  gap: var(--space-sm);
  margin-bottom: var(--space-md);
  align-items: center;
}

.filter-bar select,
.filter-bar input {
  padding: 6px 10px;
  border: 1px solid var(--border-secondary);
  border-radius: 6px;
  font-size: 13px;
  background: var(--bg-primary);
  color: var(--text-primary);
}

.filter-bar-rich { flex-wrap: wrap; }
.filter-bar .filter-count {
  margin-left: auto;
  font-size: 12px;
  color: var(--text-secondary);
}

.record-row:focus {
  outline: 2px solid var(--accent-primary);
  outline-offset: -2px;
}

.record-detail-toolbar {
  display: flex;
  gap: var(--space-sm);
  align-items: center;
  margin-bottom: var(--space-md);
  flex-wrap: wrap;
}

/* Take 5 Form — mobile-first design adapted for desktop */
.form-container {
  max-width: 640px;
  margin: 0 auto;
}

.form-group {
  margin-bottom: var(--space-lg);
}

.form-label {
  display: block;
  font-size: 14px;
  font-weight: 500;
  margin-bottom: var(--space-xs);
  color: var(--text-primary);
}

.form-hint {
  font-size: 12px;
  color: var(--text-secondary);
  margin-bottom: var(--space-xs);
}

.form-input,
.form-select,
.form-textarea {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--border-secondary);
  border-radius: 6px;
  font-size: 14px;
  transition: border-color var(--transition-fast);
  font-family: var(--font-sans);
  /* explicit dark field chrome — previously inherited the UA's light
     defaults; fields recess into the card like the admin console */
  background: var(--bg-secondary);
  color: var(--text-primary);
}

.form-input:focus,
.form-select:focus,
.form-textarea:focus {
  outline: none;
  border-color: var(--accent-primary);
  box-shadow: 0 0 0 3px rgba(56, 189, 248, 0.18);
}

.form-textarea { min-height: 80px; resize: vertical; }

/* Checkbox/toggle for boolean fields */
.form-check {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-sm) 0;
  min-height: 48px; /* WCAG 2.2 AA touch target */
  cursor: pointer;
}

.form-check input[type="checkbox"] {
  width: 20px;
  height: 20px;
  accent-color: var(--accent-primary);
}

/* Hazard pills */
.hazard-pills {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
}

.hazard-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding: 6px 12px;
  border: 1px solid var(--border-secondary);
  border-radius: 20px;
  font-size: 13px;
  cursor: pointer;
  transition: all var(--transition-fast);
  background: var(--bg-primary);
  min-height: 36px;
}

.hazard-pill:hover { border-color: var(--accent-primary); }
.hazard-pill.selected { background: var(--accent-primary); color: #0f172a; border-color: var(--accent-primary); }

.hazard-pill .risk-select {
  padding: 2px 4px;
  border: 1px solid rgba(15, 23, 42, 0.35);
  border-radius: 4px;
  font-size: 11px;
  background: rgba(255, 255, 255, 0.25); /* lightens the sky pill further —
                                            inherited dark text stays ≥8:1 */
  color: inherit;
}

/* Slice 7.2 — tier-one form chrome */
.legal-ref {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-tertiary);
  background: var(--bg-secondary);
  border-left: 2px solid var(--accent-primary);
  padding: 2px 8px;
  margin-top: var(--space-xs);
  border-radius: 2px;
  letter-spacing: 0.02em;
}

/* Plain-English tooltip on legal_ref chips. Native title on hover for
 * desktop, long-press for touch. Visually a small (?) badge so users
 * notice it's clickable and not just typography. */
.legal-ref-tip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  min-width: 16px;
  padding: 0;
  border: 1px solid var(--accent-primary);
  border-radius: 50%;
  background: transparent;
  color: var(--accent-primary);
  font-family: var(--font-sans, inherit);
  font-size: 10px;
  font-weight: 600;
  line-height: 1;
  cursor: help;
  transition: background 120ms ease, color 120ms ease;
}
.legal-ref-tip:hover,
.legal-ref-tip:focus {
  background: var(--accent-primary);
  color: var(--bg-primary, #fff);
  outline: none;
}

.field-error {
  color: #f87171; /* --accent-danger #dc2626 is only 3.0:1 on dark cards */
  font-size: 12px;
  margin-top: 4px;
  line-height: 1.4;
}

.input-error,
.form-input.input-error,
.form-select.input-error {
  border-color: var(--accent-danger) !important;
  box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.25);
}

.form-draft-banner {
  background: rgba(250, 204, 21, 0.08);
  border: 1px solid rgba(250, 204, 21, 0.35);
  color: #fde047;
  padding: var(--space-sm) var(--space-md);
  border-radius: 6px;
  margin-bottom: var(--space-md);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  font-size: 13px;
}

.signature-pad {
  width: 100%;
  max-width: 100%;
  height: 150px;
  border: 1px dashed var(--border-secondary);
  border-radius: 6px;
  /* INTENTIONALLY LIGHT: the pad draws #111 ink (app.js initSignaturePad)
     and exports a transparent PNG that lands on white PDF paper — the ink
     colour must stay dark, so the on-screen pad stays a light "paper"
     island (dark ink 17.2:1 against it). Canvas CSS background is not
     captured by toDataURL, so submitted signatures are byte-identical. */
  background: #f8fafc;
  touch-action: none;
  cursor: crosshair;
  display: block;
}

/* Success animation */
.submit-success {
  text-align: center;
  padding: var(--space-xl);
}

.submit-success .checkmark {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: var(--accent-success);
  color: #0f172a; /* dark tick on #22c55e (7.8:1); white was 2.3:1 */
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 32px;
  margin: 0 auto var(--space-md);
  animation: checkmark-pop 0.3s ease;
}

@keyframes checkmark-pop {
  0% { transform: scale(0); }
  50% { transform: scale(1.2); }
  100% { transform: scale(1); }
}

/* Toast notifications */
.toast-container {
  position: fixed;
  bottom: var(--space-lg);
  right: var(--space-lg);
  z-index: 1000;
}

.toast {
  background: var(--bg-sidebar);
  color: var(--text-inverse);
  padding: var(--space-sm) var(--space-md);
  border-radius: 6px;
  font-size: 13px;
  margin-top: var(--space-sm);
  animation: toast-in 0.3s ease;
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

@keyframes toast-in {
  from { transform: translateY(20px); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}

/* Loading skeleton */
.skeleton {
  background: linear-gradient(90deg, var(--bg-tertiary) 25%, var(--bg-secondary) 50%, var(--bg-tertiary) 75%);
  background-size: 200% 100%;
  animation: skeleton-shimmer 1.5s infinite;
  border-radius: 4px;
}

@keyframes skeleton-shimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* Responsive — dashboard still works at 1366x768 */
@media (max-width: 1366px) {
  .kpi-bar { gap: var(--space-sm); }
  .kpi-card .kpi-value { font-size: 24px; }
  .sidebar { width: 200px; min-width: 200px; }
}

/* Chain verification panel */
.chain-panel {
  padding: var(--space-md);
  background: var(--bg-secondary);
  border-radius: 6px;
  margin-top: var(--space-md);
}

.chain-valid {
  color: var(--accent-success);
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: var(--space-xs);
}

.chain-invalid {
  color: #f87171; /* --accent-danger #dc2626 is only 3.7:1 on #0f172a */
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: var(--space-xs);
}

.chain-version {
  padding: var(--space-sm);
  border-left: 2px solid var(--border-secondary);
  margin: var(--space-sm) 0 var(--space-sm) var(--space-md);
  font-size: 12px;
  font-family: var(--font-mono);
}

.chain-version .hash { color: var(--text-tertiary); word-break: break-all; }

/* Loading screen (inline critical path) */
.loading-screen {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
  background: var(--bg-secondary);
  font-family: var(--font-sans);
  color: var(--text-secondary);
}

.loading-center { text-align: center; }
.loading-skeleton { width: 200px; height: 24px; margin: 0 auto 12px; }
.loading-label { font-size: 14px; }

/* ═══════════════════════════════════════════════════════════════════════
   2026 ULTRA layer — visual elevation only.
   Refines earlier rules via equal-or-higher specificity + cascade order.
   NOTHING above is deleted; no selector here changes behaviour, data or
   endpoints. Every animation/transition touched by this layer is disabled
   inside the prefers-reduced-motion guard at the bottom of the layer.
   The scheme is now DARK-ALIGNED: deep slate body (#0f172a), elevated
   cards (#1e293b), sky accent — the same palette as the admin console and
   mobile PWA. This layer brings the admin console's "ultra" language
   (elevation, gradient edges, tracked headers, tabular numerals,
   micro-interactions) to that shared dark scheme.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── layer tokens (additive to the ULTRA token block in :root above) ────── */

:root {
  color-scheme: dark;
  /* sky accent ON the sidebar: 8.8:1 vs #0b1120 and 5.0:1 vs the #334155
     active fill (≥3:1 non-text AA) */
  --accent-on-dark: #38bdf8;
  /* zebra: white-alpha sheen on #1e293b — body text #f8fafc stays ≥14:1 */
  --zebra-wash: rgba(255, 255, 255, 0.03);
  /* hover: sky tint on the dark card — text contrast unchanged (≥13:1) */
  --hover-wash: rgba(var(--accent-rgb), 0.08);
  --focus-ring: 0 0 0 3px rgba(var(--accent-rgb), 0.25);
}

/* ── base: selection, refined stack ─────────────────────────────────────── */

::selection { background: rgba(var(--accent-rgb), 0.3); color: var(--text-primary); }
.sidebar ::selection { background: rgba(var(--accent-rgb), 0.35); color: var(--text-inverse); }

html, body {
  font-family: var(--font-sans-2);
  text-rendering: optimizeLegibility;
}

/* ── slim themed scrollbars ─────────────────────────────────────────────── */

html,
.page-body {
  scrollbar-width: thin;
  scrollbar-color: var(--border-secondary) transparent;
}
.sidebar-nav {
  scrollbar-width: thin;
  scrollbar-color: var(--bg-sidebar-active) transparent;
}
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--border-secondary);
  border-radius: var(--radius-pill);
  border: 2px solid var(--bg-secondary);
}
::-webkit-scrollbar-thumb:hover { background: var(--text-tertiary); }
.sidebar-nav::-webkit-scrollbar-thumb {
  background: var(--bg-sidebar-active);
  border-color: var(--bg-sidebar);
}

/* ── universal focus ring (keyboard only) ───────────────────────────────── */
/* Low specificity: the existing .kpi-card:focus / .record-row:focus rules
   above out-specify this, so those elements keep their tuned rings. */

:focus-visible {
  outline: 2px solid var(--accent-primary);
  outline-offset: 2px;
}
/* sky reads on the deep sidebar too (8.8:1 vs #0b1120) — kept for the
   day the accents ever diverge again */
.sidebar :focus-visible { outline-color: var(--accent-on-dark); }

/* ── typography refinement ──────────────────────────────────────────────── */

.page-header h1 { letter-spacing: -0.02em; }
.card-header { letter-spacing: -0.01em; }
.sidebar-section-label { letter-spacing: 0.08em; }

/* tabular numerals wherever numbers stack or align vertically */
.kpi-card .kpi-value,
.kpi-meta-bar,
.records-table td,
.sidebar-link .link-badge,
.filter-bar .filter-count,
.chain-version { font-variant-numeric: tabular-nums; }

/* ── page header: whisper of accent, like the admin header ──────────────── */

.page-header {
  background:
    linear-gradient(180deg, rgba(var(--accent-rgb), 0.03), rgba(var(--accent-rgb), 0) 70%),
    var(--bg-primary);
}

/* ── sidebar: brand glow, accent rail on active, soft hover ─────────────── */

.sidebar {
  background:
    linear-gradient(180deg, rgba(var(--accent-rgb), 0.14), rgba(var(--accent-rgb), 0) 190px),
    var(--bg-sidebar);
}

.sidebar-brand .brand-icon {
  background: var(--grad-accent);
  box-shadow:
    0 0 16px rgba(var(--accent-rgb), 0.45),
    inset 0 1px 0 rgba(255, 255, 255, 0.25);
}

.sidebar-link {
  position: relative;
  transition: background var(--dur-2) var(--ease-out-2), color var(--dur-2) var(--ease-out-2);
}
.sidebar-link::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 3px;
  height: 60%;
  border-radius: var(--radius-pill);
  background: var(--accent-on-dark);
  box-shadow: 0 0 8px rgba(var(--accent-rgb), 0.6);
  transform: translateY(-50%) scaleY(0);
  transform-origin: center;
  transition: transform var(--dur-2) var(--ease-out-2);
  pointer-events: none;
}
.sidebar-link.active::before { transform: translateY(-50%) scaleY(1); }
.sidebar-link.active {
  background:
    linear-gradient(90deg, rgba(var(--accent-rgb), 0.28), rgba(var(--accent-rgb), 0.08) 75%),
    var(--bg-sidebar-active);
  color: #ffffff;
}
.sidebar-link .link-icon { transition: opacity var(--dur-2) var(--ease-out-2); }
.sidebar-link:hover .link-icon,
.sidebar-link.active .link-icon { opacity: 1; }
.sidebar-link .link-badge { box-shadow: 0 0 10px rgba(var(--danger-rgb), 0.45); }

/* ── KPI cards: gradient top edge, elevation, lift on hover ─────────────── */

.kpi-card {
  position: relative;
  overflow: hidden;
  box-shadow: var(--shadow-1);
  transition:
    transform var(--dur-1) var(--ease-out-2),
    box-shadow var(--dur-2) var(--ease-out-2),
    border-color var(--dur-2) var(--ease-out-2);
}
.kpi-card::after {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: linear-gradient(90deg, transparent 4%, rgba(var(--accent-rgb), 0.35), transparent 96%);
  pointer-events: none;
}
.kpi-card.state-good::after    { background: linear-gradient(90deg, transparent 4%, rgba(var(--success-rgb), 0.5),  transparent 96%); }
.kpi-card.state-warning::after { background: linear-gradient(90deg, transparent 4%, rgba(var(--warning-rgb), 0.55), transparent 96%); }
.kpi-card.state-danger::after  { background: linear-gradient(90deg, transparent 4%, rgba(var(--danger-rgb), 0.55),  transparent 96%); }
.kpi-card:hover {
  transform: translateY(-2px);
  border-color: var(--border-secondary);
  box-shadow: var(--shadow-2);
}

/* ── cards ──────────────────────────────────────────────────────────────── */

.card { box-shadow: var(--shadow-1); }
.card-header {
  background: linear-gradient(180deg, rgba(var(--ink-rgb), 0.015), rgba(var(--ink-rgb), 0) 70%);
}

.activity-icon { box-shadow: inset 0 0 0 1px rgba(var(--ink-rgb), 0.05); }

/* ── tables: tracked sticky header, zebra, accent hover wash ────────────── */

.records-table th {
  color: var(--text-th);                       /* 7.0:1 on #0f172a (AA) */
  letter-spacing: 0.06em;
  background:
    linear-gradient(180deg, rgba(var(--ink-rgb), 0.02), rgba(var(--ink-rgb), 0) 60%),
    var(--bg-secondary);
  position: sticky;
  top: 0;
  z-index: 1;
}
.records-table td { transition: background var(--dur-2) var(--ease-out-2); }
.records-table tbody tr:nth-child(even) td { background: var(--zebra-wash); }
.records-table tbody tr:hover td { background: var(--hover-wash); }

/* ── buttons: gradient primary, depth, press states ─────────────────────── */

.btn {
  transition:
    background var(--dur-2) var(--ease-out-2),
    border-color var(--dur-2) var(--ease-out-2),
    color var(--dur-2) var(--ease-out-2),
    box-shadow var(--dur-2) var(--ease-out-2),
    transform var(--dur-1) var(--ease-out-2);
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0) scale(0.98); }

/* --grad-accent stops hold the dark #0f172a label at 6.4:1+ (see token
   comment above) */
.btn-primary {
  background: var(--grad-accent);
  background-size: 160% 100%;
  background-position: 0% 50%;
  border-color: transparent;
  box-shadow:
    0 2px 10px -2px rgba(var(--accent-rgb), 0.4),
    inset 0 1px 0 rgba(255, 255, 255, 0.22);
}
.btn-primary:hover {
  background: var(--grad-accent);
  background-size: 160% 100%;
  background-position: 100% 50%;
  box-shadow:
    0 4px 14px -2px rgba(var(--accent-rgb), 0.5),
    inset 0 1px 0 rgba(255, 255, 255, 0.22);
}

.btn-secondary { box-shadow: var(--shadow-1); }
.btn-secondary:hover { border-color: var(--text-tertiary); }

/* ── badges: hairline border derived from the badge's own text colour ───── */

.badge,
.type-badge {
  border: 1px solid rgba(var(--ink-rgb), 0.06);                 /* fallback */
  border-color: color-mix(in srgb, currentColor 25%, transparent);
  letter-spacing: 0.01em;
}

/* ── filter bar + form fields: tokenised focus glow ─────────────────────── */

.filter-bar select,
.filter-bar input {
  transition: border-color var(--dur-2) var(--ease-out-2), box-shadow var(--dur-2) var(--ease-out-2);
}
.filter-bar select:hover,
.filter-bar input:hover { border-color: var(--text-tertiary); }
.filter-bar select:focus,
.filter-bar input:focus {
  outline: none;
  border-color: var(--accent-primary);
  box-shadow: var(--focus-ring);
}

.form-input,
.form-select,
.form-textarea {
  transition: border-color var(--dur-2) var(--ease-out-2), box-shadow var(--dur-2) var(--ease-out-2);
}

/* ── hazard pills: lift + gradient selected state ───────────────────────── */

.hazard-pill {
  transition:
    background var(--dur-2) var(--ease-out-2),
    border-color var(--dur-2) var(--ease-out-2),
    color var(--dur-2) var(--ease-out-2),
    box-shadow var(--dur-2) var(--ease-out-2),
    transform var(--dur-1) var(--ease-out-2);
}
.hazard-pill:hover { transform: translateY(-1px); box-shadow: var(--shadow-1); }
.hazard-pill.selected {
  background: var(--grad-accent);
  box-shadow: 0 2px 8px -2px rgba(var(--accent-rgb), 0.45);
}

/* ── misc surfaces ──────────────────────────────────────────────────────── */

.risk-bar { border-radius: var(--radius-md); }
.skeleton { border-radius: var(--radius-md); }
.chain-panel { border: 1px solid var(--border-primary); }
.form-draft-banner { box-shadow: var(--shadow-1); }

/* ── toasts: real elevation + hairline ──────────────────────────────────── */

.toast {
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: var(--radius-lg);
  /* shadow stays BLACK (not --ink-rgb, which is now a light wash triplet) */
  box-shadow: var(--shadow-2), 0 12px 32px rgba(0, 0, 0, 0.5);
}

/* ── boot screen: gradient brand mark (index.html .loading-brand) ───────── */

.loading-brand {
  width: 44px;
  height: 44px;
  margin: 0 auto var(--space-md);
  border-radius: var(--radius-xl);
  background: var(--grad-accent);
  color: #0f172a; /* dark bolt on the sky gradient (6.4:1 at darkest stop) */
  font-size: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 8px 24px -6px rgba(var(--accent-rgb), 0.5);
  animation: boot-pulse 1.8s var(--ease-out-2) infinite;
}

@keyframes boot-pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.06); }
}

/* ── print: elevation is meaningless on paper ───────────────────────────── */

@media print {
  .kpi-card, .card, .btn, .toast, .form-draft-banner { box-shadow: none !important; }
  .kpi-card::after { display: none !important; }
}

/* ── reduced-motion: every animation/transition this layer touches ──────── */
/* Also retro-guards the pre-existing animations (toast-in, checkmark-pop,
   skeleton shimmer, risk-bar width tween) that had no guard before. */

@media (prefers-reduced-motion: reduce) {
  .toast,
  .submit-success .checkmark,
  .loading-brand { animation: none; }
  .skeleton { animation: none; background: var(--bg-tertiary); }
  .sidebar-link,
  .sidebar-link::before,
  .sidebar-link .link-icon,
  .kpi-card,
  .btn,
  .hazard-pill,
  .records-table td,
  .filter-bar select, .filter-bar input,
  .form-input, .form-select, .form-textarea,
  .risk-bar .segment,
  .legal-ref-tip { transition: none; }
  .kpi-card:hover,
  .btn:hover, .btn:active,
  .hazard-pill:hover { transform: none; }
}

/* sr-only — required by chartkit's embedded accessible data tables;
   without it the raw <table> renders visibly inside every sparkline. */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* ═══════════════════════════════════════════════════════════════════════
   R3 GLASS layer — glass depth + cross-document view transitions.
   Append-only: nothing above is modified, renamed or removed. Solid
   fallbacks are the original rules above, which stay in force OUTSIDE
   the @supports blocks, so browsers without backdrop-filter render
   exactly as before. Every piece of motion added here sits inside a
   prefers-reduced-motion guard (no-preference opt-in).
   NOTE: the SPA has no CSS-owned modal backdrops (toasts are surfaces,
   not backdrops), so there is no R3 backdrop-blur block in this file.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── R3.1 Glass page header ─────────────────────────────────────────────
   Translucent --bg-primary at 78% + blur/saturate, keeping the ULTRA
   accent whisper. Computed contrast against the WORST underlying
   content (mid-tone #334155 surface beneath the glass): effective
   backdrop ≈ #232e41 →
     #f8fafc h1 / primary text  13.0:1
     #cbd5e1 secondary text      9.2:1
   — all ≥ 4.5:1 (WCAG 2.2 AA). */
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .page-header {
    background:
      linear-gradient(180deg, rgba(var(--accent-rgb), 0.03), rgba(var(--accent-rgb), 0) 70%),
      rgba(30, 41, 59, 0.78);
    -webkit-backdrop-filter: blur(14px) saturate(1.3);
    backdrop-filter: blur(14px) saturate(1.3);
    border-bottom-color: rgba(148, 163, 184, 0.2);    /* hairline glass edge */
  }
}

/* glass is meaningless on paper — restore the print remap's solid header */
@media print {
  .page-header {
    background: var(--bg-primary) !important;
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
  }
}

/* ── R3.2 View transitions — MPA page hops (dashboard ⇄ admin ⇄ mobile).
   Progressive enhancement: the opt-in lives inside BOTH the @supports
   probe AND the no-preference motion guard, so reduced-motion users
   never opt in at all — navigation stays an instant swap for them and
   for every browser without the View Transitions API. */
@supports (view-transition-name: root) {
  @media (prefers-reduced-motion: no-preference) {
    @view-transition { navigation: auto; }
    ::view-transition-old(root),
    ::view-transition-new(root) {
      animation-duration: 160ms;      /* default cross-fade, tightened */
      animation-timing-function: ease;
    }
  }
}

/* ── R3.3 Scroll polish ─────────────────────────────────────────────────
   Highlighted/focused record rows land clear of the sticky table <th>
   inside the .page-body scroll container. */
.records-table tbody tr { scroll-margin-top: 44px; }
/* nested scroll containers must not chain-scroll each other */
.page-body,
.sidebar-nav { overscroll-behavior: contain; }

/* ── Unified SVG icon system (js/icons.js) — additive layer ──────────────
   Stroke icons inherit currentColor from their container, so existing
   colour tokens (KPI states, severity bands, chip text) apply unchanged.
   No animation/transition introduced here. */
.whs-icon {
  display: inline-block;
  vertical-align: -0.15em;   /* optical baseline alignment beside text */
  flex-shrink: 0;
}
/* Centre icons inside existing flex glyph wells without new classes. */
.activity-icon .whs-icon,
.m-tile-icon .whs-icon,
.m-quick-icon .whs-icon { vertical-align: middle; }
