/* ══════════════════════════════════════════════════════════
   aptEDMS Design System
   Premium dark-mode design tokens, components & layouts
   ══════════════════════════════════════════════════════════ */

/* ── Reset ── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* ── Design Tokens ── */
:root {
  /* Colours */
  --bg-base: #050d1a;
  --bg-surface: #0a1628;
  --bg-elevated: #0f1d32;
  --bg-card: rgba(15, 25, 50, 0.7);
  --bg-input: #0c1a2e;
  --bg-hover: rgba(59, 130, 246, 0.06);
  --bg-active: rgba(59, 130, 246, 0.10);

  --text-primary: #e8edf5;
  --text-secondary: #8899b4;
  --text-tertiary: #5a6d88;
  --text-inverse: #050d1a;

  --accent: #3b82f6;
  --accent-hover: #2563eb;
  --accent-subtle: rgba(59, 130, 246, 0.12);
  --accent-glow: rgba(59, 130, 246, 0.25);

  --success: #22c55e;
  --success-subtle: rgba(34, 197, 94, 0.12);
  --warning: #f59e0b;
  --warning-subtle: rgba(245, 158, 11, 0.12);
  --danger: #ef4444;
  --danger-subtle: rgba(239, 68, 68, 0.12);
  --info: #06b6d4;
  --info-subtle: rgba(6, 182, 212, 0.12);
  --purple: #8b5cf6;
  --purple-subtle: rgba(139, 92, 246, 0.12);
  --pink: #ec4899;
  --pink-subtle: rgba(236, 72, 153, 0.12);

  --border: rgba(100, 130, 180, 0.12);
  --border-strong: rgba(100, 130, 180, 0.22);
  --border-accent: rgba(59, 130, 246, 0.3);

  --gradient-start: #1e40af;
  --gradient-end: #7c3aed;

  /* Spacing */
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
  --sp-5: 20px; --sp-6: 24px; --sp-8: 32px; --sp-10: 40px;
  --sp-12: 48px; --sp-16: 64px;

  /* Radius */
  --r-sm: 6px; --r-md: 10px; --r-lg: 14px; --r-xl: 18px; --r-full: 999px;

  /* Typography */
  --font: 'Inter', system-ui, -apple-system, sans-serif;
  --font-mono: 'JetBrains Mono', 'Fira Code', monospace;

  /* Shadows */
  --shadow-sm: 0 1px 3px rgba(0,0,0,0.3);
  --shadow-md: 0 4px 12px rgba(0,0,0,0.3);
  --shadow-lg: 0 8px 30px rgba(0,0,0,0.4);
  --shadow-glow: 0 0 20px var(--accent-glow);

  /* Sidebar */
  --sidebar-width: 260px;
  --sidebar-collapsed: 64px;
  --topbar-height: 56px;
}

/* ── Base ── */
html { font-size: 14px; }
body {
  font-family: var(--font);
  background: var(--bg-base);
  color: var(--text-primary);
  min-height: 100vh;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
img { max-width: 100%; display: block; }

/* ── Scrollbar ── */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: var(--text-tertiary); }

/* ══════════════════════════════════════════════════════════
   LAYOUT: App Shell
   ══════════════════════════════════════════════════════════ */

.app-layout {
  display: grid;
  grid-template-columns: var(--sidebar-width) 1fr;
  grid-template-rows: var(--topbar-height) 1fr;
  grid-template-areas:
    "sidebar topbar"
    "sidebar main";
  min-height: 100vh;
}

/* ── Sidebar ── */
.sidebar {
  grid-area: sidebar;
  background: var(--bg-surface);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  padding: var(--sp-4) 0;
  overflow-y: auto;
  position: sticky;
  top: 0;
  height: 100vh;
}
.sidebar-logo {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-5);
  margin-bottom: var(--sp-6);
  text-decoration: none;
}
.sidebar-logo-icon {
  width: 34px; height: 34px; border-radius: 9px;
  background: linear-gradient(135deg, var(--gradient-start), var(--gradient-end));
  display: grid; place-items: center;
  font-weight: 900; font-size: 13px; color: #fff; flex-shrink: 0;
}
.sidebar-logo-text { font-weight: 800; font-size: 16px; color: var(--text-primary); }

.sidebar-section { margin-bottom: var(--sp-6); }
.sidebar-section-label {
  font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--text-tertiary);
  padding: 0 var(--sp-5); margin-bottom: var(--sp-2);
}

.sidebar-nav { list-style: none; }
.sidebar-nav-item {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-5);
  margin: 0 var(--sp-2); border-radius: var(--r-md);
  color: var(--text-secondary);
  font-size: 13px; font-weight: 500;
  cursor: pointer;
  transition: all 0.15s;
  text-decoration: none;
}
.sidebar-nav-item:hover {
  background: var(--bg-hover);
  color: var(--text-primary);
  text-decoration: none;
}
.sidebar-nav-item.active {
  background: var(--accent-subtle);
  color: var(--accent);
  font-weight: 600;
}
.sidebar-nav-item .icon { width: 18px; text-align: center; font-size: 15px; }
.sidebar-nav-item .badge {
  margin-left: auto;
  background: var(--danger);
  color: #fff;
  font-size: 10px; font-weight: 700;
  padding: 1px 6px; border-radius: var(--r-full);
  min-width: 18px; text-align: center;
}

.sidebar-spacer { flex: 1; }

.sidebar-user {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-5);
  margin: 0 var(--sp-2); border-radius: var(--r-md);
  border-top: 1px solid var(--border);
  padding-top: var(--sp-4);
}
.sidebar-user-avatar {
  width: 32px; height: 32px; border-radius: var(--r-full);
  background: var(--accent-subtle);
  display: grid; place-items: center;
  font-weight: 700; font-size: 12px; color: var(--accent);
}
.sidebar-user-info { flex: 1; min-width: 0; }
.sidebar-user-name { font-size: 13px; font-weight: 600; color: var(--text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sidebar-user-role { font-size: 11px; color: var(--text-tertiary); }

/* ── Top Bar ── */
.topbar {
  grid-area: topbar;
  background: var(--bg-surface);
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center;
  padding: 0 var(--sp-6);
  gap: var(--sp-4);
  position: sticky; top: 0; z-index: 50;
}
.topbar-title { font-size: 15px; font-weight: 700; }
.topbar-breadcrumb { font-size: 12px; color: var(--text-tertiary); }
.topbar-breadcrumb span { color: var(--text-secondary); }
.topbar-spacer { flex: 1; }
.topbar-actions { display: flex; align-items: center; gap: var(--sp-3); }

/* ── Main Content ── */
.main-content {
  grid-area: main;
  padding: var(--sp-6);
  overflow-y: auto;
}

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

/* ── Buttons ── */
.btn {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-4);
  border-radius: var(--r-md); border: 1px solid transparent;
  font-family: var(--font); font-size: 13px; font-weight: 600;
  cursor: pointer; transition: all 0.15s;
  white-space: nowrap;
}
.btn-primary {
  background: linear-gradient(135deg, var(--gradient-start), var(--gradient-end));
  color: #fff; border-color: transparent;
}
.btn-primary:hover { transform: translateY(-1px); box-shadow: var(--shadow-glow); }
.btn-secondary {
  background: transparent;
  color: var(--text-primary);
  border-color: var(--border-strong);
}
.btn-secondary:hover { background: var(--bg-hover); border-color: var(--border-accent); }
.btn-ghost {
  background: transparent; color: var(--text-secondary); border: none;
}
.btn-ghost:hover { color: var(--text-primary); background: var(--bg-hover); }
.btn-danger { background: var(--danger); color: #fff; }
.btn-danger:hover { background: #dc2626; }
.btn-sm { padding: var(--sp-1) var(--sp-3); font-size: 12px; }
.btn-lg { padding: var(--sp-3) var(--sp-6); font-size: 14px; }
.btn-icon { padding: var(--sp-2); width: 34px; height: 34px; justify-content: center; }

/* ── Cards ── */
.card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: var(--sp-5);
  backdrop-filter: blur(12px);
  transition: transform 0.2s, border-color 0.2s, box-shadow 0.2s;
}
.card:hover {
  border-color: var(--border-accent);
  box-shadow: 0 4px 20px rgba(59, 130, 246, 0.06);
}
.card-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--sp-4); }
.card-title { font-size: 15px; font-weight: 700; }
.card-subtitle { font-size: 12px; color: var(--text-tertiary); margin-top: 2px; }
.card-body { }
.card-footer { margin-top: var(--sp-4); padding-top: var(--sp-4); border-top: 1px solid var(--border); }

/* ── Stat Cards (Dashboard) ── */
.stat-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: var(--sp-5);
  display: flex; align-items: flex-start; gap: var(--sp-4);
}
.stat-icon {
  width: 42px; height: 42px; border-radius: var(--r-md);
  display: grid; place-items: center; font-size: 18px; flex-shrink: 0;
}
.stat-icon.blue { background: var(--accent-subtle); }
.stat-icon.green { background: var(--success-subtle); }
.stat-icon.amber { background: var(--warning-subtle); }
.stat-icon.purple { background: var(--purple-subtle); }
.stat-icon.pink { background: var(--pink-subtle); }
.stat-icon.cyan { background: var(--info-subtle); }
.stat-value { font-size: 26px; font-weight: 800; line-height: 1; margin-bottom: 2px; }
.stat-label { font-size: 12px; color: var(--text-tertiary); font-weight: 500; }
.stat-trend { font-size: 11px; font-weight: 600; margin-top: var(--sp-1); }
.stat-trend.up { color: var(--success); }
.stat-trend.down { color: var(--danger); }

/* ── Tables ── */
.table-container {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.table-toolbar {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5);
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}
.table-toolbar .search-input { flex: 1; min-width: 200px; }

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
thead th {
  text-align: left;
  padding: var(--sp-3) var(--sp-4);
  font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--text-tertiary);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
}
thead th:hover { color: var(--text-secondary); }
tbody tr {
  border-bottom: 1px solid var(--border);
  transition: background 0.1s;
}
tbody tr:last-child { border-bottom: none; }
tbody tr:hover { background: var(--bg-hover); }
tbody td {
  padding: var(--sp-3) var(--sp-4);
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 250px;
}
tbody td:first-child { color: var(--text-primary); font-weight: 600; }

.table-footer {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--sp-3) var(--sp-5);
  border-top: 1px solid var(--border);
  font-size: 12px; color: var(--text-tertiary);
}

/* ── Status Badges ── */
.badge-status {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 10px; border-radius: var(--r-full);
  font-size: 11px; font-weight: 600;
  white-space: nowrap;
}
.badge-status.draft { background: var(--border); color: var(--text-secondary); }
.badge-status.ifa { background: var(--info-subtle); color: var(--info); }
.badge-status.ifr { background: var(--warning-subtle); color: var(--warning); }
.badge-status.ifc { background: var(--success-subtle); color: var(--success); }
.badge-status.approved { background: var(--success-subtle); color: var(--success); }
.badge-status.rejected { background: var(--danger-subtle); color: var(--danger); }
.badge-status.superseded { background: var(--purple-subtle); color: var(--purple); }

/* ── Inputs ── */
.input-group { margin-bottom: var(--sp-4); }
.input-group label {
  display: block; font-size: 12px; font-weight: 600;
  color: var(--text-secondary); margin-bottom: var(--sp-1);
}
.input, .select, .textarea {
  width: 100%;
  padding: var(--sp-2) var(--sp-3);
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  color: var(--text-primary);
  font-family: var(--font); font-size: 13px;
  transition: border-color 0.15s;
  outline: none;
}
.input:focus, .select:focus, .textarea:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-subtle);
}
.input::placeholder { color: var(--text-tertiary); }
.textarea { resize: vertical; min-height: 80px; }
.select { cursor: pointer; appearance: none; }
.search-input {
  padding-left: var(--sp-8);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='%235a6d88' viewBox='0 0 16 16'%3E%3Cpath d='M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85zm-5.242.656a5 5 0 1 1 0-10 5 5 0 0 1 0 10z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: 10px center;
}

/* ── Modals ── */
.modal-overlay {
  position: fixed; inset: 0; z-index: 1000;
  background: rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(4px);
  display: flex; align-items: center; justify-content: center;
  opacity: 0; pointer-events: none;
  transition: opacity 0.2s;
}
.modal-overlay.open { opacity: 1; pointer-events: auto; }
.modal {
  background: var(--bg-elevated);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-xl);
  padding: var(--sp-6);
  width: 90%; max-width: 560px;
  max-height: 85vh; overflow-y: auto;
  box-shadow: var(--shadow-lg);
  transform: scale(0.95); transition: transform 0.2s;
}
.modal-overlay.open .modal { transform: scale(1); }
.modal-header {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: var(--sp-5);
}
.modal-title { font-size: 17px; font-weight: 700; }
.modal-close {
  width: 30px; height: 30px; border-radius: var(--r-md);
  border: none; background: transparent; color: var(--text-tertiary);
  cursor: pointer; font-size: 18px;
  display: grid; place-items: center;
  transition: all 0.15s;
}
.modal-close:hover { background: var(--bg-hover); color: var(--text-primary); }
.modal-footer {
  display: flex; justify-content: flex-end; gap: var(--sp-3);
  margin-top: var(--sp-6); padding-top: var(--sp-4);
  border-top: 1px solid var(--border);
}

/* ── Tabs ── */
.tabs {
  display: flex; gap: 0; border-bottom: 1px solid var(--border);
  margin-bottom: var(--sp-5);
}
.tab {
  padding: var(--sp-3) var(--sp-5);
  font-size: 13px; font-weight: 600;
  color: var(--text-tertiary);
  cursor: pointer; border: none; background: none;
  border-bottom: 2px solid transparent;
  transition: all 0.15s;
  font-family: var(--font);
}
.tab:hover { color: var(--text-secondary); }
.tab.active { color: var(--accent); border-bottom-color: var(--accent); }

/* ── Dropzone ── */
.dropzone {
  border: 2px dashed var(--border-strong);
  border-radius: var(--r-lg);
  padding: var(--sp-10) var(--sp-6);
  text-align: center;
  cursor: pointer;
  transition: all 0.2s;
}
.dropzone:hover, .dropzone.dragover {
  border-color: var(--accent);
  background: var(--accent-subtle);
}
.dropzone-icon { font-size: 36px; margin-bottom: var(--sp-3); }
.dropzone-text { font-size: 14px; color: var(--text-secondary); font-weight: 500; }
.dropzone-hint { font-size: 12px; color: var(--text-tertiary); margin-top: var(--sp-1); }

/* ── Empty State ── */
.empty-state {
  text-align: center; padding: var(--sp-16) var(--sp-6);
}
.empty-state-icon { font-size: 48px; margin-bottom: var(--sp-4); opacity: 0.5; }
.empty-state-title { font-size: 16px; font-weight: 700; margin-bottom: var(--sp-2); }
.empty-state-desc { font-size: 13px; color: var(--text-tertiary); max-width: 360px; margin: 0 auto var(--sp-5); }

/* ── Activity Feed ── */
.activity-item {
  display: flex; gap: var(--sp-3); padding: var(--sp-3) 0;
  border-bottom: 1px solid var(--border);
  /* Without this, flex defaults to align-items:stretch and any direct child —
     notably a status badge with border-radius:999px — is stretched to the full
     row height, turning it into a tall blob whenever the text wraps. */
  align-items: flex-start;
}
.activity-item:last-child { border-bottom: none; }
/* Badges sit alongside multi-line text, so centre them against the whole row
   and stop them being squeezed on narrow viewports. */
.activity-item > .badge-status { align-self: center; flex-shrink: 0; }
.activity-dot {
  width: 8px; height: 8px; border-radius: 50%;
  margin-top: 5px; flex-shrink: 0;
}
.activity-dot.upload { background: var(--accent); }
.activity-dot.review { background: var(--warning); }
.activity-dot.approved { background: var(--success); }
.activity-dot.transmittal { background: var(--purple); }
.activity-text { font-size: 13px; color: var(--text-secondary); }
.activity-text strong { color: var(--text-primary); font-weight: 600; }
.activity-time { font-size: 11px; color: var(--text-tertiary); margin-top: 2px; }

/* ── Grid Helpers ── */
.grid { display: grid; gap: var(--sp-5); }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }
.grid-auto { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }

/* ── Flex Helpers ── */
.flex { display: flex; }
.flex-col { flex-direction: column; }
.flex-wrap { flex-wrap: wrap; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.gap-2 { gap: var(--sp-2); }
.gap-3 { gap: var(--sp-3); }
.gap-4 { gap: var(--sp-4); }
.gap-5 { gap: var(--sp-5); }

/* ── Spacing Helpers ── */
.mt-4 { margin-top: var(--sp-4); }
.mt-6 { margin-top: var(--sp-6); }
.mb-4 { margin-bottom: var(--sp-4); }
.mb-6 { margin-bottom: var(--sp-6); }

/* ── Text Helpers ── */
.text-sm { font-size: 12px; }
.text-xs { font-size: 11px; }
.text-muted { color: var(--text-tertiary); }
.text-accent { color: var(--accent); }
.text-success { color: var(--success); }
.text-warning { color: var(--warning); }
.text-danger { color: var(--danger); }
.font-mono { font-family: var(--font-mono); }

/* ── Page Header ── */
.page-header {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: var(--sp-6);
  flex-wrap: wrap; gap: var(--sp-3);
}
.page-title { font-size: 22px; font-weight: 800; }
.page-desc { font-size: 13px; color: var(--text-tertiary); margin-top: 2px; }

/* ── Login Page ── */
.login-page {
  min-height: 100vh;
  display: flex; align-items: center; justify-content: center;
  background:
    radial-gradient(ellipse 80% 60% at 20% 10%, rgba(30, 64, 175, 0.15), transparent),
    radial-gradient(ellipse 60% 50% at 80% 80%, rgba(124, 58, 237, 0.10), transparent),
    var(--bg-base);
}
.login-card {
  background: var(--bg-elevated);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-xl);
  padding: var(--sp-10);
  width: 100%; max-width: 400px;
  box-shadow: var(--shadow-lg);
}
.login-logo {
  display: flex; align-items: center; gap: var(--sp-3);
  justify-content: center; margin-bottom: var(--sp-8);
}
.login-logo-icon {
  width: 42px; height: 42px; border-radius: 11px;
  background: linear-gradient(135deg, var(--gradient-start), var(--gradient-end));
  display: grid; place-items: center;
  font-weight: 900; font-size: 15px; color: #fff;
}
.login-logo-text { font-weight: 800; font-size: 20px; }
.login-title { text-align: center; font-size: 17px; font-weight: 700; margin-bottom: var(--sp-1); }
.login-subtitle { text-align: center; font-size: 13px; color: var(--text-tertiary); margin-bottom: var(--sp-6); }
.login-form .btn { width: 100%; justify-content: center; margin-top: var(--sp-4); padding: var(--sp-3); }
.login-footer { text-align: center; margin-top: var(--sp-5); font-size: 12px; color: var(--text-tertiary); }
.login-footer a { color: var(--accent); font-weight: 600; }

/* ══════════════════════════════════════════════════════════
   COMPONENTS — Phase 1 completion
   ══════════════════════════════════════════════════════════ */

/* ── Toasts ── */
.toast-container {
  position: fixed; bottom: var(--sp-6); right: var(--sp-6);
  z-index: 2000; display: flex; flex-direction: column-reverse;
  gap: var(--sp-3); pointer-events: none;
}
.toast {
  display: flex; align-items: center; gap: var(--sp-3);
  background: var(--bg-elevated);
  border: 1px solid var(--border-strong);
  border-left: 3px solid var(--accent);
  border-radius: var(--r-md);
  padding: var(--sp-3) var(--sp-5);
  box-shadow: var(--shadow-lg);
  font-size: 13px; font-weight: 500;
  min-width: 260px; max-width: 420px;
  pointer-events: auto;
  animation: toast-in 0.25s ease-out;
}
.toast.success { border-left-color: var(--success); }
.toast.warning { border-left-color: var(--warning); }
.toast.danger  { border-left-color: var(--danger); }
.toast.leaving { animation: toast-out 0.2s ease-in forwards; }
@keyframes toast-in  { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
@keyframes toast-out { to { opacity: 0; transform: translateX(20px); } }

/* ── Checkboxes / selectable tables ── */
.checkbox {
  appearance: none; -webkit-appearance: none;
  width: 16px; height: 16px; flex-shrink: 0;
  border: 1.5px solid var(--border-strong);
  border-radius: 4px; background: var(--bg-input);
  cursor: pointer; position: relative;
  transition: all 0.15s; vertical-align: middle;
}
.checkbox:hover { border-color: var(--accent); }
.checkbox:checked { background: var(--accent); border-color: var(--accent); }
.checkbox:checked::after {
  content: '✓'; position: absolute; inset: 0;
  display: grid; place-items: center;
  color: #fff; font-size: 11px; font-weight: 900; line-height: 1;
}
th.col-check, td.col-check { width: 40px; padding-right: 0; cursor: default; }

/* ── Selection bar ── */
.selection-bar {
  display: flex; align-items: center; gap: var(--sp-4);
  padding: var(--sp-3) var(--sp-5);
  background: var(--accent-subtle);
  border-bottom: 1px solid var(--border-accent);
  font-size: 13px; font-weight: 600; color: var(--accent);
}
.selection-bar .spacer { flex: 1; }

/* ── Stepper ── */
.stepper { display: flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-6); flex-wrap: wrap; }
.step {
  display: flex; align-items: center; gap: var(--sp-2);
  font-size: 12px; font-weight: 600; color: var(--text-tertiary);
}
.step-num {
  width: 22px; height: 22px; border-radius: var(--r-full);
  display: grid; place-items: center;
  background: var(--border); color: var(--text-tertiary);
  font-size: 11px; font-weight: 700;
}
.step.active { color: var(--accent); }
.step.active .step-num { background: var(--accent); color: #fff; }
.step.done { color: var(--success); }
.step.done .step-num { background: var(--success-subtle); color: var(--success); }
.step-divider { width: 28px; height: 1px; background: var(--border-strong); }

/* ── Chips ── */
.chip {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  padding: 3px 6px 3px 10px; border-radius: var(--r-full);
  background: var(--accent-subtle); color: var(--accent);
  font-size: 11px; font-weight: 600;
}
.chip button {
  border: none; background: none; cursor: pointer;
  color: inherit; opacity: 0.6; font-size: 13px; line-height: 1;
  padding: 0 2px; font-family: var(--font);
}
.chip button:hover { opacity: 1; }

/* ── Threaded conversation ── */
.thread { display: flex; flex-direction: column; gap: var(--sp-4); }
.thread-message {
  display: flex; gap: var(--sp-4);
  padding: var(--sp-4);
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
}
.thread-message.mine { border-color: var(--border-accent); background: var(--accent-subtle); }
.thread-avatar {
  width: 34px; height: 34px; border-radius: var(--r-full);
  background: var(--accent-subtle); color: var(--accent);
  display: grid; place-items: center;
  font-weight: 700; font-size: 12px; flex-shrink: 0;
}
.thread-content { flex: 1; min-width: 0; }
.thread-meta {
  display: flex; align-items: baseline; gap: var(--sp-3);
  margin-bottom: var(--sp-2); flex-wrap: wrap;
}
.thread-author { font-size: 13px; font-weight: 700; }
.thread-org { font-size: 11px; color: var(--text-tertiary); }
.thread-time { font-size: 11px; color: var(--text-tertiary); margin-left: auto; }
.thread-body { font-size: 13px; line-height: 1.65; color: var(--text-secondary); white-space: pre-wrap; }
.thread-attachments { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-3); }
.attachment {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-1) var(--sp-3);
  background: var(--bg-input); border: 1px solid var(--border);
  border-radius: var(--r-sm);
  font-size: 11px; font-family: var(--font-mono); color: var(--text-secondary);
  cursor: pointer;
}
.attachment:hover { border-color: var(--border-accent); color: var(--text-primary); }

/* ── Timeline (workflow) ── */
.timeline { display: flex; flex-direction: column; gap: 0; }
.timeline-item { display: flex; gap: var(--sp-4); position: relative; padding-bottom: var(--sp-5); }
.timeline-item:last-child { padding-bottom: 0; }
.timeline-item::before {
  content: ''; position: absolute; left: 10px; top: 22px; bottom: 0;
  width: 1px; background: var(--border-strong);
}
.timeline-item:last-child::before { display: none; }
.timeline-dot {
  width: 21px; height: 21px; border-radius: var(--r-full);
  display: grid; place-items: center; flex-shrink: 0;
  font-size: 10px; font-weight: 700; z-index: 1;
  background: var(--border); color: var(--text-tertiary);
}
.timeline-dot.done { background: var(--success-subtle); color: var(--success); }
.timeline-dot.active { background: var(--accent); color: #fff; }
.timeline-title { font-size: 13px; font-weight: 600; }
.timeline-desc { font-size: 11px; color: var(--text-tertiary); margin-top: 2px; }

/* ── Definition rows ── */
.def-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-4); padding: var(--sp-2) 0;
}
.def-row + .def-row { border-top: 1px solid var(--border); }
.def-label { font-size: 12px; color: var(--text-tertiary); flex-shrink: 0; }
.def-value { font-size: 12px; font-weight: 600; text-align: right; word-break: break-word; }

/* ── Priority badges ── */
.badge-status.critical { background: var(--danger-subtle); color: var(--danger); }
.badge-status.high { background: var(--warning-subtle); color: var(--warning); }
.badge-status.medium { background: var(--info-subtle); color: var(--info); }
.badge-status.low { background: var(--border); color: var(--text-secondary); }
.badge-status.purple { background: var(--purple-subtle); color: var(--purple); }

/* ── Misc helpers ── */
.mt-2 { margin-top: var(--sp-2); }
.mt-3 { margin-top: var(--sp-3); }
.mt-5 { margin-top: var(--sp-5); }
.mb-2 { margin-bottom: var(--sp-2); }
.mb-3 { margin-bottom: var(--sp-3); }
.mb-5 { margin-bottom: var(--sp-5); }
.w-full { width: 100%; }
.text-right { text-align: right; }
.text-center { text-align: center; }
.justify-center { justify-content: center; }
.items-start { align-items: flex-start; }
.flex-1 { flex: 1; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.clickable { cursor: pointer; }
.divider { height: 1px; background: var(--border); margin: var(--sp-5) 0; }
.hint { font-size: 11px; color: var(--text-tertiary); margin-top: var(--sp-1); }
.field-error { border-color: var(--danger) !important; }
.error-text { font-size: 11px; color: var(--danger); margin-top: var(--sp-1); }

/* ── Mail detail layout ── */
.mail-layout { grid-template-columns: minmax(0, 1fr) 300px; }

/* ── Loading skeletons ── */
/* Shown only when a render takes longer than ~150ms, so fast local
   reads never flash a placeholder. */
.skeleton-page { padding: var(--sp-2) 0; }
.skeleton {
  background: linear-gradient(90deg,
    var(--bg-elevated) 25%, var(--bg-hover) 37%, var(--bg-elevated) 63%);
  background-size: 400% 100%;
  border-radius: var(--r-md);
  animation: skeleton-sweep 1.4s ease-in-out infinite;
}
.skeleton-title { height: 26px; width: 260px; margin-bottom: var(--sp-3); }
.skeleton-line  { height: 13px; margin-bottom: var(--sp-2); }
.skeleton-block { height: 120px; margin-bottom: var(--sp-4); }
@keyframes skeleton-sweep {
  from { background-position: 100% 50%; }
  to   { background-position: 0 50%; }
}
@media (prefers-reduced-motion: reduce) {
  .skeleton { animation: none; }
}

/* ── Upload progress ── */
/* A 50MB drawing on a slow connection takes long enough that silence
   reads as a hung page. Determinate while the bytes are moving, since
   the browser reports a total; indeterminate while hashing and while
   the server verifies, where there is no meaningful fraction. */
.progress-track {
  height: 6px;
  border-radius: 999px;
  background: var(--bg-hover);
  overflow: hidden;
}
.progress-bar {
  height: 100%;
  width: 0;
  border-radius: 999px;
  background: var(--accent);
  transition: width 160ms ease-out;
}
.progress-indeterminate {
  width: 35%;
  animation: progress-slide 1.1s ease-in-out infinite;
}
@keyframes progress-slide {
  from { transform: translateX(-100%); }
  to   { transform: translateX(340%); }
}
@media (prefers-reduced-motion: reduce) {
  .progress-indeterminate { animation: none; width: 100%; opacity: 0.55; }
  .progress-bar { transition: none; }
}

/* ── Mobile navigation ── */
/* Hidden on desktop, where the sidebar is always present. */
.sidebar-toggle {
  display: none;
  width: 34px; height: 34px; flex-shrink: 0;
  border: none; background: transparent;
  color: var(--text-secondary); font-size: 18px;
  border-radius: var(--r-md); cursor: pointer;
  align-items: center; justify-content: center;
}
.sidebar-toggle:hover { background: var(--bg-hover); color: var(--text-primary); }

.sidebar-backdrop {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(0, 0, 0, 0.5);
  opacity: 0; pointer-events: none;
  transition: opacity 0.2s;
}

/* ── Responsive ── */
@media (max-width: 1024px) {
  .grid-4 { grid-template-columns: repeat(2, 1fr); }
  .mail-layout { grid-template-columns: 1fr; }
}

@media (max-width: 768px) {
  .app-layout { grid-template-columns: 1fr; grid-template-areas: "topbar" "main"; }
  .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
  .table-toolbar { flex-direction: column; align-items: stretch; }
  .toast-container { left: var(--sp-4); right: var(--sp-4); bottom: var(--sp-4); }
  .toast { min-width: 0; max-width: none; }

  .sidebar-toggle { display: inline-flex; }

  /* The sidebar becomes a drawer rather than disappearing entirely,
     so navigation is still reachable on a phone. */
  .sidebar {
    position: fixed; top: 0; left: 0; bottom: 0; z-index: 100;
    width: var(--sidebar-width); height: 100vh;
    transform: translateX(-100%);
    transition: transform 0.22s ease;
    box-shadow: var(--shadow-lg);
  }
  body.sidebar-open .sidebar { transform: none; }
  body.sidebar-open .sidebar-backdrop { opacity: 1; pointer-events: auto; }

  /* Keep the topbar usable once the hamburger takes space. */
  .topbar { padding: 0 var(--sp-4); gap: var(--sp-3); }
  .topbar-actions .search-input { display: none; }
  .page-header { align-items: flex-start; }
}

@media (max-width: 480px) {
  .page-title { font-size: 19px; }
  .main-content { padding: var(--sp-4); }
}

/* ══════════════════════════════════════════════════════════
   DOCUMENT VIEWER — Phase 3b
   The PDF renders on a canvas; markup lives in an SVG overlay
   whose viewBox is the scale-1 page box, so stored coordinates
   land in the same place at every zoom level.
   ══════════════════════════════════════════════════════════ */

.viewer-layout {
  display: grid;
  grid-template-columns: 1fr 320px;
  gap: var(--sp-5);
  align-items: start;
}

.viewer-rev-tag {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-secondary);
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  padding: 2px 8px;
  margin-left: var(--sp-2);
  vertical-align: middle;
}

.viewer-main {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow: hidden;
}

.viewer-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--border);
  background: var(--bg-surface);
}

.viewer-tool-group {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}

.viewer-divider {
  width: 1px;
  height: 20px;
  background: var(--border);
  margin: 0 var(--sp-2);
}

.tool-btn.active {
  background: var(--accent-subtle);
  border-color: var(--accent);
  color: var(--accent);
}

.viewer-swatch {
  width: 18px;
  height: 18px;
  border-radius: var(--r-full);
  border: 2px solid transparent;
  cursor: pointer;
  padding: 0;
}
.viewer-swatch.active {
  border-color: var(--text-primary);
  box-shadow: 0 0 0 2px var(--bg-card);
}

.viewer-page-label {
  font-size: 12px;
  color: var(--text-secondary);
  min-width: 90px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.viewer-stage {
  overflow: auto;
  max-height: calc(100vh - var(--topbar-height) - 210px);
  min-height: 320px;
  padding: var(--sp-5);
  background: var(--bg-base);
  display: flex;
  justify-content: safe center;
}

.viewer-loading {
  align-self: center;
  color: var(--text-tertiary);
  font-size: 13px;
  padding: var(--sp-8) 0;
}

.viewer-canvas-wrap {
  position: relative;
  box-shadow: var(--shadow-lg);
  align-self: flex-start;
  line-height: 0;
  background: #fff;
}
.viewer-canvas-wrap[data-tool="note"],
.viewer-canvas-wrap[data-tool="rect"],
.viewer-canvas-wrap[data-tool="ink"] { cursor: crosshair; }

.viewer-overlay {
  position: absolute;
  inset: 0;
  touch-action: none;
}
.viewer-ann { cursor: pointer; }
.viewer-ann.resolved { opacity: 0.35; }
.viewer-ann.selected { filter: drop-shadow(0 0 3px currentColor); }
.viewer-pin text { pointer-events: none; user-select: none; }

/* ── Markup panel ── */

.markup-panel {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow: hidden;
  position: sticky;
  top: var(--sp-5);
  max-height: calc(100vh - var(--topbar-height) - 140px);
  display: flex;
  flex-direction: column;
}

.markup-panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--sp-4) var(--sp-5);
  border-bottom: 1px solid var(--border);
  font-weight: 700;
  font-size: 13px;
}

.markup-count {
  font-size: 11px;
  font-weight: 500;
  color: var(--text-tertiary);
}

.markup-list {
  overflow-y: auto;
  flex: 1;
}

.markup-item {
  border-bottom: 1px solid var(--border);
  padding: var(--sp-3) var(--sp-4);
}
.markup-item.selected { background: var(--accent-subtle); }
.markup-item.resolved .markup-body { opacity: 0.55; }

.markup-item-main {
  display: flex;
  gap: var(--sp-3);
  cursor: pointer;
}

.markup-kind { font-size: 14px; line-height: 1.4; }

.markup-body {
  font-size: 13px;
  line-height: 1.45;
  overflow-wrap: anywhere;
}

.markup-meta {
  font-size: 11px;
  color: var(--text-tertiary);
  margin-top: 2px;
}

.markup-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--sp-1);
  margin-top: var(--sp-2);
}

.markup-thread {
  margin-top: var(--sp-2);
  border-top: 1px dashed var(--border);
  padding-top: var(--sp-2);
}

.markup-comment {
  font-size: 12px;
  line-height: 1.45;
  padding: var(--sp-2) 0;
  overflow-wrap: anywhere;
}

.markup-reply {
  display: flex;
  gap: var(--sp-2);
  margin-top: var(--sp-2);
}
.markup-reply .input { flex: 1; font-size: 12px; }

@media (max-width: 1024px) {
  .viewer-layout { grid-template-columns: 1fr; }
  .markup-panel { position: static; max-height: 380px; }
}

/* ── Revu-class markup additions (3b.2) ── */

.viewer-tool-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--sp-2);
  width: 100%;
}
.viewer-tool-row + .viewer-tool-row { margin-top: var(--sp-2); }

.viewer-toolbar { flex-direction: column; align-items: flex-start; }

.stroke-btn .stroke-sample {
  display: inline-block;
  width: 16px;
  background: currentColor;
  border-radius: 2px;
  vertical-align: middle;
}
.stroke-btn.active, .opacity-btn.active {
  background: var(--accent-subtle);
  border-color: var(--accent);
  color: var(--accent);
}
.opacity-btn { font-size: 10px; padding: 4px 6px; }

.viewer-stamp-select { width: 120px; font-size: 11px; }

.viewer-handle {
  fill: #fff;
  stroke: var(--accent, #6366f1);
  stroke-width: 1.5;
  cursor: nwse-resize;
}
.viewer-fo { pointer-events: none; }

.markup-filters {
  display: flex;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--border);
}
.markup-filters .select { flex: 1; font-size: 11px; padding: 4px 6px; min-width: 0; }

.markup-panel-footer {
  display: flex;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4);
  border-top: 1px solid var(--border);
}
.markup-panel-footer .btn { flex: 1; justify-content: center; }

.markup-status {
  display: inline-block;
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  padding: 1px 6px;
  border-radius: var(--r-full);
  margin-right: 4px;
}
.markup-status.st-open     { background: var(--info-subtle);    color: var(--info); }
.markup-status.st-answered { background: var(--warning-subtle); color: var(--warning); }
.markup-status.st-accepted { background: var(--success-subtle); color: var(--success); }
.markup-status.st-rejected { background: var(--danger-subtle);  color: var(--danger); }
.markup-status.st-closed   { background: var(--bg-elevated);    color: var(--text-tertiary); }

.markup-status-select {
  font-size: 10px;
  padding: 2px 4px;
  width: auto;
}

/* Lobby stat cards that lead somewhere behave like buttons. */
.stat-card.clickable { cursor: pointer; transition: transform 0.12s ease, border-color 0.12s ease; }
.stat-card.clickable:hover { transform: translateY(-2px); border-color: var(--border-strong); }
.stat-card.clickable:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ══════════════════════════════════════════════════════════
   TEXT LAYER, SEARCH AND LAYERS (3b.3)

   The text layer is PDF.js's: transparent spans positioned in
   percentages, each carrying its own --font-height, scaled as a
   group by --total-scale-factor on the container. Zooming
   therefore changes one variable rather than re-laying out
   every span.
   ══════════════════════════════════════════════════════════ */

.viewer-text-layer {
  position: absolute;
  inset: 0;
  overflow: clip;
  line-height: 1;
  text-align: initial;
  text-size-adjust: none;
  forced-color-adjust: none;
  transform-origin: 0 0;
  caret-color: CanvasText;
  z-index: 1;
  /* Only selectable in select / text-highlight modes; in drawing
     modes the SVG above must receive the drag instead. */
  pointer-events: none;
  user-select: none;
}
.viewer-canvas-wrap[data-mode="select"] .viewer-text-layer {
  pointer-events: auto;
  user-select: text;
}

.viewer-text-layer span,
.viewer-text-layer br {
  position: absolute;
  color: transparent;
  white-space: pre;
  cursor: text;
  transform-origin: 0% 0%;
}
.viewer-text-layer span {
  font-size: calc(var(--font-height) * var(--total-scale-factor, 1));
  transform: scaleX(var(--scale-x, 1));
}
.viewer-text-layer ::selection { background: rgba(58, 123, 232, 0.35); }

/* The overlay sits above the text layer. In selectable modes it is
   pointer-transparent so clicks reach the words, but the shapes
   themselves stay clickable so markup can still be selected. */
.viewer-overlay { z-index: 2; }
.viewer-canvas-wrap[data-mode="select"] .viewer-overlay { pointer-events: none; }
.viewer-canvas-wrap[data-mode="select"] .viewer-overlay .viewer-ann,
.viewer-canvas-wrap[data-mode="select"] .viewer-overlay .viewer-handle { pointer-events: auto; }

.viewer-canvas-wrap[data-tool="draw"] .viewer-text-layer { cursor: crosshair; }

/* ── Search ── */

.viewer-search .input { width: 170px; font-size: 12px; padding: 4px 8px; }
.viewer-search-count {
  font-size: 11px;
  color: var(--text-tertiary);
  min-width: 40px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.viewer-search-hit {
  fill: var(--warning, #e8a33a);
  fill-opacity: 0.35;
  stroke: none;
}
.viewer-search-hit.current {
  fill-opacity: 0.6;
  stroke: var(--warning, #e8a33a);
  stroke-width: 1;
}

/* ── Layer panel ── */

.markup-layers:not(:empty) {
  border-bottom: 1px solid var(--border);
  padding: var(--sp-3) var(--sp-4);
}
.markup-layers-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--text-tertiary);
  margin-bottom: var(--sp-2);
}
.markup-layer {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: 12px;
  padding: 2px 0;
}
.markup-layer.hidden .markup-layer-name { opacity: 0.45; text-decoration: line-through; }
.markup-layer-toggle {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex: 1;
  min-width: 0;
  cursor: pointer;
}
.markup-layer-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.markup-layer-count { font-size: 10px; color: var(--text-tertiary); white-space: nowrap; }

.markup-quote { font-style: italic; }

/* ══════════════════════════════════════════════════════════
   WORKFLOW ENGINE (3c)
   ══════════════════════════════════════════════════════════ */

.badge.badge-urgent { background: var(--danger); color: #fff; }

tr.row-overdue td { background: var(--danger-subtle); }
.text-xs { font-size: 10px; }

/* ── The workflow panel on a document ── */

.workflow-active-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
  margin-bottom: var(--sp-3);
  font-size: 13px;
}

.workflow-outcome {
  font-size: 12px;
  line-height: 1.5;
  padding: var(--sp-3);
  border-radius: var(--r-md);
  border: 1px solid var(--border);
}
.workflow-outcome.approved  { background: var(--success-subtle); border-color: var(--success); }
.workflow-outcome.rejected  { background: var(--danger-subtle);  border-color: var(--danger); }
.workflow-outcome.cancelled { background: var(--bg-elevated); }

.workflow-trail {
  margin-top: var(--sp-4);
  border-top: 1px solid var(--border);
  padding-top: var(--sp-3);
  max-height: 260px;
  overflow-y: auto;
}
.workflow-trail-item {
  display: flex;
  gap: var(--sp-3);
  padding: var(--sp-2) 0;
}
.workflow-trail-mark {
  width: 20px; height: 20px;
  border-radius: var(--r-full);
  display: flex; align-items: center; justify-content: center;
  font-size: 10px;
  flex-shrink: 0;
  background: var(--bg-elevated);
  color: var(--text-secondary);
}
.workflow-trail-mark.approve { background: var(--success-subtle); color: var(--success); }
.workflow-trail-mark.reject  { background: var(--danger-subtle);  color: var(--danger); }
.workflow-trail-mark.auto    { background: var(--info-subtle);    color: var(--info); }
.workflow-trail-comment {
  font-size: 12px;
  color: var(--text-secondary);
  line-height: 1.45;
  margin-top: 2px;
  overflow-wrap: anywhere;
}

/* ── Template list ── */

.workflow-row {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-4);
  padding: var(--sp-4) 0;
  border-bottom: 1px solid var(--border);
}
.workflow-row:last-child { border-bottom: none; }

.workflow-steps-inline {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin-top: var(--sp-2);
}
.workflow-chip {
  font-size: 11px;
  padding: 3px 8px;
  border-radius: var(--r-sm);
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  white-space: nowrap;
}
.workflow-arrow { color: var(--text-tertiary); font-size: 12px; }

/* ── The step editor ── */

.modal.modal-wide { max-width: 860px; width: 92vw; }

.workflow-editor-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: var(--sp-5) 0 var(--sp-3);
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--text-tertiary);
}

.workflow-default-toggle,
.workflow-step-transmittal {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: 12px;
  cursor: pointer;
  margin-top: var(--sp-2);
}

.workflow-step-card {
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: var(--sp-3) var(--sp-4);
  margin-bottom: var(--sp-3);
  background: var(--bg-surface);
}
.workflow-step-head {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}
.workflow-step-number {
  width: 22px; height: 22px;
  border-radius: var(--r-full);
  background: var(--accent-subtle);
  color: var(--accent);
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700;
  flex-shrink: 0;
}
.workflow-step-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-3);
  margin-top: var(--sp-3);
}
.workflow-step-grid .input-group { margin-bottom: 0; }
.workflow-step-grid label { font-size: 10px; }

@media (max-width: 768px) {
  .workflow-step-grid { grid-template-columns: 1fr 1fr; }
  .modal.modal-wide { width: 96vw; }
  .workflow-row { flex-direction: column; gap: var(--sp-3); }
}

/* ── Notification preferences (3d) ── */

.notify-toggle {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  cursor: pointer;
  font-size: 13px;
}
.notify-toggle input { margin-top: 3px; flex-shrink: 0; }
.notify-toggle input:disabled { cursor: not-allowed; }
.notify-toggle .hint { display: block; margin-top: 2px; }
.text-warning { color: var(--warning); }

.notify-list { max-height: 220px; overflow-y: auto; }
.notify-item {
  display: flex;
  gap: var(--sp-3);
  padding: var(--sp-2) 0;
  border-bottom: 1px solid var(--border);
}
.notify-item:last-child { border-bottom: none; }
.notify-state {
  width: 18px; height: 18px; flex-shrink: 0;
  border-radius: var(--r-full);
  display: flex; align-items: center; justify-content: center;
  font-size: 10px;
  background: var(--bg-elevated);
  color: var(--text-tertiary);
}
.notify-state.sent    { background: var(--success-subtle); color: var(--success); }
.notify-state.failed  { background: var(--danger-subtle);  color: var(--danger); }
.notify-state.pending { background: var(--info-subtle);    color: var(--info); }

/* ══════════════════════════════════════════════════════════
   REPORTS

   Two layouts: a card picker for the standard registers, and a
   three-column builder — palette, canvas, live preview.

   The drag affordances are deliberately visible at rest rather than
   on hover. A drag target nobody can see is a drag target nobody
   uses, and this is the one screen where the interaction is not
   guessable from the layout.
   ══════════════════════════════════════════════════════════ */

.report-picker {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 12px;
  margin-bottom: 20px;
}

.report-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 16px;
  text-align: left;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 12px;
  cursor: pointer;
  transition: border-color .15s ease, transform .15s ease;
}
.report-card:hover { border-color: var(--border-strong); transform: translateY(-1px); }
.report-card.active { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent-glow); }
.report-card-title { font-weight: 600; color: var(--text-primary); }
.report-card-desc  { font-size: 12px; line-height: 1.5; color: var(--text-secondary); }

.report-controls {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 16px;
  flex-wrap: wrap;
}
.report-controls label { font-size: 13px; color: var(--text-secondary); }

/* The header block. Present on every report, because a report that
   does not say what it covers is a spreadsheet. */
.report-meta {
  display: flex;
  justify-content: space-between;
  gap: 24px;
  padding: 16px;
  margin-bottom: 12px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 12px;
  flex-wrap: wrap;
}
.report-meta-slim { padding: 10px 16px; }
.report-title { margin: 0 0 4px; font-size: 17px; }
.report-scope { margin: 0; font-size: 12px; line-height: 1.6; color: var(--text-secondary); max-width: 70ch; }
.report-meta-side { display: flex; gap: 18px; align-items: center; font-size: 12px; flex-wrap: wrap; }
.report-meta-side .k { display: block; color: var(--text-tertiary); font-size: 11px; }

.report-bands { display: flex; gap: 12px; margin-bottom: 14px; flex-wrap: wrap; }
.band {
  display: flex; flex-direction: column; gap: 2px;
  padding: 10px 18px; border-radius: 10px;
  border: 1px solid var(--border); background: var(--bg-card);
}
.band b { font-size: 22px; line-height: 1; }
.band span { font-size: 11px; color: var(--text-secondary); }
.band-warn b { color: var(--warning); }
.band-mid  b { color: #fb923c; }
.band-bad  b { color: var(--danger); }

/* ── The builder ─────────────────────────────────────────── */

.builder {
  display: grid;
  grid-template-columns: 260px 1fr;
  gap: 16px;
  align-items: start;
}

.builder-palette {
  position: sticky;
  top: 12px;
  padding: 14px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 12px;
}
.palette-head { margin: 16px 0 4px; font-size: 12px; text-transform: uppercase;
                letter-spacing: .06em; color: var(--text-tertiary); }
.palette-list { display: flex; flex-direction: column; gap: 6px; margin-top: 8px;
                max-height: 46vh; overflow-y: auto; }

.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  font-size: 12px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--bg-elevated);
  color: var(--text-primary);
}
.chip-draggable { cursor: grab; user-select: none; }
.chip-draggable:hover { border-color: var(--accent); }
.chip-draggable:active { cursor: grabbing; }
.chip-draggable.dragging { opacity: .4; }
/* Already in the report — still draggable into Filters or Group by,
   so it is dimmed rather than disabled. */
.chip-used { opacity: .5; }
.chip-type { font-size: 10px; width: 14px; text-align: center; color: var(--text-tertiary); }

.chip-column { background: var(--bg-surface); border-color: var(--border-strong); }
.chip-group  { background: rgba(139, 92, 246, .12); border-color: rgba(139, 92, 246, .35); }

.chip-select {
  font-size: 11px; padding: 1px 4px;
  background: var(--bg-base); color: var(--text-secondary);
  border: 1px solid var(--border); border-radius: 5px;
}
.chip-x, .chip-sort {
  border: none; background: none; cursor: pointer; padding: 0 2px;
  color: var(--text-tertiary); font-size: 13px; line-height: 1;
}
.chip-x:hover { color: var(--danger); }
.chip-sort:hover, .chip-sort.active { color: var(--accent); }

.builder-canvas { display: flex; flex-direction: column; gap: 12px; }

.drop-zone {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  min-height: 68px;
  padding: 12px 14px;
  border: 1.5px dashed var(--border-strong);
  border-radius: 12px;
  background: var(--bg-card);
  transition: border-color .12s ease, background .12s ease;
}
.drop-zone h4 {
  width: 100%; margin: 0 0 2px;
  font-size: 12px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--text-tertiary);
}
.drop-zone h4 .hint { text-transform: none; letter-spacing: 0; margin-left: 6px; }
.drop-zone.drop-over { border-color: var(--accent); background: var(--accent-glow); }
.drop-hint { margin: 0; font-size: 12px; color: var(--text-tertiary); }

.filter-row { display: flex; align-items: center; gap: 8px; width: 100%; flex-wrap: wrap; }
.filter-field { font-size: 12px; font-weight: 600; min-width: 120px; }
.filter-row .input { max-width: 220px; }

.builder-errors {
  padding: 12px 14px;
  border: 1px solid rgba(239, 68, 68, .35);
  background: rgba(239, 68, 68, .08);
  border-radius: 10px;
  font-size: 12.5px;
}
.builder-errors ul { margin: 6px 0 0; padding-left: 18px; }
.builder-errors li { margin: 3px 0; color: var(--text-secondary); }

.builder-actions { display: flex; gap: 8px; justify-content: flex-end; }

/* ── Saved reports ───────────────────────────────────────── */

.saved-list { display: flex; flex-direction: column; gap: 10px; }
.saved-report {
  display: flex; justify-content: space-between; gap: 16px;
  padding: 14px 16px;
  background: var(--bg-card); border: 1px solid var(--border); border-radius: 12px;
  flex-wrap: wrap;
}
.saved-main h3 { margin: 0 0 4px; font-size: 15px; display: flex; align-items: center; gap: 8px; }
.saved-desc    { margin: 0 0 4px; font-size: 13px; color: var(--text-secondary); }
.saved-summary { margin: 0 0 4px; font-size: 12px; color: var(--text-tertiary); max-width: 70ch; }
.saved-actions { display: flex; gap: 6px; align-items: flex-start; flex-wrap: wrap; }

.table td.num, .table th.num { text-align: right; font-variant-numeric: tabular-nums; }
.table-total td { border-top: 2px solid var(--border-strong); font-weight: 600; }
.hint.warn { color: var(--warning); }

/* Below a laptop the palette stacks above the canvas rather than
   sitting beside it. Dragging still works; the fallback click-to-add
   matters more here, because dragging on a touch screen does not. */
@media (max-width: 980px) {
  .builder { grid-template-columns: 1fr; }
  .builder-palette { position: static; }
  .palette-list { max-height: 200px; flex-direction: row; flex-wrap: wrap; }
}

/* ── Scheduled delivery ──────────────────────────────────── */

.saved-schedule {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 6px 0 0;
  padding: 6px 10px;
  font-size: 12px;
  color: var(--text-secondary);
  background: rgba(59, 130, 246, .07);
  border: 1px solid var(--border-accent);
  border-radius: 8px;
}

/* The sentence the schedule reduces to. Prominent on purpose: it is
   what somebody checks against what they meant, and a schedule is a
   promise about another person's inbox. */
.schedule-summary {
  margin: 10px 0 14px;
  padding: 10px 12px;
  font-size: 13px;
  color: var(--text-primary);
  background: var(--bg-elevated);
  border-left: 3px solid var(--accent);
  border-radius: 6px;
}

.recipient-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-height: 200px;
  overflow-y: auto;
  padding: 8px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-base);
}

.form-row { display: flex; gap: 12px; flex-wrap: wrap; }
.form-row .form-group { flex: 1 1 140px; min-width: 140px; }

/* Download formats sit together so they read as one control rather
   than three unrelated buttons. */
.format-group { display: inline-flex; gap: 4px; }
.format-group .btn { padding-left: 10px; padding-right: 10px; }

/* ══════════════════════════════════════════════════════════
   SEARCH
   ══════════════════════════════════════════════════════════ */

.search-bar { display: flex; gap: 8px; margin-bottom: 6px; }
.search-bar .input { flex: 1; font-size: 15px; padding: 12px 14px; }

.search-syntax { margin: 0 0 18px; }
.search-syntax code {
  padding: 1px 6px; margin-right: 4px;
  font-size: 11px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 5px;
}

.search-coverage {
  padding: 8px 12px;
  margin-bottom: 14px;
  border-left: 3px solid var(--warning);
  background: rgba(245, 158, 11, .06);
  border-radius: 6px;
  line-height: 1.6;
}

.search-count { margin: 0 0 12px; font-size: 13px; color: var(--text-secondary); }

.search-results { display: flex; flex-direction: column; gap: 8px; }

.search-result {
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: 100%;
  padding: 14px 16px;
  text-align: left;
  cursor: pointer;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 12px;
  transition: border-color .12s ease, transform .12s ease;
}
.search-result:hover { border-color: var(--border-accent); transform: translateY(-1px); }

.search-result-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.search-result-title { font-size: 14px; color: var(--text-primary); }

/* The snippet is document text. It is escaped before rendering and
   only the highlight markers are restored — see markSafe(). */
.search-snippet {
  margin: 2px 0;
  font-size: 12.5px;
  line-height: 1.7;
  color: var(--text-secondary);
  padding-left: 10px;
  border-left: 2px solid var(--border);
}
.search-snippet mark {
  padding: 0 2px;
  color: var(--text-primary);
  background: rgba(59, 130, 246, .28);
  border-radius: 3px;
}

.search-result-meta {
  display: flex; gap: 14px; flex-wrap: wrap;
  font-size: 11.5px; color: var(--text-tertiary);
}

/* ══════════════════════════════════════════════════════════
   ROLES & PERMISSIONS
   ══════════════════════════════════════════════════════════ */

.tier-explainer {
  padding: 14px 16px;
  margin-bottom: 22px;
  font-size: 13px;
  line-height: 1.75;
  color: var(--text-secondary);
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 10px;
}
.tier-explainer b { color: var(--text-primary); }

.role-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 12px;
  margin-bottom: 26px;
}

.role-card {
  padding: 16px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 12px;
}
.role-card-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.role-card-head h4 { margin: 0; font-size: 15px; }
.role-card-desc { margin: 8px 0 6px; font-size: 12.5px; line-height: 1.6; color: var(--text-secondary); }
.role-card-actions { display: flex; gap: 6px; margin-top: 12px; flex-wrap: wrap; }

/* The tier badge is colour-coded because the tier is the thing that
   actually decides access, and it should be the first thing read. */
.badge-tier-viewer      { background: rgba(100,130,180,.15); color: var(--text-secondary); }
.badge-tier-participant { background: rgba(6,182,212,.15);   color: var(--info); }
.badge-tier-writer      { background: rgba(59,130,246,.15);  color: var(--accent); }
.badge-tier-admin       { background: rgba(139,92,246,.18);  color: var(--purple); }

/* ── The matrix ─────────────────────────────────────────────
   Three states, kept visually distinct: granted, not granted, and
   impossible for that tier. Collapsing the last two would hide the
   tier model, which is the thing somebody has to understand before
   they can design a role that works. */

.matrix td:first-child, .matrix th:first-child { text-align: left; }
.matrix-category td {
  padding-top: 14px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--text-tertiary);
  background: transparent;
}
.matrix-yes        { color: var(--success); font-weight: 700; }
.matrix-no         { color: var(--text-tertiary); }
.matrix-impossible { color: var(--border-strong); }

/* ── The editor ─────────────────────────────────────────── */

.capability-editor { max-height: 46vh; overflow-y: auto; margin-top: 8px; padding-right: 4px; }
.capability-category {
  margin: 16px 0 6px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--text-tertiary);
}
.capability-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 8px 10px;
  border-radius: 8px;
  cursor: pointer;
}
.capability-row:hover { background: var(--bg-elevated); }
.capability-row span { display: flex; flex-direction: column; gap: 2px; font-size: 13px; }
.capability-row .hint { font-size: 11.5px; }

/* Disabled rather than hidden: somebody designing a role should see
   that a permission exists and learn which tier it needs. */
.capability-impossible { opacity: .45; cursor: not-allowed; }
.capability-impossible:hover { background: transparent; }

/* ── Markup properties panel (Phase V1) ─────────────────────
   Sits above the register, describing the one selected markup.
   Everything in it is a property of that markup; the toolbar above
   the drawing sets what the NEXT one will be. Two panels because
   they answer two different questions, and merging them makes
   "change this" and "change the next" the same control. */

.markup-properties:empty { display: none; }

.markup-props {
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--border);
  background: var(--surface-2, rgba(255, 255, 255, 0.03));
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}

.markup-props-head {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  justify-content: space-between;
}

.prop-row {
  display: grid;
  grid-template-columns: 5.5rem 1fr;
  align-items: center;
  gap: var(--sp-2);
  font-size: 0.8125rem;
}

.prop-row .input,
.prop-row .select { padding: 2px 6px; font-size: 0.8125rem; }

.prop-swatches { display: flex; gap: 4px; flex-wrap: wrap; align-items: center; }

/* The "no fill" swatch has to read as an absence rather than as a
   colour, so it is drawn rather than filled. */
.viewer-swatch.prop-none {
  background: transparent;
  border: 1px dashed var(--border-strong, var(--border));
  color: var(--text-muted);
  font-size: 10px;
  line-height: 1;
}

/* Locked markup is still legible — it is not disabled, it is fixed. */
.viewer-ann.locked { cursor: not-allowed; }

/* ── Viewer navigation (Phase V2) ───────────────────────────── */

.viewer-zoom-label {
  min-width: 3.25rem;
  text-align: center;
  font-variant-numeric: tabular-nums;
  font-size: 0.8125rem;
  color: var(--text-muted);
}

/* Held space, or the hand tool: the cursor says so before the drag
   starts, because a pan that only announces itself once it is moving
   reads as the page having slipped. */
.viewer-stage.pannable { cursor: grab; }
.viewer-stage.panning  { cursor: grabbing; user-select: none; }

.tool-btn.active,
.btn.active { outline: 2px solid var(--accent, #3a7be8); outline-offset: -2px; }

/* ── The page rail (Phase V2) ───────────────────────────────── */

.viewer-body { display: flex; flex: 1; min-height: 0; }

.viewer-rail {
  width: 148px;
  flex: 0 0 148px;
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: var(--surface-2, rgba(255, 255, 255, 0.02));
}

.viewer-rail[hidden] { display: none; }

.viewer-rail-tabs {
  display: flex;
  gap: 2px;
  padding: var(--sp-2);
  border-bottom: 1px solid var(--border);
}

.viewer-rail-body {
  overflow-y: auto;
  padding: var(--sp-2);
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  min-height: 0;
}

.rail-thumb {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 4px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm, 4px);
  background: none;
  color: var(--text-muted);
  font-size: 0.6875rem;
  cursor: pointer;
}

.rail-thumb canvas {
  background: #fff;
  border: 1px solid var(--border);
  max-width: 100%;
}

.rail-thumb:hover { border-color: var(--border-strong, var(--border)); }
.rail-thumb.current { border-color: var(--accent, #3a7be8); color: var(--text); }

.rail-outline, .rail-outline ul { list-style: none; margin: 0; padding: 0; }

.rail-outline-item {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  color: var(--text);
  font-size: 0.75rem;
  padding: 4px 8px;
  cursor: pointer;
  border-radius: var(--radius-sm, 4px);
}

.rail-outline-item:hover { background: var(--surface-3, rgba(255, 255, 255, 0.06)); }

.viewer-page-input {
  width: 3.5rem;
  padding: 2px 4px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

/* Always reserve the vertical scrollbar. Without this, fitting to
   width measures a stage whose width depends on whether the page
   currently overflows — so fitting makes it not overflow, which makes
   the stage wider, which changes the fit. Rotating a sheet twice came
   back at a different zoom than it started. Reserving the space
   breaks the loop; on platforms with overlay scrollbars it costs
   nothing. */
.viewer-stage { overflow-y: scroll; overflow-x: auto; }

/* The stage sits in a flex row beside the rail, so it must be told to
   take the remaining width. Without `flex: 1; min-width: 0` its width
   is decided by its content — and since fit-width sizes the content
   from the stage's width, the two chase each other: rotating a sheet
   twice came back smaller each time. */
.viewer-body > .viewer-stage { flex: 1 1 auto; min-width: 0; }

/* ── The markups list as a table (Phase V5) ─────────────────── */

.markup-table-wrap { overflow: auto; max-height: 100%; }

.markup-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.75rem;
}

.markup-table th,
.markup-table td {
  padding: 4px 8px;
  text-align: left;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}

.markup-th {
  position: sticky;
  top: 0;
  background: var(--surface-2, var(--bg-base));
  cursor: pointer;
  user-select: none;
  font-weight: 600;
}

.markup-th.sorted { color: var(--accent, #3a7be8); }

.markup-row { cursor: pointer; }
.markup-row:hover { background: var(--surface-3, rgba(255, 255, 255, 0.04)); }
.markup-row.selected { background: rgba(58, 123, 232, 0.16); }

/* A section heading is a fact about the rows under it, so it reads as
   a heading rather than as another row. */
.markup-section td {
  background: var(--surface-2, rgba(255, 255, 255, 0.05));
  border-top: 1px solid var(--border-strong, var(--border));
}

.markup-section-total td {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  border-bottom: 2px solid var(--border-strong, var(--border));
}

.column-picker { display: flex; flex-direction: column; gap: 2px; max-height: 320px; overflow-y: auto; }

.column-pick {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 3px 4px;
  font-size: 0.8125rem;
}

/* ── Alignment commands (Phase V6) ──────────────────────────── */

.align-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 4px;
}

.align-row .btn { padding: 3px 6px; font-size: 0.75rem; }
