/* ============================================================================
   CMEye — design system + components
   Two themes via [data-theme="dark"] | [data-theme="light"] on <html>.
   Dark is the default; light is selectable from the sidebar footer.
   ============================================================================ */

@font-face {
  font-family: "Sloan CMEye Fixed";
  src: url("assets/Sloan-CMEye-Fixed.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* ───── Theme tokens ───── */
:root {
  --radius-sm: 8px;
  --radius:    12px;
  --radius-lg: 16px;
  --shadow-1: 0 1px 2px rgba(0,0,0,.25);
  --shadow-2: 0 8px 24px rgba(0,0,0,.18);
  --shadow-3: 0 16px 48px rgba(0,0,0,.35);
  --sidebar-w: 244px;
  --sidebar-w-collapsed: 64px;
  --topbar-h: 56px;
  --gap: 16px;
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
  /* Brand accents (constant across themes) — iVista green, NOT highlighter. */
  --brand:      #0e7a2b;        /* iVista green */
  --brand-2:    #0a5d20;        /* darker hover shade */
  --brand-soft: #1a9d3d;        /* slightly lighter for dark-bg contrast */
  --gold:       #f2b01e;        /* iVista gold */
  --gold-dark:  #c98e08;        /* darker hover shade for gold */
  --cyan:       #22d3ee;
  --magenta:    #e879f9;
  --info:       #38bdf8;
  --danger:     #ef4444;
  --warn:       #f59e0b;
  --ok:         #15803d;
  /* Sidebar tokens — defined per-theme below (dark navy in dark mode,
     lighter royal-blue in light mode, à la Aurora Bank). */
}

[data-theme="dark"]{
  --shell-bg:     #050811;   /* outer tray (darker than canvas) */
  --bg:           #0a0f1f;   /* main canvas */
  --bg-grad:      radial-gradient(1200px 600px at 80% -100px, rgba(34,211,238,.08), transparent 60%),
                   radial-gradient(900px 400px at -100px 100%, rgba(232,121,249,.05), transparent 60%);
  --surface:      #131a2e;
  --surface-2:    #1a2240;
  --surface-3:    #232b4e;
  --border:       #232b4e;
  --border-soft:  #1c2440;
  --text:         #e6edf6;
  --text-muted:   #8c97b0;
  --text-faint:   #5a6680;
  --accent:       var(--brand-soft);   /* slightly brighter on dark bg for legibility */
  --accent-soft:  rgba(26,157,61,.16);
  --accent-ring:  rgba(26,157,61,.30);
  --pill-bg:      #1a2240;
  --pill-text:    #c5d2ea;
  --input-bg:     #0e1530;
  --input-border: #2a3357;
  --table-head-bg: #1a2240;
  --chip-bg:      #232b4e;
  /* Sidebar — dark navy */
  --sb-bg:          #0e1530;
  --sb-surface-2:   #1a2240;
  --sb-surface-3:   #232b4e;
  --sb-border:      #1c2440;
  --sb-text:        #e6edf6;
  --sb-text-muted:  #8c97b0;
  --sb-text-faint:  #5a6680;
  --sb-accent-soft: rgba(26,157,61,.16);
  --sb-accent-ring: rgba(26,157,61,.30);
}

[data-theme="light"]{
  --shell-bg:     #dbe5f4;   /* light blue-gray outer tray */
  --bg:           #ffffff;   /* main canvas — clean white */
  --bg-grad:      radial-gradient(1200px 600px at 80% -100px, rgba(14,122,43,.04), transparent 60%);
  --surface:      #ffffff;
  --surface-2:    #f1f5f9;
  --surface-3:    #e2e8f0;
  --border:       #e2e8f0;
  --border-soft:  #eef2f7;
  --text:         #0f172a;
  --text-muted:   #64748b;
  --text-faint:   #94a3b8;
  --accent:       var(--brand-2);
  --accent-soft:  rgba(14,122,43,.10);
  --accent-ring:  rgba(14,122,43,.22);
  --pill-bg:      #f1f5f9;
  --pill-text:    #1e293b;
  --input-bg:     #ffffff;
  --input-border: #cbd5e1;
  --table-head-bg: #f8fafc;
  --chip-bg:      #e2e8f0;
  /* Sidebar — Aurora Bank-style royal blue (lighter than dark theme) */
  --sb-bg:          #1e40af;
  --sb-surface-2:   #1e3a8a;
  --sb-surface-3:   #2451c4;
  --sb-border:      rgba(255,255,255,.14);
  --sb-text:        #ffffff;
  --sb-text-muted:  #c7d2fe;
  --sb-text-faint:  #93c5fd;
  --sb-accent-soft: rgba(255,255,255,.16);
  --sb-accent-ring: rgba(255,255,255,.32);
}

/* ───── Reset ───── */
*, *::before, *::after { box-sizing: border-box; }
/* `[hidden]` must beat .shell/.auth-screen's `display: grid|flex`. */
[hidden] { display: none !important; }
html, body { height: 100%; }
body {
  margin: 0;
  /* Outer tray bg — slightly different from --bg so the sidebar + main panel
     appear as "floating" rounded cards over a darker (or lighter blue) base.
     Aurora Bank vibes. */
  background: var(--shell-bg);
  color: var(--text);
  font: 15px/1.5 var(--font);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
body::before {
  content:""; position: fixed; inset: 0; pointer-events:none; z-index:0;
  background: var(--bg-grad);
}
button { font: inherit; color: inherit; cursor: pointer; }
input, select, textarea { font: inherit; color: inherit; }
h1, h2, h3, h4 { margin: 0 0 8px; font-weight: 600; letter-spacing: -0.01em; }
h1 { font-size: 24px; }
h2 { font-size: 20px; }
h3 { font-size: 16px; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
.muted { color: var(--text-muted); }
.fail  { color: var(--danger); }
.warn  { color: var(--warn); }
.success, .ok { color: var(--ok); }

/* ═══════════════════════════════════════════════════════════════
   APP SHELL — sidebar + main (both rounded, floating over --shell-bg)
   ═══════════════════════════════════════════════════════════════ */
.shell {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: var(--sidebar-w) 1fr;
  gap: 14px;
  padding: 14px;
  min-height: 100vh;
}
.shell[data-collapsed="true"] { grid-template-columns: var(--sidebar-w-collapsed) 1fr; }

/* ───── Sidebar (rounded floating panel) ───── */
.sidebar {
  background: var(--sb-bg);
  color: var(--sb-text);
  display: flex;
  flex-direction: column;
  position: sticky; top: 14px;
  height: calc(100vh - 28px);
  border-radius: 18px;
  box-shadow: 0 8px 24px rgba(0,0,0,.16);
  /* No overflow:hidden — the collapsed-mode collapse button hangs off the
     right edge (right: -14px) as a pull-tab and was getting clipped. */
  z-index: 30;
}
.sidebar-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 14px 12px;
  border-bottom: 1px solid var(--sb-border);
  position: relative;
}
.sidebar-brand .brand-logo { height: 48px; width: auto; flex-shrink: 0; }
.brand-text {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  line-height: 1.05;
  min-width: 0;
  transform: translateY(1px);
}
.brand-name {
  font-family: "Sloan CMEye Fixed", var(--font);
  font-weight: 400;
  font-size: 16px;
  line-height: 0.92;
  letter-spacing: 0;
  color: var(--gold);
  white-space: nowrap;
}
.brand-tag  {
  font-size: 11px;
  color: var(--sb-text-muted);
  white-space: nowrap;
  margin-top: 5px;
  text-align: center;
}
.sidebar-collapse {
  margin-left: auto;
  width: 28px; height: 28px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--sb-surface-2); color: var(--sb-text-muted);
  border: 1px solid var(--sb-border); border-radius: 8px;
  flex-shrink: 0;
  transition: background .15s, color .15s;
}
.sidebar-collapse:hover { background: var(--sb-surface-3); color: var(--sb-text); }
.shell[data-collapsed="true"] .sidebar-collapse svg { transform: scaleX(-1); }

.sidebar-nav {
  flex: 1;
  overflow-y: auto;
  padding: 12px 8px;
  display: flex; flex-direction: column; gap: 2px;
}
.nav-section-label {
  font-size: 11px; text-transform: uppercase; letter-spacing: .1em;
  color: var(--sb-text-faint); padding: 14px 12px 6px;
}
.nav-section-label:first-child { padding-top: 4px; }
.nav-item {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 10px;
  color: var(--sb-text-muted);
  text-align: left;
  width: 100%;
  font-size: 14px;
  font-weight: 500;
  transition: background .15s, color .15s, border-color .15s;
}
.nav-item:hover { background: var(--sb-surface-2); color: var(--sb-text); }
.nav-item.active {
  background: var(--sb-accent-soft);
  color: var(--sb-text);
  border-color: var(--sb-accent-ring);
  box-shadow: inset 3px 0 0 0 var(--accent);
}
.nav-item svg { flex-shrink: 0; opacity: .9; }
.nav-item.active svg { color: var(--accent); opacity: 1; }
/* Light theme: sidebar is royal blue, so the dark-green accent gets lost.
   Make the active stripe + icon white for contrast on the blue. */
[data-theme="light"] .nav-item.active {
  background: rgba(255,255,255,.18);
  color: #ffffff;
  border-color: rgba(255,255,255,.30);
  box-shadow: inset 3px 0 0 0 #ffffff;
}
[data-theme="light"] .nav-item.active svg { color: #ffffff; }
[data-theme="light"] .nav-item:hover { color: #ffffff; }

/* Collapsed sidebar — icons only. The pull-tab collapse button sits OUTSIDE
   the right edge (right: -14px) as a half-circle handle; no overflow:hidden
   on .sidebar so it stays visible. */
.shell[data-collapsed="true"] .nav-label,
.shell[data-collapsed="true"] .brand-text,
.shell[data-collapsed="true"] .theme-label,
.shell[data-collapsed="true"] .nav-section-label,
.shell[data-collapsed="true"] .user-meta { display: none; }
.shell[data-collapsed="true"] .sidebar-brand { justify-content: center; padding: 14px 8px; }
.shell[data-collapsed="true"] .sidebar-collapse {
  position: absolute; right: -14px; top: 22px;
  width: 28px; height: 28px;
  background: var(--sb-bg);
  border: 1px solid var(--sb-border);
  border-radius: 50%;
  z-index: 31;
  box-shadow: 2px 0 4px rgba(0,0,0,.3);
}
.shell[data-collapsed="true"] .nav-item { justify-content: center; padding: 10px; }
.shell[data-collapsed="true"] .user-chip { padding: 6px; justify-content: center; gap: 0; }
/* In the 64px-wide collapsed rail, avatar + logout icon side-by-side overflow.
   Hide the logout button — user can expand to sign out. */
.shell[data-collapsed="true"] .user-chip .btn-icon { display: none; }
.shell[data-collapsed="true"] .theme-toggle { justify-content: center; padding: 8px; }

.sidebar-footer {
  border-top: 1px solid var(--sb-border);
  padding: 10px 8px;
  display: flex; flex-direction: column; gap: 8px;
}
.theme-toggle {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 12px;
  background: transparent;
  border: 1px solid var(--sb-border);
  border-radius: 10px;
  color: var(--sb-text-muted);
  font-size: 13px;
  transition: background .15s, color .15s;
}
.theme-toggle:hover { background: var(--sb-surface-2); color: var(--sb-text); }
[data-theme="dark"]  .theme-toggle .icon-sun  { display: none; }
[data-theme="light"] .theme-toggle .icon-moon { display: none; }

.user-chip {
  display: flex; align-items: center; gap: 10px;
  padding: 10px;
  background: var(--sb-surface-2);
  border-radius: 12px;
  border: 1px solid var(--sb-border);
}
.user-avatar {
  width: 32px; height: 32px; border-radius: 50%;
  background: linear-gradient(135deg, var(--brand), var(--cyan));
  color: #001405; font-weight: 700; font-size: 13px;
  display: inline-flex; align-items: center; justify-content: center;
  text-transform: uppercase;
  flex-shrink: 0;
  overflow: hidden;
}
/* When an organization logo is uploaded it replaces the initial — show the
   logo on white in a rounded pill that widens to fit a wide wordmark. */
.user-avatar.has-logo {
  width: auto; min-width: 32px; max-width: 108px;
  border-radius: 8px; background: #fff; padding: 3px;
}
.user-avatar.has-logo img {
  height: 100%; width: auto; max-width: 100%;
  object-fit: contain; display: block;
}
.user-meta { flex: 1; min-width: 0; line-height: 1.2; }
.user-name { font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--sb-text); }
.user-role { font-size: 11px; color: var(--sb-text-muted); }
.btn-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text-muted);
  transition: background .15s, color .15s, border-color .15s;
}
.btn-icon:hover { background: var(--surface-3); color: var(--text); border-color: var(--accent-ring); }
/* Inside the always-dark sidebar, btn-icon (logout) should match the rail. */
.user-chip .btn-icon { border-color: var(--sb-border); color: var(--sb-text-muted); }
.user-chip .btn-icon:hover { background: var(--sb-surface-3); color: var(--sb-text); border-color: var(--sb-accent-ring); }

/* ───── Main canvas (rounded floating panel) ───── */
.main {
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--bg);
  border-radius: 18px;
  box-shadow: 0 8px 24px rgba(0,0,0,.10);
  min-height: calc(100vh - 28px);
  overflow: hidden;   /* clip topbar at the rounded top corners */
}
.topbar {
  height: var(--topbar-h);
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: 10px;
  padding: 0 24px;
  /* No `position: sticky` — main is overflow:hidden for the rounded clip,
     so sticky would freeze at top of main anyway. Header scrolls naturally. */
  z-index: 20;
  flex-shrink: 0;
}

/* Back button as a yellow back-pointing chevron in the topbar (left side).
   Mirror-image of the .step chevrons. */
.btn-back-chevron {
  --chev: 12px;
  display: inline-flex; align-items: center;
  gap: 6px;
  padding: 6px 14px 6px calc(14px + var(--chev));
  background: var(--gold);
  color: #1a1100;
  font-size: 12px;
  font-weight: 700;
  border: 0;
  cursor: pointer;
  /* Left-pointing chevron: left edge tapers to a point, right edge flat. */
  clip-path: polygon(
    0 50%,
    var(--chev) 0,
    100% 0,
    100% 100%,
    var(--chev) 100%
  );
  transition: background .15s;
  flex-shrink: 0;
}
.btn-back-chevron:hover { background: var(--gold-dark); }
.btn-back-chevron svg { width: 14px; height: 14px; }
.topbar-spacer { flex: 1; }
#btn-menu { display: none; }     /* shown only on mobile */
.crumbs {
  display: flex; align-items: center; gap: 6px;
  font-size: 14px;
  color: var(--text-muted);
  flex: 1; min-width: 0;
  overflow: hidden;
}
.crumbs .crumb-sep { color: var(--text-faint); }
.crumbs .crumb-current { color: var(--text); font-weight: 600; }
.crumbs button { background: none; border: 0; color: inherit; padding: 0; cursor: pointer; }
.crumbs button:hover { color: var(--text); }
/* When the crumbs host is given a chevron stepper instead, drop crumb spacing.
   The stepper supplies its own spacing via clip-path margins. */
.crumbs.topbar-stepper { gap: 0; }
.crumbs.topbar-stepper .stepper { margin: 0; }
.crumbs.topbar-stepper .step { font-size: 12px; padding-top: 6px; padding-bottom: 6px; }
.crumbs.topbar-stepper .step .step-num { width: 18px; height: 18px; font-size: 11px; }

.page {
  flex: 1;
  padding: 24px;
  max-width: 1400px;
  width: 100%;
  margin: 0 auto;
}

/* ═══════════════════════════════════════════════════════════════
   COMMON COMPONENTS
   ═══════════════════════════════════════════════════════════════ */

/* Page header bar (title + subtitle on left, actions on right) */
.page-header {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 16px; margin-bottom: 22px; flex-wrap: wrap;
}
.page-header .ph-left { flex: 1; min-width: 0; }
.page-header .ph-sub { color: var(--text-muted); font-size: 14px; margin-top: 2px; }
.page-header .ph-actions { display: flex; gap: 8px; flex-wrap: wrap; }

/* Card */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 20px;
  margin-bottom: 16px;
  box-shadow: var(--shadow-1);
}
.card h2, .card h3 { margin-top: 0; }
.card-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-bottom: 14px;
}
.card-head h3 { margin: 0; }
.card-head .card-actions { display: flex; gap: 8px; }

/* Grids */
.grid { display: grid; gap: 16px; }
/* Grid cards fill their cell so the shorter of two side-by-side cards (e.g.
   Practice vs Barriers with different item counts) stretches to the row height
   and its WHITE background covers the whole cell. Without this, in print the
   shorter card ends at its content height and the gray page background shows in
   the rest of the cell (`break-inside: avoid` suppresses the default stretch). */
.grid > .chart-card { height: 100%; }
.grid-6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.grid-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 1200px) {
  .grid-6, .grid-5 { grid-template-columns: repeat(3, minmax(0,1fr)); }
}
@media (max-width: 1024px) {
  .grid-6, .grid-5 { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .grid-4 { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .grid-3 { grid-template-columns: repeat(2, minmax(0,1fr)); }
}
@media (max-width: 640px) {
  .grid-6, .grid-5, .grid-4, .grid-3, .grid-2 { grid-template-columns: 1fr; }
}

/* KPI tile */
.kpi {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 18px 20px;
  position: relative;
  overflow: hidden;
}
.kpi::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events:none;
  background: linear-gradient(135deg, transparent 50%, var(--accent-soft) 100%);
  opacity: .6;
}
.kpi > * { position: relative; z-index: 1; }
.kpi .kpi-label { color: var(--text-muted); font-size: 12px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; }
.kpi .kpi-value { font-size: 30px; font-weight: 700; letter-spacing: -0.02em; margin-top: 6px; line-height: 1.1; }
.kpi .kpi-meta { color: var(--text-muted); font-size: 12px; margin-top: 6px; }
.kpi .kpi-icon {
  position: absolute; top: 14px; right: 14px;
  width: 34px; height: 34px; border-radius: 10px;
  background: var(--accent-soft); color: var(--accent);
  display: inline-flex; align-items: center; justify-content: center;
}
.kpi.cyan    .kpi-icon { background: rgba(34,211,238,.16); color: var(--cyan); }
.kpi.cyan::after { background: linear-gradient(135deg, transparent 50%, rgba(34,211,238,.16) 100%); }
.kpi.gold    .kpi-icon { background: rgba(242,176,30,.16); color: var(--gold); }
.kpi.gold::after { background: linear-gradient(135deg, transparent 50%, rgba(242,176,30,.16) 100%); }
.kpi.magenta .kpi-icon { background: rgba(232,121,249,.16); color: var(--magenta); }
.kpi.magenta::after { background: linear-gradient(135deg, transparent 50%, rgba(232,121,249,.16) 100%); }

/* Buttons */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 8px;
  padding: 10px 16px;
  border-radius: 10px;
  border: 1px solid transparent;
  background: var(--surface-2);
  color: var(--text);
  font-size: 14px;
  font-weight: 500;
  transition: background .15s, border-color .15s, transform .05s;
  text-decoration: none;
}
.btn:hover { background: var(--surface-3); }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn-primary {
  background: var(--brand);
  color: #ffffff;
  border-color: transparent;
}
.btn-primary:hover { background: var(--brand-2); }
[data-theme="light"] .btn-primary { color: white; background: var(--brand); }
[data-theme="light"] .btn-primary:hover { background: var(--brand-2); }
.btn-ghost { background: transparent; border-color: var(--border); color: var(--text); }
.btn-ghost:hover { background: var(--surface-2); }
.btn-danger { background: var(--danger); color: white; }
.btn-danger:hover { background: #dc2626; }
.btn-icon-danger {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; padding: 0;
  background: transparent;
  color: var(--text-muted);
  border: 1px solid var(--border);
  border-radius: 8px;
  cursor: pointer;
  transition: background .15s, color .15s, border-color .15s;
  font: inherit;
}
.btn-icon-danger:hover { background: rgba(239,68,68,.12); color: var(--danger); border-color: var(--danger); }
.btn-sm { padding: 6px 12px; font-size: 13px; }
.btn-block { width: 100%; }

/* Pill / chip */
.pill {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 10px;
  background: var(--pill-bg);
  color: var(--pill-text);
  border-radius: 999px;
  font-size: 12px; font-weight: 600;
}
.pill.ok    { background: rgba(14,122,43,.18); color: #6ee7a8; }
.pill.warn  { background: rgba(245,158,11,.18); color: #fcd34d; }
.pill.fail  { background: rgba(239,68,68,.18); color: #fca5a5; }
.pill.info  { background: rgba(56,189,248,.18); color: #7dd3fc; }
[data-theme="light"] .pill.ok    { background: #dcfce7; color: #15803d; }
[data-theme="light"] .pill.warn  { background: #fef3c7; color: #92400e; }
[data-theme="light"] .pill.fail  { background: #fee2e2; color: #991b1b; }
[data-theme="light"] .pill.info  { background: #dbeafe; color: #1e40af; }

/* Inputs */
.field { display: flex; flex-direction: column; gap: 6px; }
.label { color: var(--text-muted); font-size: 12px; font-weight: 600; letter-spacing: .02em; }
.input, .select, .textarea {
  width: 100%;
  padding: 10px 12px;
  background: var(--input-bg);
  color: var(--text);
  border: 1px solid var(--input-border);
  border-radius: 10px;
  transition: border-color .15s, box-shadow .15s;
}
.input:focus, .select:focus, .textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-ring);
}
.input.input-sm { padding: 6px 8px; font-size: 13px; }
/* Click-to-edit affordance for the Meetings list meeting-date cell. */
.date-edit-display,
.name-edit-display {
  display: inline-block;
  padding: 2px 6px;
  border-radius: 6px;
  cursor: pointer;
  border: 1px dashed transparent;
  transition: background .12s, border-color .12s;
}
.date-edit-display:hover,
.name-edit-display:hover {
  background: var(--surface-2);
  border-color: var(--input-border);
}
/* Native <select> dropdown options — browsers/OSes use their own colors here
   unless we override. Without this rule the option text is unreadable on
   the dark-theme system white popup. */
select, .select { color: var(--text); }
select option, .select option {
  background-color: var(--input-bg);
  color: var(--text);
}
.textarea { resize: vertical; min-height: 120px; font-family: var(--mono); font-size: 13px; }
.row { display: flex; gap: 14px; flex-wrap: wrap; align-items: flex-end; }
.row > .field { flex: 1; min-width: 200px; }

/* Tables */
.table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 14px;
}
.table th, .table td {
  text-align: left;
  padding: 12px 14px;
  border-bottom: 1px solid var(--border-soft);
}
.table th {
  background: var(--table-head-bg);
  color: var(--text-muted);
  font-weight: 600;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .04em;
  position: sticky; top: 0;
}
.table tr:last-child td { border-bottom: 0; }
.table tr.row-link { cursor: pointer; transition: background .12s; }
.table tr.row-link:hover { background: var(--surface-2); }
.table-wrap {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--surface);
}
.table .col-actions { text-align: right; width: 1%; white-space: nowrap; }

/* ─── KV grid (used by Preflight + Settings) ─── */
.kv {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 14px 18px;
  font-size: 14px;
  align-items: center;
  /* Force every row to be the same height so a pill-containing row doesn't
     visually shift the rows around it. */
  grid-auto-rows: minmax(32px, auto);
}
.kv > div {
  min-height: 32px;
  display: flex;
  align-items: center;
}
.kv > div:nth-child(odd) { color: var(--text-muted); font-weight: 600; font-size: 13px; }
.kv ul { list-style: none; margin: 0; padding: 0; }
.kv ul li { padding: 2px 0; }
@media (max-width: 640px) {
  .kv { grid-template-columns: 1fr; gap: 4px; }
  .kv > div:nth-child(odd) { padding-top: 8px; }
}

/* ═══════════════════════════════════════════════════════════════
   FLOW HEADER — meeting name + section + chevron stepper
   ═══════════════════════════════════════════════════════════════ */
.flow-header { margin-bottom: 20px; }
.flow-meta {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;
  margin-bottom: 0;
  flex-wrap: wrap;
}
.flow-name {
  margin: 0;
  font-size: 24px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--text);
}
.flow-section {
  font-size: 13px;
  color: var(--text-muted);
  font-weight: 500;
}
.flow-section b { color: var(--text); font-weight: 600; }
.flow-actions { display: flex; gap: 8px; flex-wrap: wrap; }

/* Chevron / arrow stepper — each step "points" into the next via clip-path.
   No borders (clip-path doesn't trace borders nicely); shape is purely fill
   color, so contrast with the page background tells the eye where steps end. */
.stepper {
  display: flex;
  flex-wrap: wrap;
  margin: 0;
  font-family: var(--font);
}
.step {
  --chev: 14px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 22px 10px calc(20px + var(--chev));
  background: var(--surface-2);
  color: var(--text-muted);
  font-size: 13px;
  font-weight: 600;
  position: relative;
  cursor: default;
  /* Right-pointing chevron: right edge tapers to a point, left edge has a
     matching indent so the previous step's tip slots in. */
  clip-path: polygon(
    0 0,
    calc(100% - var(--chev)) 0,
    100% 50%,
    calc(100% - var(--chev)) 100%,
    0 100%,
    var(--chev) 50%
  );
  margin-left: calc(var(--chev) * -1);
  transition: background .15s, color .15s;
}
.step:first-child {
  padding-left: 20px;
  margin-left: 0;
  /* Flat left edge (no incoming indent). */
  clip-path: polygon(
    0 0,
    calc(100% - var(--chev)) 0,
    100% 50%,
    calc(100% - var(--chev)) 100%,
    0 100%
  );
}
/* Last step keeps its outgoing chevron point (like SAP Fiori wizards).
   The trailing point just hangs out into empty space since no step follows.
   Add a hair of right padding so the text isn't crammed against the tip. */
.step:last-child { padding-right: 28px; }
.step.clickable { cursor: pointer; }
.step.clickable:hover { background: var(--surface-3); color: var(--text); z-index: 3; }
.step.active {
  background: var(--brand);
  color: white;
  z-index: 2;
}
.step.done {
  background: var(--accent-soft);
  color: var(--accent);
  z-index: 1;
}
.step .step-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 50%;
  background: rgba(0,0,0,.18);
  font-weight: 700; font-size: 12px;
  flex-shrink: 0;
}
.step.active .step-num { background: rgba(255,255,255,.30); color: white; }
.step.done .step-num   { background: var(--brand); color: white; }
@media (max-width: 640px) {
  .step { padding: 8px 16px 8px 22px; font-size: 12px; }
  .step .step-num { width: 18px; height: 18px; font-size: 11px; }
}

/* ═══════════════════════════════════════════════════════════════
   MAPPING LAYOUT — Key + Registration on top, Pre/Post/Eval below
   Top row is 2 cols; main row is 3 cols and the cards there carry the
   actual column-mapping UI. Key + Reg only need ingest controls.
   ═══════════════════════════════════════════════════════════════ */
.mapping-grid {
  display: grid;
  gap: 14px;
  align-items: stretch;
}
.mapping-grid-top  { grid-template-columns: repeat(2, minmax(220px, 1fr)); margin-bottom: 14px; }
.mapping-grid-main { grid-template-columns: repeat(3, minmax(220px, 1fr)); }
/* With the audience-collapse card present, Key/Reg narrow so the wider collapse
   card fits. align-items:stretch (inherited) keeps all three equal height, so
   the column-mapping row below starts at one baseline. */
.mapping-grid-top-3 { grid-template-columns: minmax(150px,0.6fr) minmax(150px,0.6fr) minmax(380px,2.2fr); }
@media (max-width: 900px) {
  .mapping-grid-top  { grid-template-columns: 1fr; }
  .mapping-grid-top-3 { grid-template-columns: 1fr; }
  .mapping-grid-main { grid-template-columns: 1fr; }
}
.map-col {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 16px;
  display: flex; flex-direction: column;
  gap: 12px;
  min-width: 0;
}
/* Key + Total Participants stacked in one top-row column. align-self:start so a
   short Key card doesn't stretch to a tall neighbour (e.g. the Integrated card)
   and leave a big empty gap — the Total Participants card sits right under it. */
.map-col-stack {
  display: flex; flex-direction: column; gap: 14px;
  align-self: start;
  min-width: 0;
}
.map-col-stack > .map-col { flex: 0 0 auto; }
.map-col-head {
  display: flex; align-items: center; gap: 10px;
  min-width: 0;
}
.map-col-head h3 { margin: 0; font-size: 15px; }
.map-col-head .req-pill {
  margin-left: auto;
  font-size: 10px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .04em;
  padding: 2px 8px; border-radius: 999px;
  background: var(--surface-2); color: var(--text-muted);
}
.map-col-head .req-pill.optional { opacity: .8; }
.map-col-ingest {
  display: grid;
  grid-template-columns: 1fr 64px;
  gap: 8px;
  align-items: end;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--border-soft);
}
.map-col-ingest .field { gap: 4px; }
.map-col-ingest .field .label { font-size: 11px; }
.map-col-ingest .select,
.map-col-ingest .input { padding: 7px 10px; font-size: 13px; }
.map-col-ingest .col-status {
  grid-column: 1 / -1;
  color: var(--text-muted);
  font-size: 11px;
}
.map-col-fields { display: flex; flex-direction: column; gap: 10px; }
.map-col-fields.empty { color: var(--text-muted); font-size: 13px; font-style: italic; padding: 6px 0; }
.map-field { display: flex; flex-direction: column; gap: 4px; }
.map-field .map-field-label {
  font-size: 12px; font-weight: 600;
  color: var(--text);
  display: flex; align-items: center; gap: 4px;
}
.map-field.unmatched .map-field-label { color: var(--danger); }
.map-field.unmatched .map-field-label::before { content: "⚠ "; }
.map-field .select { padding: 7px 10px; font-size: 13px; }
.map-col-status-pill {
  font-size: 11px; font-weight: 600;
  padding: 3px 8px; border-radius: 999px;
  display: inline-block;
}
.map-col-status-pill.ok   { background: rgba(14,122,43,.18); color: #6ee7a8; }
.map-col-status-pill.fail { background: rgba(239,68,68,.18); color: #fca5a5; }
[data-theme="light"] .map-col-status-pill.ok   { background: #dcfce7; color: #15803d; }
[data-theme="light"] .map-col-status-pill.fail { background: #fee2e2; color: #991b1b; }

/* ── Audience collapse card (grant lines) ─────────────────────────────────── */
.ac-toggle { display:flex; align-items:center; gap:6px; font-size:13px; font-weight:600; cursor:pointer; }
.ac-toggle input { cursor:pointer; }
.ac-sec-label { font-size:11px; text-transform:uppercase; letter-spacing:.04em; color:var(--text-muted); margin:10px 0 4px; }
.ac-lines { display:flex; flex-direction:column; gap:8px; }
.ac-line {
  border:1px dashed var(--border); border-radius:10px; padding:8px; background:var(--surface-2,rgba(255,255,255,.02));
  transition:border-color .12s, background .12s;
}
.ac-line.ac-dragover, .ac-pool.ac-dragover { border-color:#7c8cff; background:rgba(124,140,255,.12); }
.ac-line-inputs { display:flex; gap:6px; align-items:center; }
.ac-in { padding:5px 8px !important; font-size:12px !important; }
.ac-in:first-child { flex:0 0 64px; }
.ac-in:nth-child(2) { flex:1 1 auto; }
.ac-del {
  flex:0 0 auto; width:24px; height:24px; border:none; border-radius:6px; cursor:pointer;
  background:rgba(239,68,68,.14); color:#fca5a5; font-size:16px; line-height:1;
}
.ac-del:hover { background:rgba(239,68,68,.26); }
.ac-line-count { font-size:11px; color:var(--text-muted); margin:6px 0 4px; }
.ac-line-count.empty { font-style:italic; opacity:.7; }
.ac-line-chips, .ac-pool { display:flex; flex-wrap:wrap; gap:6px; }
.ac-pool { min-height:34px; border:1px dashed var(--border); border-radius:10px; padding:8px; align-items:center; }
.ac-chip {
  display:inline-flex; align-items:center; gap:5px; padding:3px 6px 3px 8px;
  background:var(--surface); border:1px solid var(--border); border-radius:14px;
  font-size:11px; cursor:grab; user-select:none;
}
.ac-chip.assigned { background:rgba(124,140,255,.12); border-color:rgba(124,140,255,.4); }
.ac-chip.dragging { opacity:.45; }
.ac-chip-lbl { white-space:nowrap; }
.ac-chip-n { font-size:10px; color:var(--text-muted); }
.ac-chip-sel { font-size:10px; padding:1px 2px; border-radius:6px; border:1px solid var(--border); background:transparent; color:inherit; cursor:pointer; }
.ac-add { font-size:12px; padding:4px 10px; margin-top:6px; align-self:flex-start; }
.ac-head-toggle { margin-left:auto; font-size:12px; font-weight:600; }
.ac-comment-headrow { display:flex; align-items:center; justify-content:space-between; gap:8px; margin-top:28px; margin-bottom:6px; }
.ac-comment-block { display:flex; flex-direction:column; gap:8px; align-items:flex-start; }
.ac-comment-text { font-size:11px; font-style:italic; color:var(--text-muted); }
.ac-copy { font-size:11px; padding:2px 10px; flex:0 0 auto; }
/* Two side-by-side panes inside the card (category list ↔ grant categories). */
.ac-2pane { display:flex; gap:12px; align-items:flex-start; margin-top:8px; }
.ac-pane { flex:1 1 0; min-width:0; }
.ac-scroll { max-height:240px; overflow:auto; padding-right:2px; }
.ac-hint { font-size:11px; color:var(--text-muted); margin-bottom:6px; }
@media (max-width: 1100px) { .ac-2pane { flex-direction:column; } }
/* Pick-list: detected pairs the user checks to KEEP as grant categories. */
.ac-picks { display:flex; flex-direction:column; gap:2px; }
.ac-picks.ac-dragover { outline:2px dashed #7c8cff; outline-offset:2px; border-radius:8px; }
.ac-pick { display:flex; align-items:center; gap:8px; padding:4px 6px; border-radius:8px; cursor:pointer; font-size:12px; }
.ac-pick:hover { background:rgba(124,140,255,.08); }
.ac-pick.on { background:rgba(124,140,255,.14); }
.ac-pick-static { cursor:default; }
.ac-pick-static:hover { background:transparent; }
.ac-pick input { cursor:pointer; }
.ac-pick-lbl { flex:1 1 auto; }
/* Target (grant category) header: picked-pair label + rename + remove. */
.ac-line-hdr { display:flex; align-items:center; gap:6px; }
.ac-line-title { flex:1 1 auto; font-size:12px; font-weight:600; }
.ac-mini { flex:0 0 auto; width:22px; height:22px; border:none; border-radius:6px; cursor:pointer;
  background:rgba(124,140,255,.16); color:#a9b4ff; font-size:12px; line-height:1; }
.ac-mini:hover { background:rgba(124,140,255,.3); }
.ac-chip-x { cursor:pointer; color:#fca5a5; font-size:13px; line-height:1; padding-left:2px; }
.ac-chip-x:hover { color:#ef4444; }

/* ═══════════════════════════════════════════════════════════════
   CHART CARDS — Results-dashboard panels
   Each card has a header (title + optional action) + a chart body.
   ApexCharts is themed via JS (renderApex.theme) — these styles handle
   the surrounding chrome.
   ═══════════════════════════════════════════════════════════════ */
.chart-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 18px 20px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
  box-shadow: var(--shadow-1);
}
.chart-card .chart-head {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 12px;
  min-width: 0;
}
.chart-card .chart-head > .chart-title    { grid-column: 1; justify-self: start; min-width: 0; }
.chart-card .chart-head > .chart-actions  { grid-column: 3; justify-self: end; }
/* The violin SVG has asymmetric padding (padL=50 vs padR=30), so its
   plot-area center sits ~10px right of the chart-head's geometric center.
   Shift the chip right by that amount so it visually lands between the
   two violin columns rather than offset to the left. */
.chart-card .chart-head > .pair-banner-chip {
  grid-column: 2;
  justify-self: center;
  transform: translateX(10px);
}
.chart-actions { display: flex; gap: 4px; flex-shrink: 0; }
.chart-action-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text-muted);
  cursor: pointer;
  transition: background .15s, color .15s, border-color .15s;
  padding: 0;
}
.chart-action-btn:hover { background: var(--surface-2); color: var(--text); border-color: var(--accent-ring); }
@media print { .chart-actions { display: none !important; } }
.chart-card .chart-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  display: flex; align-items: center; gap: 10px;
  min-width: 0;
}
.chart-card .chart-title .slot-icon {
  width: 30px; height: 30px;
  border-radius: 8px;
  flex-shrink: 0;
}
.chart-card .chart-sub { font-size: 11px; color: var(--text-muted); margin-top: -4px; }
/* No min-height on chart-body — each chart manages its own height and adding
   a minimum produces dead space under shorter charts (notably the Confidence
   Likert and demographics pies). ApexCharts mounts fine even when the host
   has a momentary zero height; we measure on render. */
.chart-card .chart-body { width: 100%; }
.chart-card.span-2 { grid-column: span 2; }

/* Aggregate grantor checkbox group — small bordered pills with a visible
   checkbox. The "All" master sits first and adopts indeterminate styling
   when a partial selection is active. */
.agg-check {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 12px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  border-radius: 10px;
  font-size: 13px;
  color: var(--text);
  cursor: pointer;
  user-select: none;
  transition: background .15s, border-color .15s;
}
.agg-check:hover { border-color: var(--accent-ring); background: var(--surface-3); }
.agg-check-input {
  width: 16px; height: 16px;
  accent-color: var(--brand);
  cursor: pointer;
  margin: 0;
}
.agg-check-input:checked + .agg-check-label { color: var(--accent); font-weight: 600; }
.agg-check-all { background: var(--accent-soft); border-color: var(--accent-ring); }
.agg-check-all .agg-check-label { font-weight: 700; }

/* Score-distribution summary strip — Pre/Post stats centered under each
   violin column. The SVG draws violins at padL + innerW * 0.25 and
   padL + innerW * 0.75 (padL=50, padR=30). To make cell text centers
   land EXACTLY on those positions at every width, we use a 4-column
   grid (padL · innerW/2 · innerW/2 · padR) with gap:0. The two cells
   occupy cols 2 and 3, whose centers are then padL + innerW/4 and
   padL + 3*innerW/4 — identical to the violin centers. Visual spacing
   between cells comes from each cell's max-width + padding, not gap. */
.sd-summary {
  display: grid;
  grid-template-columns: 50px 1fr 1fr 30px;
  gap: 0;
  margin-top: 6px;
}
.sd-summary-cell {
  text-align: center;
  font-size: 12px;
  padding: 8px 14px;
  border-radius: 8px;
  background: var(--surface-2);
  justify-self: center;
  min-width: 220px;
  max-width: 360px;
}
.sd-summary-cell:first-child  { grid-column: 2; }
.sd-summary-cell:nth-child(2) { grid-column: 3; }
.sd-summary-title {
  font-weight: 700;
  margin-bottom: 2px;
}
@media (max-width: 700px) {
  .sd-summary {
    margin: 6px 12px 0;
    grid-template-columns: 1fr;
  }
  .sd-summary-cell:first-child,
  .sd-summary-cell:nth-child(2) { grid-column: 1; }
}

/* Paired-test result banner — centered between the two summary cells.
   The wrap mirrors .sd-summary's horizontal padding so the banner's
   horizontal midpoint lines up with the chart's plot-area midpoint
   (i.e. the gap between Pre-Test and Post-Test cells). */
.pair-banner-wrap {
  display: flex;
  justify-content: center;
  margin: 10px 30px 0 70px;
}
@media (max-width: 700px) {
  .pair-banner-wrap { margin: 10px 12px 0; }
}
.pair-banner {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 18px;
  border-radius: 10px;
  background: var(--surface-2);
  border-left: 4px solid var(--text-muted);
  max-width: 540px;
  justify-content: flex-start;
}
.pair-banner.sig   { background: var(--accent-soft); border-left-color: var(--accent); }
.pair-banner.nonsig { background: var(--surface-2); border-left-color: var(--warn); }
.pair-banner-icon {
  width: 28px; height: 28px;
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 700;
  flex-shrink: 0;
}
.pair-banner.sig   .pair-banner-icon { background: var(--accent); color: white; }
.pair-banner.nonsig .pair-banner-icon { background: var(--warn); color: #1a1100; }
.pair-banner-text { flex: 1; min-width: 0; }
.pair-banner-headline { font-size: 14px; color: var(--text); }
.pair-banner-sub { font-size: 12px; color: var(--text-muted); margin-top: 2px; }

/* Compact chip variant — for inline placement in chart-head rows.
   Removes the colored left-edge accent (which looks like a stray
   off-center highlight when the chip sits in a centered header slot)
   and bumps the headline text up to match the title's weight. */
.pair-banner.pair-banner-chip {
  padding: 6px 14px;
  border-radius: 10px;
  border-left: 0;
  gap: 10px;
  max-width: none;
  margin: 0;
  flex-shrink: 1;
  min-width: 0;
}
.pair-banner-chip .pair-banner-icon {
  width: 22px; height: 22px;
  font-size: 12px;
}
.pair-banner-chip .pair-banner-headline {
  font-size: 14px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* List-style bar charts (for narrower screens / small cards) — kept as a
   fallback when not enough room for a full ApexChart. */
.h-bar-list { display: flex; flex-direction: column; gap: 8px; padding-bottom: 14px; }
.h-bar-list .row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 8px;
  align-items: center;
  font-size: 13px;
}
.h-bar-list .row .lbl { color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.h-bar-list .row .pct { color: var(--text-muted); font-weight: 600; font-variant-numeric: tabular-nums; }
.h-bar-list .bar {
  grid-column: 1 / -1;
  height: 8px; border-radius: 999px;
  background: var(--surface-2);
  overflow: hidden;
  position: relative;
}
.h-bar-list .bar > span {
  position: absolute; top: 0; left: 0; bottom: 0;
  background: linear-gradient(90deg, var(--accent), var(--cyan));
  border-radius: inherit;
}

/* Compact file row — flex layout so all generated reports sit side-by-side
   on one row at typical widths. Each pill is label + icon-only Download.
   Smaller min-basis (140px) so 6 cards comfortably fit on a 1100px+ container. */
.files-row {
  display: flex; flex-wrap: wrap; gap: 8px;
}
.compact-file-card {
  flex: 1 1 140px;
  min-width: 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 8px 10px 8px 12px;
  display: flex; align-items: center; gap: 8px;
}
.compact-file-card .cf-label {
  flex: 1;
  font-weight: 600;
  font-size: 13px;
  color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.btn-icon-dl {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px;
  background: var(--brand);
  color: white;
  border-radius: 8px;
  flex-shrink: 0;
  transition: background .15s;
  text-decoration: none;
}
.btn-icon-dl:hover { background: var(--brand-2); }

/* ═══════════════════════════════════════════════════════════════
   RESULT CARDS — compact small cards for downloads
   ═══════════════════════════════════════════════════════════════ */
.result-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 14px;
  display: flex; flex-direction: column;
  gap: 6px;
  transition: border-color .15s, box-shadow .15s;
}
.result-card:hover { border-color: var(--accent-ring); box-shadow: var(--shadow-1); }
.result-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px;
}
.result-label { font-weight: 600; font-size: 14px; line-height: 1.2; }
.result-filename { font-size: 11px; color: var(--text-muted); word-break: break-all; min-height: 16px; }
.result-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; margin-top: 6px;
}
.ext-badge {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 10px; font-weight: 700;
  padding: 3px 8px; border-radius: 6px;
  background: var(--surface-2); color: var(--text-muted);
  text-transform: uppercase; letter-spacing: .04em;
}
.ext-badge.docx { background: rgba(56,189,248,.16); color: var(--info); }
.ext-badge.pptx { background: rgba(232,121,249,.16); color: var(--magenta); }
.ext-badge.xlsx { background: rgba(14,122,43,.16); color: var(--ok); }
.ext-badge.pdf  { background: rgba(239,68,68,.16);  color: var(--danger); }
[data-theme="light"] .ext-badge.docx { background: #dbeafe; color: #1e40af; }
[data-theme="light"] .ext-badge.pptx { background: #fce7f3; color: #be185d; }
[data-theme="light"] .ext-badge.xlsx { background: #dcfce7; color: #166534; }
.result-card .btn { padding: 5px 12px; font-size: 12px; }

/* ═══════════════════════════════════════════════════════════════
   DROPZONE — drag-and-drop file picker
   ═══════════════════════════════════════════════════════════════ */
.dropzone {
  border: 2px dashed var(--input-border);
  border-radius: var(--radius-lg);
  padding: 28px 20px;
  text-align: center;
  background: var(--surface);
  transition: border-color .15s, background .15s, transform .15s;
  position: relative;
  cursor: pointer;
}
.dropzone:hover { border-color: var(--accent); }
.dropzone.is-drag {
  border-color: var(--accent);
  background: var(--accent-soft);
  box-shadow: 0 0 0 4px var(--accent-ring);
}
.dropzone .dz-icon {
  width: 48px; height: 48px;
  margin: 0 auto 10px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent-soft);
  color: var(--accent);
  border-radius: 14px;
}
.dropzone .dz-title { font-size: 16px; font-weight: 600; }
.dropzone .dz-sub { color: var(--text-muted); font-size: 13px; margin-top: 4px; }
.dropzone input[type=file] { display: none; }

/* Per-slot file cards */
.slot-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px;
  margin-top: 16px;
}
.slot {
  border: 1px solid var(--border);
  background: var(--surface);
  border-radius: var(--radius);
  padding: 14px;
  transition: border-color .15s, background .15s;
  position: relative;
  min-height: 130px;
}
.slot.is-drag {
  border-color: var(--accent);
  background: var(--accent-soft);
  box-shadow: 0 0 0 3px var(--accent-ring);
}
.slot.has-file { border-color: var(--ok); }
.slot.optional { border-style: dashed; }
.slot-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 8px;
  gap: 8px;
}
.slot-head .slot-title {
  display: flex; align-items: center; gap: 8px;
  min-width: 0; flex: 1;
}
.slot-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px;
  border-radius: 8px;
  background: var(--accent-soft); color: var(--accent);
  flex-shrink: 0;
}
.slot-label { font-weight: 600; font-size: 14px; }
.slot-req { font-size: 11px; color: var(--text-muted); text-transform: uppercase; letter-spacing: .05em; flex-shrink: 0; }
.slot-body { color: var(--text-muted); font-size: 13px; min-height: 36px; }
.slot.has-file .slot-body { color: var(--text); }
.slot-filename {
  display: flex; align-items: center; gap: 8px;
  word-break: break-all;
  font-size: 13px;
}
.slot-filename .check { color: var(--ok); flex-shrink: 0; }
.slot-meta { color: var(--text-muted); font-size: 11px; margin-top: 2px; }
.slot-actions { margin-top: 10px; display: flex; gap: 6px; }

/* ═══════════════════════════════════════════════════════════════
   MODAL — custom confirm/alert dialog (replaces native confirm())
   ═══════════════════════════════════════════════════════════════ */
.modal-host {
  position: fixed; inset: 0; z-index: 900;
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  background: rgba(0,0,0,.55);
  backdrop-filter: blur(4px);
  animation: modal-fade-in .15s ease-out;
}
@keyframes modal-fade-in { from { opacity: 0; } to { opacity: 1; } }
.modal-host.fade { animation: modal-fade-out .12s ease-in forwards; }
@keyframes modal-fade-out { from { opacity: 1; } to { opacity: 0; } }
.modal-card {
  width: 100%; max-width: 480px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-3);
  padding: 24px 26px 20px;
  animation: modal-slide-in .18s ease-out;
}
@keyframes modal-slide-in {
  from { transform: translateY(-12px); opacity: 0; }
  to   { transform: translateY(0); opacity: 1; }
}
.modal-title {
  margin: 0 0 8px;
  font-size: 18px;
  font-weight: 600;
  color: var(--text);
  display: flex; align-items: center; gap: 10px;
}
.modal-icon {
  width: 32px; height: 32px;
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.modal-icon.warn   { background: rgba(245,158,11,.16); color: var(--warn); }
.modal-icon.danger { background: rgba(239,68,68,.16); color: var(--danger); }
.modal-icon.info   { background: rgba(56,189,248,.16); color: var(--info); }
.modal-body {
  font-size: 14px; line-height: 1.55;
  color: var(--text);
  white-space: pre-wrap;
  margin-bottom: 18px;
}
.modal-actions {
  display: flex; justify-content: flex-end; gap: 8px;
  flex-wrap: wrap;
}
.modal-gate {
  margin: 0 0 16px;
  display: flex; flex-direction: column; gap: 6px;
}
.modal-gate-label { font-size: 13px; color: var(--text-muted); }
.modal-gate b { color: var(--danger); letter-spacing: .04em; font-family: monospace; }

/* ═══════════════════════════════════════════════════════════════
   BULK SELECTION (Meetings list)
   ═══════════════════════════════════════════════════════════════ */
.table thead th.col-bulk,
.table tbody td.col-bulk { width: 36px; padding-right: 0; text-align: center; }
.bulk-bar {
  position: fixed;
  left: 50%; bottom: 24px;
  transform: translateX(-50%);
  z-index: 800;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 10px 16px;
  box-shadow: var(--shadow-3);
  display: flex; align-items: center; gap: 14px;
  min-width: 360px;
  animation: bulk-bar-in .18s ease-out;
}
@keyframes bulk-bar-in {
  from { transform: translate(-50%, 12px); opacity: 0; }
  to   { transform: translate(-50%, 0); opacity: 1; }
}
.bulk-bar .bulk-count { font-weight: 600; color: var(--text); }
.bulk-bar .bulk-progress {
  flex: 1; height: 6px; background: var(--surface-2); border-radius: 4px;
  overflow: hidden; min-width: 120px;
}
.bulk-bar .bulk-progress > .fill {
  height: 100%; background: var(--accent); width: 0; transition: width .25s;
}
.bulk-bar .muted { font-size: 12px; }

/* ═══════════════════════════════════════════════════════════════
   TOASTS
   ═══════════════════════════════════════════════════════════════ */
.toast-host {
  position: fixed; top: 16px; right: 16px;
  display: flex; flex-direction: column; gap: 8px;
  z-index: 1000;
  pointer-events: none;
}
.toast {
  pointer-events: auto;
  padding: 12px 16px;
  border-radius: 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text);
  font-size: 14px;
  box-shadow: var(--shadow-2);
  display: flex; align-items: center; gap: 10px;
  min-width: 240px; max-width: 380px;
  animation: toast-in .25s ease-out;
}
.toast.ok    { border-left: 4px solid var(--ok); }
.toast.warn  { border-left: 4px solid var(--warn); }
.toast.fail  { border-left: 4px solid var(--danger); }
.toast.info  { border-left: 4px solid var(--info); }
.toast.fade  { animation: toast-out .25s ease-in forwards; }
@keyframes toast-in {
  from { opacity:0; transform: translateY(-10px); }
  to   { opacity:1; transform: translateY(0); }
}
@keyframes toast-out {
  from { opacity:1; transform: translateY(0); }
  to   { opacity:0; transform: translateY(-10px); }
}

/* ═══════════════════════════════════════════════════════════════
   AUTH SCREEN (login / forced change)
   ═══════════════════════════════════════════════════════════════ */
.auth-screen {
  min-height: 100vh;
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  position: relative;
  overflow: hidden;
}
.auth-bg {
  position: absolute; inset: 0; z-index: 0;
  background:
    radial-gradient(circle at 20% 30%, rgba(34,211,238,.12), transparent 40%),
    radial-gradient(circle at 80% 70%, rgba(14,122,43,.15), transparent 50%),
    radial-gradient(circle at 50% 100%, rgba(232,121,249,.08), transparent 50%);
  pointer-events: none;
}
.auth-card {
  position: relative; z-index: 1;
  width: 100%;
  max-width: 420px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 28px;
  box-shadow: var(--shadow-3);
}
.auth-brand {
  display: flex; align-items: center; gap: 10px;
  justify-content: center;
  margin-bottom: 18px;
}
.auth-brand img { height: 44px; }
.auth-brand .name {
  font-family: "Sloan CMEye Fixed", var(--font);
  font-size: 21px;
  line-height: 0.92;
  font-weight: 400;
  color: var(--gold);
  letter-spacing: 0;
  transform: translateY(1px);
}
.auth-title { text-align: center; font-size: 20px; font-weight: 600; margin: 6px 0; }
.auth-sub   { text-align: center; color: var(--text-muted); font-size: 13px; margin-bottom: 18px; }
.auth-form  { display: flex; flex-direction: column; gap: 12px; }
.auth-form .actions { margin-top: 8px; display: flex; gap: 8px; }
.auth-form .actions .btn { flex: 1; }
.auth-error { color: var(--danger); font-size: 13px; min-height: 16px; }
.auth-rules { background: var(--surface-2); border-radius: 10px; padding: 10px 14px; font-size: 12px; }
.auth-rules ul { margin: 4px 0 0; padding: 0; list-style: none; }
.auth-rules li { padding: 2px 0; color: var(--text-muted); }
.auth-rules li.ok { color: var(--ok); }
.auth-foot { text-align: center; color: var(--text-muted); font-size: 12px; margin-top: 14px; }

/* ═══════════════════════════════════════════════════════════════
   PRINT — clean PDF export of just the dashboard.
   Respects whatever theme the user is currently in (dark or light).
   We only hide chrome (sidebar / topbar / actions / file cards) and
   force the browser to actually print backgrounds. The chart palettes
   come straight from the theme the user sees on screen.
   ═══════════════════════════════════════════════════════════════ */
/* Explicit print page setup — portrait Letter. Margins kept tight so each
   page packs in maximum content. */
@page { size: letter portrait; margin: 0.35in; }

@media print {
  * { print-color-adjust: exact !important; -webkit-print-color-adjust: exact !important; }
  html, body { width: 100% !important; height: auto !important; }
  body::before { display: none !important; }
  .sidebar, .topbar, .toast-host, .modal-host { display: none !important; }
  .main {
    box-shadow: none !important; border-radius: 0 !important;
    min-height: 0 !important; overflow: visible !important;
    width: 100% !important;
  }
  .shell {
    padding: 0 !important; gap: 0 !important;
    grid-template-columns: 1fr !important;
    width: 100% !important;
  }
  .page { padding: 0 !important; max-width: none !important; width: 100% !important; }

  /* Hide the file-row + page-header actions from the printed dashboard. */
  .compact-file-card { display: none !important; }
  .files-row { display: none !important; }
  .flow-header .flow-actions { display: none !important; }
  .flow-name { font-size: 22px !important; margin: 6px 0 16px !important; }

  .chart-card, .kpi {
    break-inside: avoid; page-break-inside: avoid;
    box-shadow: none !important;
    padding: 14px !important;
  }
  .kpi::after { display: none !important; }
  .kpi { padding: 10px 12px !important; }
  .kpi .kpi-value { font-size: 20px !important; }
  .kpi .kpi-icon { display: none !important; }
  .kpi-meta { font-size: 10px !important; }

  /* Only hide the per-chart action buttons. Everything else (incl. ApexCharts
     legends) renders exactly as on the results page — the export is a scaled
     copy of the live dashboard, not a reflowed variant. */
  .chart-actions { display: none !important; }

  /* The one deliverable-specific tweak: let the Practice/Barriers bar labels
     wrap instead of truncating with an ellipsis, so the full item text prints. */
  .h-bar-list .row .lbl {
    white-space: normal !important;
    overflow: visible !important;
    text-overflow: clip !important;
  }
}

/* CRITICAL: also wrap the bar labels in the .printing-pdf PREP state (not just
   during @media print). equalizeCardRows() measures card heights in this state,
   BEFORE printToPDF activates @media print. If the labels are still nowrap when
   it measures, it equalizes to the short (unwrapped) heights, then long Barriers
   labels wrap during capture and grow taller than the equalized Practice card —
   leaving gray page bg below the shorter card. Wrapping here keeps the measured
   heights honest. */
html.printing-pdf .h-bar-list .row .lbl {
  white-space: normal !important;
  overflow: visible !important;
  text-overflow: clip !important;
}

/* Print layout — applied via the .printing-pdf class on <html>. We keep these
   OUT of @media print so they kick in BEFORE the chart re-render in
   printDashboard(); ApexCharts captures dimensions at mount time, so charts
   need to measure their cards in the FINAL print layout (not the screen-mode
   2-col layout) or they end up tiny inside a wider card. */
/* Critical: when .sidebar { display: none } removes the sidebar from grid
   flow, .main auto-places into the FIRST grid cell (the 244px sidebar
   column) and ends up 244px wide. We MUST override the shell's grid
   template to single-column too. */
html.printing-pdf .shell { grid-template-columns: 1fr !important; padding: 0 !important; gap: 0 !important; }
html.printing-pdf .main  { border-radius: 0 !important; box-shadow: none !important; min-height: 0 !important; }
/* Force a pure-white canvas everywhere in the printed report. The page tray
   (body --shell-bg) and the radial bg-grad are a light blue-gray; in print
   they showed through under/around any card that wasn't full-height (notably
   the shorter of Practice Changes / Barriers), reading as "gray hanging out
   the bottom of the white box." A white canvas means a short card can never
   expose gray, regardless of height. (Cards still get equal height via the
   flexbox align-items:stretch rule below — this is the safety net.) */
html.printing-pdf,
html.printing-pdf body,
html.printing-pdf .shell,
html.printing-pdf .main,
html.printing-pdf .page { background: #ffffff !important; }
html.printing-pdf body::before { display: none !important; }
html.printing-pdf .grid.grid-3,
html.printing-pdf .grid.grid-4,
html.printing-pdf .grid.grid-5 { grid-template-columns: 1fr !important; gap: 12px !important; }
/* Keep the chart grid 2-up in print so the half-width cards — Domain / LO,
   the two demographic donuts, Practice Changes / Barriers — sit side by side
   like the on-screen dashboard (the user's reference). Full-width cards still
   span both columns via the .span-2 rule below. */
/* Use FLEXBOX (not grid) for the 2-up chart row in print. Chrome's printToPDF
   does NOT stretch grid items to the row height (the shorter of two cards
   collapses to its content and shows gray page bg below it), but flexbox
   align-items:stretch DOES stretch reliably in printToPDF — so side-by-side
   cards (Practice/Barriers, the donuts, Domain/LO) come out equal height with
   their white background filling the whole cell. */
html.printing-pdf .grid.grid-2 {
  display: flex !important;
  flex-wrap: wrap !important;
  align-items: stretch !important;
  gap: 12px !important;
}
/* height:auto is CRITICAL: the base rule `.grid > .chart-card { height:100% }`
   gives the card a non-auto height, which makes flexbox `align-items:stretch`
   a no-op (stretch only applies to auto-height items) — so the shorter card
   (e.g. Barriers, 4 rows vs Practice's 5) kept its content height and came out
   ~40px shorter. Forcing height:auto + align-self:stretch lets the row equalize
   to the taller card, so both white cards reach the same bottom edge. */
html.printing-pdf .grid.grid-2 > .chart-card {
  flex: 1 1 calc(50% - 6px) !important;
  min-width: 0 !important;
  height: auto !important;
  align-self: stretch !important;
}
html.printing-pdf .grid.grid-2 > .chart-card.span-2 { flex-basis: 100% !important; }
/* Critical: `.chart-card.span-2 { grid-column: span 2 }` was forcing the
   browser to silently auto-generate a second column even when our template
   says `1fr` (1 column). In print mode, span-2 cards should fill the only
   column we have. `1 / -1` spans from first to last grid line — works
   whether the grid has 1 or many columns. */
html.printing-pdf .chart-card.span-2 { grid-column: 1 / -1 !important; }
html.printing-pdf .grid.kpi-row { grid-template-columns: repeat(5, 1fr) !important; margin-bottom: 14px !important; }
html.printing-pdf .grid.grid-4.kpi-row { grid-template-columns: repeat(4, 1fr) !important; }
/* NOTE: do NOT add horizontal margin to .sd-summary in print. The violin SVG
   spans the full host width with padL=50/padR=30, and the summary grid mirrors
   that (50px 1fr 1fr 30px) so each stat box centers under its violin. A left/
   right margin here would shift the grid relative to the SVG and the boxes would
   no longer line up under the Pre-Test / Post-Test violins. */

/* Pin the export to a FIXED design width — the same width the results page
   uses on a wide screen — so the dashboard renders identically to what the user
   sees (right-side donut legends, 2-up cards, nothing clipped). The server-side
   renderer (tools/render_dashboard_pdf.py) then measures this width and applies
   a uniform printToPDF `scale` so the whole 1280px-wide dashboard shrinks to fit
   the paper — a scaled copy of the live page, NOT a narrow reflow. Fixing the
   width here (rather than letting it track the viewport) keeps the layout
   stable while Chrome lays out the PDF, so the measured scale stays exact. */
html.printing-pdf .page {
  width: 1280px !important;
  max-width: 1280px !important;
  margin: 0 auto !important;
}
html.printing-pdf .main { width: 100% !important; align-items: center !important; }

/* Screen-side toggle: when printDashboard() flips the class, hide non-essential
   chrome immediately so the in-page preview matches the print output. */
html.printing-pdf .sidebar,
html.printing-pdf .topbar,
html.printing-pdf .toast-host { display: none; }
html.printing-pdf .files-row { display: none; }
html.printing-pdf .flow-actions { display: none; }
html.printing-pdf .chart-actions { display: none; }

/* ═══════════════════════════════════════════════════════════════
   Misc helpers
   ═══════════════════════════════════════════════════════════════ */
.empty-state {
  text-align: center;
  padding: 48px 24px;
  color: var(--text-muted);
}
.empty-state .empty-icon {
  width: 56px; height: 56px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 16px; background: var(--surface-2);
  color: var(--text-faint);
  margin-bottom: 12px;
}
.empty-state .empty-title { color: var(--text); font-weight: 600; font-size: 16px; margin-bottom: 4px; }

.status-dot {
  display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  background: var(--text-faint); vertical-align: middle; margin-right: 6px;
}
.status-dot.ok   { background: var(--ok); box-shadow: 0 0 0 2px rgba(14,122,43,.18); }
.status-dot.warn { background: var(--warn); box-shadow: 0 0 0 2px rgba(245,158,11,.18); }
.status-dot.fail { background: var(--danger); box-shadow: 0 0 0 2px rgba(239,68,68,.18); }

/* Run/loading indicator */
.spinner {
  width: 18px; height: 18px; border-radius: 50%;
  border: 2px solid var(--border);
  border-top-color: var(--accent);
  animation: spin .8s linear infinite;
  display: inline-block; vertical-align: middle;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Mapping page — unmatched fields stand out */
select.unmatched, .select.unmatched {
  border-color: var(--danger) !important;
  background: rgba(239,68,68,.08) !important;
}
.table tr.unmatched-row td:first-child {
  color: var(--danger) !important; font-weight: 600;
}
.table tr.unmatched-row td:first-child::before { content: "⚠ "; }

/* ═══════════════════════════════════════════════════════════════
   Mobile (≤900px) — sidebar becomes a drawer, drop the floating gap
   ═══════════════════════════════════════════════════════════════ */
@media (max-width: 900px) {
  /* On mobile the sidebar is a fixed drawer, never grid-positioned. Override
     the collapsed-mode grid too so it doesn't reserve a column. */
  .shell,
  .shell[data-collapsed="true"] { grid-template-columns: 1fr; padding: 0; gap: 0; }
  .main { border-radius: 0; min-height: 100vh; box-shadow: none; }
  .sidebar {
    position: fixed; top: 0; left: 0;
    width: var(--sidebar-w);
    height: 100vh;
    border-radius: 0;
    transform: translateX(-100%);
    transition: transform .22s ease-out;
    z-index: 40;
    box-shadow: var(--shadow-3);
  }
  .shell[data-mobile-open="true"] .sidebar { transform: translateX(0); }
  .shell[data-mobile-open="true"]::before {
    content: ""; position: fixed; inset: 0; background: rgba(0,0,0,.5); z-index: 35;
  }
  #btn-menu { display: inline-flex; }
  .sidebar-collapse { display: none; }
  .page { padding: 16px; }
  .topbar { padding: 0 14px; }
  /* On mobile, collapsed-mode classes shouldn't squeeze the drawer. */
  .shell[data-collapsed="true"] .sidebar { width: var(--sidebar-w); }
  .shell[data-collapsed="true"] .nav-label,
  .shell[data-collapsed="true"] .brand-text,
  .shell[data-collapsed="true"] .theme-label,
  .shell[data-collapsed="true"] .nav-section-label,
  .shell[data-collapsed="true"] .user-meta { display: revert; }
}
@media (max-width: 480px) {
  .page-header { flex-direction: column; align-items: stretch; }
  .page-header .ph-actions { justify-content: stretch; }
  .page-header .ph-actions .btn { flex: 1; }
}

/* ─────────────────────────── Keymaster ──────────────────────────────────── */
.field-label { color: var(--text-muted); font-size: 12px; font-weight: 600; letter-spacing: .02em; }
/* Compact, proportional textareas for stems (override the tall mono .textarea). */
.km-ta { min-height: 0; font-family: inherit; font-size: 14px; resize: vertical; }
.km-check { display: flex; align-items: flex-start; gap: 8px; cursor: pointer; line-height: 1.4; }
.km-check input { margin-top: 3px; }
.km-lo-head { display: flex; align-items: center; margin: 22px 0 10px; }
/* LO tally under the evaluation-form toggle; turns amber when there are none. */
.km-lo-count.warn-text { color: var(--warn, #f59e0b); }
.km-qcard { transition: border-color .15s, box-shadow .15s; }
.km-qcard.km-invalid { border-color: var(--warn, #f59e0b); box-shadow: 0 0 0 1px var(--warn, #f59e0b) inset; }
.km-choice-row { display: flex; align-items: center; gap: 10px; margin-top: 6px; }
.km-choice-letter { width: 18px; font-weight: 700; color: var(--text-muted); text-align: center; flex: 0 0 auto; }
.km-choice-row input[type=radio] { flex: 0 0 auto; }
.km-q-flag { white-space: nowrap; }
.km-example {
  white-space: pre-wrap;
  font-family: inherit;
  font-size: inherit;
  line-height: 1.5;
  color: var(--text-muted);
  background: var(--surface-2);
  border: 1px solid var(--input-border);
  border-radius: 10px;
  padding: 12px 14px;
}

/* Help & Support pages — readable prose inside a single card. */
.help-card { max-width: 720px; line-height: 1.55; }
.help-card h3 { margin: 22px 0 6px; font-size: 15px; }
.help-card h3:first-child { margin-top: 4px; }
.help-card p { margin: 0 0 10px; color: var(--text); }
.help-card a { color: var(--accent, #1f9d57); }
