/* ============================================================
   Redas Dashboard v2 — Design System
   Monday.com-inspired, mobile-first, dark/light theme
   ============================================================ */

/* CSS Cascade Layers — pattern reference: MDN @layer, Tailwind v4
   layer model, shadcn @layer base/components/utilities, Stripe
   style guide. Layer order is established here once: later layers
   WIN over earlier layers regardless of selector specificity.
   This lets mobile-overrides defeat desktop component rules
   WITHOUT !important. */
@layer reset, tokens, components, mobile-overrides;

@layer tokens {
/* ---------- CSS Variables (Light Mode) ---------- */
:root {
  /* nav.css compatibility — dropdown backgrounds need these */
  --bg-card: #ffffff;
  --border-color: #e2e8f0;
  --border-radius: 8px;
  --border-radius-sm: 4px;
  --shadow-lg: 0 10px 25px rgba(0, 0, 0, 0.15);
  --space-sm: 6px;
  --space-md: 12px;
  --bg-hover: rgba(0, 0, 0, 0.05);
  --text-primary: #1e293b;
  --color-danger: #ef4444;

  --v2-bg: #dfe4ec;
  --v2-bg-card: #ffffff;
  --v2-bg-hover: rgba(0, 0, 0, 0.03);
  --v2-bg-row-alt: rgba(0, 0, 0, 0.015);
  --v2-bg-input: #f8fafc;
  --v2-border: #e2e8f0;
  --v2-border-light: #f1f5f9;
  --v2-text: #1e293b;
  --v2-text-secondary: #64748b;
  --v2-text-muted: #94a3b8;
  --v2-shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.08);
  --v2-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.1);
  --v2-radius: 8px;
  --v2-radius-sm: 4px;
  --v2-radius-pill: 16px;
  --v2-orange: #e87722;
  --v2-orange-bg: rgba(232, 119, 34, 0.12);
  /* Aliases / additional semantic tokens — added 2026-05-01 to remove
     orphan token references that were silently hitting dark hex fallbacks
     (the "Synthesis bar is black in light mode" bug). Tokens used by
     code that was originally written assuming dark-only context. */
  --v2-accent: #e87722;
  --v2-text-faint: #94a3b8;
  /* The top-nav (.top-nav) is brand chrome — stays dark navy in BOTH
     themes. Industry pattern: Linear, Stripe, Monday.com, GitHub all
     ship dark headers in light mode. The token is defined here so the
     fallback in nav.css ever fires only when this CSS isn't loaded. */
  --bg-header: #1a2332;
  --v2-teal: #2dd4bf;
  --v2-teal-bg: rgba(45, 212, 191, 0.1);
  --v2-green: #22c55e;
  --v2-green-bg: rgba(34, 197, 94, 0.1);
  --v2-red: #ef4444;
  --v2-red-bg: rgba(239, 68, 68, 0.1);
  --v2-yellow: #f59e0b;
  --v2-yellow-bg: rgba(245, 158, 11, 0.1);
  --v2-purple: #a78bfa;
  --v2-purple-bg: rgba(167, 139, 250, 0.1);
  --v2-blue: #3b82f6;
  --v2-blue-bg: rgba(59, 130, 246, 0.1);
  --v2-navy: #0f172a;
  --v2-font: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, sans-serif;
}

/* ---------- Dark Mode ---------- */
/* Palette tracks the brand navy from landing.css:4
   ("Palette: Navy #1a2332, White #ffffff, Orange #e87722").
   Page bg uses the darker brand panel #151d28 (landing.css:315),
   card surface uses the canonical brand navy #1a2332 (the logo
   block fill). Brief detour through GitHub-deep #0e1117 was
   reverted 2026-04-27 — landing → dashboard transition felt off-brand. */
[data-theme="dark"] {
  /* nav.css compatibility */
  --bg-card: #1a2332;
  --border-color: #2a3849;
  --shadow-lg: 0 10px 25px rgba(0, 0, 0, 0.4);
  --bg-hover: rgba(255, 255, 255, 0.05);
  --text-primary: #f1f5f9;

  --v2-bg: #151d28;
  --v2-bg-card: #1a2332;
  --v2-bg-hover: rgba(255, 255, 255, 0.03);
  --v2-bg-row-alt: rgba(255, 255, 255, 0.015);
  --v2-bg-input: #151d28;
  --v2-border: #2a3849;
  --v2-border-light: rgba(255, 255, 255, 0.04);
  --v2-text: #f1f5f9;
  --v2-text-secondary: #94a3b8;
  --v2-text-muted: #64748b;
  --v2-shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.3);
  --v2-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4);
  /* Dark-mode equivalents of the aliases added in :root above.
     --bg-header stays #1a2332 same as light mode — header is
     brand-locked dark in both themes. */
  --v2-accent: #e87722;
  --v2-text-faint: #64748b;
  --bg-header: #1a2332;
}
} /* end @layer tokens */

@layer reset {
/* ---------- Reset & Base ---------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  overflow-x: hidden;
  overscroll-behavior-x: none;
  /* Disable iOS double-tap-to-zoom on the page background; individual
   * tables keep horizontal scroll via .v2-table-wrap overflow-x: auto. */
  touch-action: manipulation;
  -webkit-text-size-adjust: 100%;
}

/* Inputs at <16px font-size trigger iOS Safari's auto-zoom-on-focus.
 * Force a 16px floor on every input/select/textarea so focus never
 * zooms the viewport, even if the user has Dynamic Type cranked up. */
input, select, textarea {
  font-size: max(16px, 1em);
}

body {
  font-family: var(--v2-font);
  background: var(--v2-bg);
  color: var(--v2-text);
  margin: 0;
  padding: 0;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  overscroll-behavior-x: none;
  /* Defense-in-depth: any child element that exceeds viewport width (table,
   * floating action button, absolutely-positioned overlay) is clipped at the
   * body edge instead of pushing the layout. Child containers still manage
   * their own internal scroll (e.g., .v2-table-wrap scrolls its table), but
   * the page itself never shifts horizontally as the user interacts. */
}
} /* end @layer reset */

@layer components {

/* Belt-and-suspenders: pin the outer container to viewport width on mobile
 * so no descendant can force the <body> wider than the screen even if a
 * browser ignores overflow-x: hidden (rare, but iOS Safari edge cases exist). */
} /* close @layer components for the next @media */

@layer mobile-overrides {
@media (max-width: 768px) {
  .v2-container {
    max-width: 100vw;
    overflow-x: hidden;
  }
}
}

@layer components {

/* ---------- Container ---------- */
.v2-container {
  max-width: 1400px;
  margin: 0 auto;
  padding: 16px;
}

/* ---------- Hero Stats ---------- */
.v2-stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  margin-bottom: 16px;
}

.v2-stat {
  background: var(--v2-bg-card);
  border-radius: var(--v2-radius);
  padding: 14px 16px;
  display: flex;
  align-items: center;
  gap: 12px;
  box-shadow: var(--v2-shadow-sm);
  cursor: pointer;
  transition: box-shadow 0.15s, transform 0.15s;
}
.v2-stat:hover {
  box-shadow: var(--v2-shadow-md);
  transform: translateY(-1px);
}

.v2-stat-icon {
  width: 36px;
  height: 36px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--v2-blue-bg);
  color: var(--v2-blue);
  flex-shrink: 0;
}
.v2-stat--warning .v2-stat-icon { background: var(--v2-yellow-bg); color: var(--v2-yellow); }
.v2-stat--success .v2-stat-icon { background: var(--v2-green-bg); color: var(--v2-green); }

.v2-stat-value {
  font-size: 1.4rem;
  font-weight: 700;
  line-height: 1;
}
.v2-stat-label {
  font-size: 0.75rem;
  color: var(--v2-text-secondary);
  margin-top: 2px;
}

/* ---------- Tabs (hidden/shown by JS) ---------- */
.v2-tab { display: none; }
.v2-tab.active { display: block; }

/* ---------- Filter Bar ---------- */
.v2-filter-bar {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: 12px;
}

.v2-filter {
  padding: 5px 14px;
  border-radius: var(--v2-radius-pill);
  font-size: 0.8rem;
  font-weight: 500;
  border: 1px solid var(--v2-border);
  background: transparent;
  color: var(--v2-text-secondary);
  cursor: pointer;
  font-family: var(--v2-font);
  transition: all 0.15s;
}
.v2-filter:hover { background: var(--v2-bg-hover); color: var(--v2-text); }
.v2-filter.active {
  background: var(--v2-orange-bg);
  color: var(--v2-orange);
  border-color: rgba(232, 119, 34, 0.3);
}

.v2-filter-search {
  background: var(--v2-bg-input);
  border: 1px solid var(--v2-border);
  border-radius: var(--v2-radius-pill);
  padding: 5px 14px;
  font-size: 0.8rem;
  color: var(--v2-text);
  outline: none;
  min-width: 160px;
  font-family: var(--v2-font);
}
.v2-filter-search::placeholder { color: var(--v2-text-muted); }
.v2-filter-search:focus { border-color: var(--v2-orange); }

/* ---------- Tab Toolbar ---------- */
.v2-tab-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
  margin-bottom: 12px;
  flex-wrap: wrap;
}
.v2-toolbar-right {
  display: flex;
  gap: 8px;
  align-items: center;
}

/* ---------- Select ---------- */
.v2-select {
  background: var(--v2-bg-card);
  border: 1px solid var(--v2-border);
  border-radius: var(--v2-radius-sm);
  padding: 5px 10px;
  font-size: 0.8rem;
  color: var(--v2-text);
  font-family: var(--v2-font);
  cursor: pointer;
}

/* ---------- Column Headers (Dashboard tab) ---------- */
.v2-col-headers {
  display: flex;
  align-items: center;
  padding: 6px 12px;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--v2-text-muted);
  font-weight: 600;
  margin-bottom: 4px;
}
.v2-h-check { width: 28px; flex-shrink: 0; }
.v2-h-dir { width: 240px; flex-shrink: 0; }
.v2-h-what { flex: 1; min-width: 0; }
.v2-h-due { width: 150px; flex-shrink: 0; }
.v2-h-notes { flex: 1; padding-left: 12px; }

/* ---------- Meeting Card (Dashboard tab) ---------- */
.v2-meeting {
  background: var(--v2-bg-card);
  border-radius: var(--v2-radius);
  border-left: 3px solid var(--v2-red);
  margin-bottom: 8px;
  overflow: hidden;
  box-shadow: var(--v2-shadow-sm);
}
.v2-meeting--ok { border-left-color: var(--v2-green); }

.v2-meeting-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 12px;
  background: var(--v2-bg-hover);
  cursor: pointer;
  user-select: none;
}
.v2-meeting-header:hover { filter: brightness(0.97); }
[data-theme="dark"] .v2-meeting-header:hover { filter: brightness(1.1); }

.v2-meeting-title { font-weight: 600; font-size: 0.9rem; }
.v2-meeting-meta { font-size: 0.75rem; color: var(--v2-text-muted); margin-left: 8px; }
.v2-meeting-toggle { font-size: 0.7rem; color: var(--v2-text-muted); margin-right: 6px; }

.v2-meeting-body { /* collapsible content */ }

/* ---------- Badges ---------- */
.v2-badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 10px;
  font-size: 0.7rem;
  font-weight: 600;
}
.v2-badge--overdue { background: var(--v2-red-bg); color: var(--v2-red); }
.v2-badge--open { background: var(--v2-blue-bg); color: var(--v2-blue); }
.v2-badge--done { background: var(--v2-green-bg); color: var(--v2-green); }
.v2-badge--warning { background: var(--v2-yellow-bg); color: var(--v2-yellow); }
.v2-badge--type {
  background: var(--v2-orange-bg);
  color: var(--v2-orange);
  text-transform: uppercase;
  font-size: 0.65rem;
  letter-spacing: 0.03em;
}

/* ---------- Commitment Row (Dashboard tab) ---------- */
.v2-row {
  display: flex;
  align-items: flex-start;
  padding: 6px 12px;
  border-bottom: 1px solid var(--v2-border-light);
  cursor: pointer;
  transition: background 0.1s;
  position: relative;
}
.v2-row:hover { background: var(--v2-bg-hover); }
.v2-row:nth-child(even) { background: var(--v2-bg-row-alt); }
.v2-row:nth-child(even):hover { background: var(--v2-bg-hover); }
.v2-row:last-child { border-bottom: none; }
.v2-row--done .v2-row-dir,
.v2-row--done .v2-row-what,
.v2-row--done .v2-row-due,
.v2-row--done .v2-row-notes { opacity: 0.5; }
.v2-row--done .v2-row-what { text-decoration: line-through; }

.v2-row-check { width: 96px; flex-shrink: 0; display: flex; align-items: center; position: relative; margin-right: 12px; }
.v2-row-dir { width: 240px; flex-shrink: 0; font-size: 0.8rem; color: var(--v2-text-secondary); }
.v2-row-what { flex: 1; min-width: 0; font-weight: 600; font-size: 0.85rem; padding-right: 8px; white-space: normal; line-height: 1.4; }
.v2-row-due { width: 150px; flex-shrink: 0; font-size: 0.8rem; white-space: nowrap; padding-top: 2px; }
.v2-row-notes { flex: 1; padding-left: 12px; }

/* Direction labels */
.v2-dir-name { color: var(--v2-text); }
.v2-dir-company { color: var(--v2-text-muted); font-size: 0.75rem; }
.v2-add-company {
  color: var(--v2-text-muted);
  font-size: 0.65rem;
  font-style: italic;
  opacity: 0.4;
  transition: opacity 0.15s;
  cursor: pointer;
}
.v2-row:hover .v2-add-company { opacity: 0.7; }
/* Scoped to .v2-row so specificity (0,3,0) beats the parent hover rule
   (0,2,0) — drops the !important. Same component layer either way. */
.v2-row .v2-add-company:hover { opacity: 1; color: var(--v2-orange); }
.v2-dir-verb {
  font-weight: 700;
  font-size: 0.65rem;
  text-transform: uppercase;
  padding: 1px 5px;
  border-radius: 3px;
  margin: 0 3px;
  display: inline-block;
  vertical-align: middle;
}
.v2-dir-owe { color: var(--v2-orange); background: var(--v2-orange-bg); }
.v2-dir-owes { color: var(--v2-teal); background: var(--v2-teal-bg); }
.v2-dir-self { color: var(--v2-purple); font-weight: 600; font-size: 0.8rem; }

/* Due date states */
.v2-due-overdue { color: var(--v2-red); font-weight: 500; }
.v2-due-today { color: var(--v2-yellow); font-weight: 500; }
.v2-due-soon { color: var(--v2-text-secondary); }
.v2-due-none {
  color: var(--v2-text-muted);
  font-style: italic;
  cursor: pointer;
  border-bottom: 1px dashed var(--v2-text-muted);
}
.v2-due-none:hover { border-bottom-color: var(--v2-orange); color: var(--v2-text-secondary); }

/* Checkbox */
/* Status checkbox — opens the status picker on click for OPEN rows.
   Becomes a ✓/✗ glyph on done/missed rows (long-press for undo).
   Field report 2026-04-26: status actions live on TWO surfaces only —
   this checkbox (per-row) + the bulk-select bar (multi-row). Kebab
   is utility-only (Nudge / Detail / View Related / Run Domain Analysis /
   Flag for dispute). */
/* Status checkbox / glyph — non-interactive on done rows.
   Open rows render .v2-pill action buttons instead (see below);
   this rule only applies to .v2-checkbox.done / .missed nodes
   which are pure visual indicators. Long-press / right-click
   opens the legacy ctx-menu for Undo/Edit/Draft. */
.v2-checkbox {
  width: 18px;
  height: 18px;
  border-radius: 3px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0;
  cursor: default;
}
.v2-checkbox.done { background: var(--v2-green); border: 2px solid var(--v2-green); font-size: 11px; color: white; }
.v2-checkbox.missed { background: var(--v2-red); border: 2px solid var(--v2-red); font-size: 11px; color: white; }

/* ─── Row Status Pills (Option A, 2026-04-27) ───
   Pattern: Notion / shadcn data-table — three icon buttons per row,
   always visible, no hover-reveal, no popover indirection. Replaces
   the Option D ▾ trigger + popover that shipped 2026-04-26. Tap-to-
   misfire risk is mitigated by the existing 5-second undo toast.
   Mockup canon: src/public/mockups/row-status-pills.html. */
.v2-row-pills {
  display: inline-flex;
  gap: 4px;
  align-items: center;
}
.v2-pill {
  width: 28px;
  height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  border: 1px solid;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  background: transparent;
  padding: 0;
  transition: background 0.12s ease, transform 0.06s ease, border-color 0.12s ease;
}
.v2-pill:hover { transform: translateY(-1px); }
.v2-pill:focus-visible { outline: 2px solid var(--v2-orange); outline-offset: 1px; }
.v2-pill--done    { color: var(--v2-green);  border-color: rgba(16, 185, 129, 0.45); }
.v2-pill--done:hover    { background: rgba(16, 185, 129, 0.12); border-color: var(--v2-green); }
.v2-pill--partial { color: var(--v2-yellow); border-color: rgba(245, 158, 11, 0.45); }
.v2-pill--partial:hover { background: rgba(245, 158, 11, 0.12); border-color: var(--v2-yellow); }
.v2-pill--missed  { color: var(--v2-red);    border-color: rgba(239, 68, 68, 0.45); }
.v2-pill--missed:hover  { background: rgba(239, 68, 68, 0.12); border-color: var(--v2-red); }

/* ---------- Dial-in chip (top-right header strip) ----------
 * Compact chip showing the user's assigned Twilio dial-in number.
 * Rendered hidden by default in dashboard-v2.html and revealed by JS
 * when /accountability/dial-in-number returns an assigned line.
 * The orange-accented number signals "this is your direct line" —
 * the same visual hierarchy as Linear's keyboard-shortcut chips. */
.v2-dial-in-chip {
  display: none;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  margin-bottom: 12px;
  background: var(--v2-bg-card);
  color: var(--v2-text);
  border: 1px solid var(--v2-border);
  border-radius: var(--v2-radius);
  font-size: 0.85rem;
}
.v2-dial-in-chip[data-active="true"] { display: inline-flex; }
.v2-dial-in-chip .v2-dial-in-label { opacity: 0.75; }
.v2-dial-in-chip .v2-dial-in-number {
  font-weight: 600;
  color: var(--v2-orange);
}
.v2-dial-in-chip .v2-dial-in-copy {
  margin-left: auto;
  background: none;
  border: 1px solid var(--v2-border);
  color: var(--v2-text);
  padding: 4px 10px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 0.8rem;
}
.v2-dial-in-chip .v2-dial-in-copy:hover { background: var(--v2-bg-hover); }

} /* close @layer components */

@layer components {

/* Context menu */
.v2-ctx-menu {
  display: none;
  position: absolute;
  left: 28px;
  top: -4px;
  background: var(--v2-bg-card);
  border: 1px solid var(--v2-border);
  border-radius: 6px;
  box-shadow: var(--v2-shadow-md);
  z-index: 100;
  min-width: 140px;
  overflow: hidden;
}
.v2-ctx-menu.show { display: block; }
.v2-ctx-menu-item {
  padding: 8px 12px;
  font-size: 0.8rem;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
}
.v2-ctx-menu-item:hover { background: var(--v2-bg-hover); }
.v2-ctx-menu-item--complete { color: var(--v2-green); }
.v2-ctx-menu-item--missed { color: var(--v2-red); }
.v2-ctx-menu-item--undo { color: var(--v2-text-muted); }

/* Notes input */
.v2-notes-input {
  background: transparent;
  border: none;
  border-bottom: 1px solid transparent;
  color: var(--v2-text-secondary);
  font-size: 0.78rem;
  width: 100%;
  padding: 2px 0;
  font-family: var(--v2-font);
  outline: none;
  resize: none;
  overflow: hidden;
  min-height: 20px;
  display: block;
}
.v2-notes-input:hover { border-bottom-color: var(--v2-border); }
.v2-notes-input:focus { border-bottom-color: var(--v2-orange); color: var(--v2-text); }
.v2-notes-input::placeholder { color: var(--v2-text-muted); font-style: italic; }

/* Row hover actions — kebab + popover menu.
   Pre-2026-04-26 the actions strip (Nudge / Run Domain Analysis /
   View Related / Detail / Flag) rendered inline next to the notes
   input and overlapped the row description on long content. The new
   kebab keeps the chrome compact; the popover menu opens on click
   and contains the same buttons (same data-attributes → existing
   handlers fire). */
/* Pre-2026-04-26 the kebab only appeared on desktop hover, which
   meant touch users (and idle rows on desktop) couldn't reach the
   status actions. Field report: "kebab menu is being blocked."
   Fix: always show the kebab. On mobile the kebab still disappears
   via the per-breakpoint rule below when the row is collapsed —
   that override is applied in .v2-row--expanded-mobile only. */
.v2-row-actions {
  display: flex;
  position: absolute;
  right: 12px;
  top: 2px;
  gap: 4px;
  z-index: 10;
}
.v2-row-action--kebab {
  font-size: 1.05rem;
  line-height: 1;
  letter-spacing: 1px;
  padding: 2px 8px;
  min-width: 28px;
  cursor: pointer;
  /* Override base .v2-row-action's border + background. The kebab is
     a glyph-only action — no chrome — so it doesn't compete with the
     row content. Industry pattern: GitHub, Linear, Notion all ship
     borderless kebabs. The hover state below restores a subtle
     background for affordance. */
  border: none;
  background: transparent;
  color: var(--v2-text-secondary);
}
.v2-row-action--kebab:hover {
  background: var(--v2-bg-hover);
  color: var(--v2-text);
}
/* Kebab dropdown — native HTML [popover] + CSS anchor positioning.
   Replaces the prior absolute-positioned + JS getBoundingClientRect
   recovery (3 commits worth of guesses on 2026-04-26).
   The native popover renders in the browser top layer, so it can't
   be clipped by sibling row stacking contexts. Anchor positioning
   places the menu relative to the kebab via the matching anchor-name
   declared inline (`anchor-name: --kebab-{id}`) on the trigger. */
.v2-row-action-menu[popover] {
  /* Reset the user-agent default popover centering. Anchor positioning
     handles placement. */
  inset: unset;
  margin: 0;
  /* position-area: bottom span-left places the menu directly below
     the kebab, anchored to its right edge. Browser falls back to the
     anchor's box if `position-area` isn't supported (Safari ≤17). */
  position-area: bottom span-left;
  margin-top: 4px;
  min-width: 220px;
  background: var(--v2-bg-card);
  color: var(--v2-text, #1e293b);
  border: 1px solid var(--v2-border, #e2e8f0);
  border-radius: 8px;
  /* Lighter shadow tuned for light mode (a 60%-black drop on a white
     card looks like a heavy box). Dark theme overrides below restore
     the original depth so hierarchy stays readable on dark cards. */
  box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12), 0 0 0 1px rgba(15, 23, 42, 0.06);
  padding: 4px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
[data-theme="dark"] .v2-row-action-menu[popover] {
  box-shadow: 0 14px 44px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(0, 0, 0, 0.4);
}
.v2-row-action-menu[popover]:not(:popover-open) { display: none; }

/* Soft backdrop — uses the native ::backdrop pseudo. Free with [popover];
   no manual ::before tricks. The browser handles light-dismiss for us. */
.v2-row-action-menu[popover]::backdrop {
  background: rgba(0, 0, 0, 0.35);
}

/* Active-trigger merge — when a kebab's popover is open, the kebab
   visually blends into the menu's color scheme so the "..." doesn't
   compete with the menu items. Uses :has() since both browsers we
   target (2026 baseline) support it. */
.v2-row-action--kebab[aria-expanded="true"],
.v2-row-action--kebab:has(+ .v2-row-action-menu[popover]:popover-open) {
  background: var(--v2-bg-card);
  color: var(--v2-orange, #f97316);
  border-color: var(--v2-orange, #f97316);
}

/* Sibling dim — when ANY row's popover is open, dim the kebabs of
   the OTHER rows so the active dropdown owns user focus. Field
   report 2026-04-26: "146 dots competing with the dropdown."
   Resolved here by purely declarative CSS using :has(). */
.v2-meetings-list:has(.v2-row-action-menu[popover]:popover-open)
  .v2-row:not(:has(.v2-row-action-menu[popover]:popover-open))
  .v2-row-action--kebab {
  opacity: 0.18;
  pointer-events: none;
  transition: opacity 0.15s ease;
}
.v2-row-action-menu-item {
  background: none;
  border: none;
  color: var(--v2-text, #1e293b);
  font: inherit;
  text-align: left;
  padding: 8px 10px;
  border-radius: 4px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.82rem;
}
.v2-row-action-menu-item:hover,
.v2-row-action-menu-item:focus { background: rgba(15,23,42,0.06); outline: none; }
[data-theme="dark"] .v2-row-action-menu-item:hover,
[data-theme="dark"] .v2-row-action-menu-item:focus { background: rgba(255,255,255,0.06); }
.v2-row-action-menu-item--flag-on { color: #ef4444; }

} /* close @layer components */

@layer mobile-overrides {
/* Mobile portrait — override anchor positioning with a bottom-sheet.
   Native [popover] still renders in the top layer; we just retarget
   placement to the viewport bottom for thumb-reach + larger tap
   targets. The native ::backdrop handles dim. */
@media (max-width: 600px) {
  /* Mobile keeps the same anchored-popover pattern as desktop — opens
     below + to the left of the kebab. The earlier full-width bottom-
     sheet override was rejected by the user as too heavy; the dashboard
     should feel consistent across breakpoints, not switch UI patterns.
     We only widen tap targets here. */
  .v2-row-action-menu-item {
    padding: 12px 14px;
    font-size: 0.9rem;
    min-height: 44px; /* iOS HIG minimum */
  }
}
}

@layer components {

/* Done toggle */
.v2-done-toggle {
  padding: 6px 12px;
  font-size: 0.75rem;
  color: var(--v2-text-muted);
  cursor: pointer;
  border-top: 1px solid var(--v2-border-light);
}
.v2-done-toggle:hover { color: var(--v2-text-secondary); }

/* Column resize handles */
.v2-resize-handle {
  position: absolute;
  right: -2px;
  top: 0;
  bottom: 0;
  width: 5px;
  cursor: col-resize;
  z-index: 5;
}
.v2-resize-handle:hover,
.v2-resize-handle.active {
  background: var(--v2-orange);
  opacity: 0.5;
}

/* Follow-up button + badge */
.v2-followup-btn {
  display: inline-block;
  font-size: 0.65rem;
  font-weight: 600;
  padding: 1px 8px;
  border-radius: 3px;
  border: 1px solid rgba(251, 191, 36, 0.3);
  background: var(--v2-yellow-bg);
  color: var(--v2-yellow);
  cursor: pointer;
  font-family: var(--v2-font);
  vertical-align: middle;
  margin-left: 4px;
}
.v2-followup-btn:hover { background: rgba(251, 191, 36, 0.2); }

.v2-followup-badge {
  display: inline-block;
  font-size: 0.6rem;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: 3px;
  background: var(--v2-yellow-bg);
  color: var(--v2-yellow);
  vertical-align: middle;
  margin-left: 4px;
  letter-spacing: 0.03em;
}

.v2-request-badge {
  display: inline-block;
  font-size: 0.6rem;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: 3px;
  background: var(--v2-orange-bg);
  color: var(--v2-orange);
  vertical-align: middle;
  margin-left: 6px;
  letter-spacing: 0.03em;
}

/* Category badge — small inline label on commitment text */
.v2-cat-badge {
  display: inline-block;
  font-size: 0.6rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  padding: 1px 6px;
  border-radius: 3px;
  background: var(--v2-bg-hover);
  color: var(--v2-text-muted);
  vertical-align: middle;
  margin-left: 6px;
}

/* Category divider — subtle topic label between commitment rows */
.v2-category-divider {
  padding: 4px 12px 2px;
  border-top: 1px solid var(--v2-border-light);
}
.v2-category-divider:first-child { border-top: none; }
.v2-category-label {
  font-size: 0.65rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--v2-text-muted);
}

/* ---------- Table (Recaps, Action Items, Contracts) ---------- */
.v2-table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.v2-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.85rem;
}
.v2-table thead {
  position: sticky;
  top: 0;
  z-index: 2;
}
.v2-table th {
  background: var(--v2-bg-card);
  border-bottom: 2px solid var(--v2-border);
  padding: 8px 12px;
  text-align: left;
  font-weight: 600;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--v2-text-muted);
  white-space: nowrap;
  user-select: none;
}
.v2-table td {
  padding: 10px 12px;
  border-bottom: 1px solid var(--v2-border-light);
  vertical-align: middle;
}
.v2-table tbody tr { transition: background 0.1s; }
.v2-table tbody tr:hover { background: var(--v2-bg-hover); }
.v2-table tbody tr:nth-child(even) { background: var(--v2-bg-row-alt); }
.v2-table tbody tr:nth-child(even):hover { background: var(--v2-bg-hover); }

.v2-sortable { cursor: pointer; }
.v2-sortable:hover { color: var(--v2-text); }
.v2-sort-icon { font-size: 0.65rem; margin-left: 4px; }

/* ---------- Card ---------- */
.v2-card {
  background: var(--v2-bg-card);
  border-radius: var(--v2-radius);
  box-shadow: var(--v2-shadow-sm);
  overflow: hidden;
}
.v2-card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  border-bottom: 1px solid var(--v2-border-light);
}
.v2-card-header h3 {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 600;
}
.v2-card-header--collapsible { cursor: pointer; user-select: none; }
.v2-card-header--collapsible:hover { background: var(--v2-bg-hover); }
.v2-collapse-icon {
  font-size: 0.7rem;
  color: var(--v2-text-muted);
  transition: transform 0.2s;
}
.v2-collapse-icon.expanded { transform: rotate(90deg); }

.v2-card-body { padding: 16px; }

/* ---------- Calendar Grid (Schedule tab) ---------- */
.v2-cal-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
}
.v2-cal-provider {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px;
  border: 1px solid var(--v2-border);
  border-radius: var(--v2-radius);
  transition: border-color 0.15s;
}
.v2-cal-provider.connected { border-color: var(--v2-green); }
.v2-cal-provider.disconnected { border-color: var(--v2-border); }

.v2-cal-icon {
  width: 40px;
  height: 40px;
  border-radius: 8px;
  background: var(--v2-bg-hover);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  color: var(--v2-text-secondary);
}
.v2-cal-provider.connected .v2-cal-icon { background: var(--v2-green-bg); color: var(--v2-green); }

.v2-cal-info { flex: 1; min-width: 0; }
.v2-cal-name { font-weight: 600; font-size: 0.85rem; }
.v2-cal-status { font-size: 0.75rem; color: var(--v2-text-muted); }
.v2-cal-provider.connected .v2-cal-status { color: var(--v2-green); }

/* Schedule meeting item */
.v2-schedule-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 0;
  border-bottom: 1px solid var(--v2-border-light);
}
.v2-schedule-item:last-child { border-bottom: none; }

.v2-schedule-time {
  width: 70px;
  flex-shrink: 0;
  text-align: center;
}
.v2-schedule-time-date { font-size: 0.7rem; color: var(--v2-text-muted); }
.v2-schedule-time-hour { font-size: 0.9rem; font-weight: 600; }

.v2-schedule-info { flex: 1; min-width: 0; }
.v2-schedule-title { font-weight: 600; font-size: 0.85rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v2-schedule-location { font-size: 0.75rem; color: var(--v2-text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v2-schedule-detail { font-size: 0.7rem; color: var(--v2-text-muted); margin-top: 2px; }

.v2-schedule-actions {
  display: flex;
  gap: 6px;
  flex-shrink: 0;
}

/* ---------- Reliability Grid ---------- */
.v2-rel-summary {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  margin-bottom: 16px;
}
.v2-rel-stat {
  background: var(--v2-bg-card);
  border-radius: var(--v2-radius);
  padding: 14px 16px;
  text-align: center;
  box-shadow: var(--v2-shadow-sm);
}
.v2-rel-stat-value { font-size: 1.4rem; font-weight: 700; }
.v2-rel-stat-label { font-size: 0.75rem; color: var(--v2-text-secondary); margin-top: 2px; }
.v2-rel-stat--danger .v2-rel-stat-value { color: var(--v2-red); }

.v2-rel-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 10px;
}

.v2-rel-card {
  background: var(--v2-bg-card);
  border-radius: var(--v2-radius);
  padding: 12px 16px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
  box-shadow: var(--v2-shadow-sm);
  cursor: pointer;
  transition: box-shadow 0.15s, transform 0.15s;
  border-left: 3px solid var(--v2-border);
}
.v2-rel-card:hover { box-shadow: var(--v2-shadow-md); transform: translateY(-1px); }
.v2-rel-card--green { border-left-color: var(--v2-green); }
.v2-rel-card--yellow { border-left-color: var(--v2-yellow); }
.v2-rel-card--red { border-left-color: var(--v2-red); }

.v2-rel-ring { flex-shrink: 0; }
.v2-rel-card-info { flex: 1; min-width: 0; }
.v2-rel-card-name { font-weight: 600; font-size: 0.9rem; }
.v2-rel-card-company { font-size: 0.75rem; color: var(--v2-text-muted); }
.v2-rel-card-pills { display: flex; gap: 6px; margin-top: 6px; flex-wrap: wrap; }

.v2-pill {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 2px 8px;
  border-radius: 10px;
  font-size: 0.7rem;
  font-weight: 600;
}
.v2-pill--green { background: var(--v2-green-bg); color: var(--v2-green); }
.v2-pill--yellow { background: var(--v2-yellow-bg); color: var(--v2-yellow); }
.v2-pill--red { background: var(--v2-red-bg); color: var(--v2-red); }

/* ---------- Reliability Leaderboard ----------
 * Top of Reliability tab. Desktop renders as a table; mobile portrait
 * (max-width: 600px) collapses to stacked cards via v2-leaderboard-card-mobile.
 * Top-3 rows tinted gold/silver/bronze to mirror the badge column. */
.v2-leaderboard-card {
  margin-bottom: 16px;
  padding: 14px 16px 12px;
}
.v2-leaderboard-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
  flex-wrap: wrap;
}
.v2-leaderboard-title-row { flex: 1; min-width: 0; }
.v2-leaderboard-title {
  margin: 0 0 2px;
  font-size: 1.05rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  gap: 6px;
}
.v2-leaderboard-subtitle {
  margin: 0;
  font-size: 0.78rem;
  color: var(--v2-text-muted, #94a3b8);
}
.v2-leaderboard-controls { flex-shrink: 0; }
.v2-leaderboard-sort { font-size: 0.82rem; }

.v2-leaderboard-body { overflow-x: auto; }

.v2-leaderboard-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.85rem;
}
.v2-leaderboard-table th {
  text-align: left;
  padding: 8px 10px;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--v2-text-muted, #94a3b8);
  border-bottom: 1px solid var(--v2-border, #e2e8f0);
  font-weight: 600;
}
.v2-leaderboard-table td {
  padding: 10px;
  border-bottom: 1px solid var(--v2-border, #e2e8f0);
  vertical-align: middle;
}
.v2-leaderboard-row { cursor: pointer; transition: background 0.12s; }
.v2-leaderboard-row:hover { background: var(--v2-bg-hover, rgba(148, 163, 184, 0.06)); }
.v2-leaderboard-row:last-child td { border-bottom: none; }

/* Top-3 tinted backgrounds (gold/silver/bronze) — match badge column */
.v2-leaderboard-row--gold   { background: rgba(234, 179, 8, 0.10); }
.v2-leaderboard-row--gold:hover   { background: rgba(234, 179, 8, 0.18); }
.v2-leaderboard-row--silver { background: rgba(148, 163, 184, 0.10); }
.v2-leaderboard-row--silver:hover { background: rgba(148, 163, 184, 0.18); }
.v2-leaderboard-row--bronze { background: rgba(180, 83, 9, 0.10); }
.v2-leaderboard-row--bronze:hover { background: rgba(180, 83, 9, 0.18); }

.v2-leaderboard-rank {
  font-weight: 700;
  font-size: 0.95rem;
  min-width: 28px;
}
.v2-leaderboard-person { font-weight: 600; }
.v2-leaderboard-company { color: var(--v2-text-muted, #94a3b8); font-size: 0.8rem; }
.v2-leaderboard-score {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.v2-leaderboard-trend { font-size: 1rem; font-weight: 700; text-align: center; }
.v2-leaderboard-trend--up    { color: var(--v2-green, #22c55e); }
.v2-leaderboard-trend--down  { color: var(--v2-red, #ef4444); }
.v2-leaderboard-trend--flat  { color: var(--v2-text-muted, #94a3b8); }

.v2-leaderboard-badge {
  font-size: 1.05rem;
  text-align: center;
  white-space: nowrap;
}
.v2-leaderboard-badge--gold   { color: #eab308; }
.v2-leaderboard-badge--silver { color: #94a3b8; }
.v2-leaderboard-badge--bronze { color: #b45309; }
.v2-leaderboard-badge--none   { color: var(--v2-text-muted, #94a3b8); }

.v2-leaderboard-volume {
  font-variant-numeric: tabular-nums;
  color: var(--v2-text-secondary, #64748b);
}

/* Mobile cards — used on portrait phones where the 7-column table chokes */
.v2-leaderboard-cards { display: none; }
.v2-leaderboard-mcard {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--v2-border, #e2e8f0);
  cursor: pointer;
}
.v2-leaderboard-mcard:last-child { border-bottom: none; }
.v2-leaderboard-mcard--gold   { background: rgba(234, 179, 8, 0.10); }
.v2-leaderboard-mcard--silver { background: rgba(148, 163, 184, 0.10); }
.v2-leaderboard-mcard--bronze { background: rgba(180, 83, 9, 0.10); }
.v2-leaderboard-mcard-rank {
  font-weight: 800;
  font-size: 1.1rem;
  min-width: 32px;
  text-align: center;
}
.v2-leaderboard-mcard-info { flex: 1; min-width: 0; }
.v2-leaderboard-mcard-name {
  font-weight: 600;
  font-size: 0.9rem;
  display: flex;
  align-items: center;
  gap: 6px;
}
.v2-leaderboard-mcard-meta {
  font-size: 0.72rem;
  color: var(--v2-text-muted, #94a3b8);
  margin-top: 2px;
}
.v2-leaderboard-mcard-score {
  text-align: right;
  font-weight: 700;
  font-size: 1rem;
  font-variant-numeric: tabular-nums;
}

} /* close @layer components */

@layer mobile-overrides {
/* Portrait phones: stack to cards, hide table */
@media (max-width: 600px) {
  .v2-leaderboard-head { flex-direction: column; align-items: stretch; }
  .v2-leaderboard-controls { width: 100%; }
  .v2-leaderboard-sort { width: 100%; }
  .v2-leaderboard-table { display: none; }
  .v2-leaderboard-cards { display: block; }
}
}

@layer components {

/* ---------- Buttons ---------- */
.v2-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 16px;
  border-radius: var(--v2-radius-sm);
  font-size: 0.85rem;
  font-weight: 500;
  font-family: var(--v2-font);
  border: none;
  background: var(--v2-orange);
  color: white;
  cursor: pointer;
  transition: opacity 0.15s;
  text-decoration: none;
}
.v2-btn:hover { opacity: 0.9; }
.v2-btn:disabled { opacity: 0.5; cursor: not-allowed; }

.v2-btn--sm { padding: 5px 12px; font-size: 0.8rem; }
.v2-btn--ghost {
  background: transparent;
  color: var(--v2-text-secondary);
  border: 1px solid var(--v2-border);
}
.v2-btn--ghost:hover { background: var(--v2-bg-hover); color: var(--v2-text); }
.v2-btn--danger { background: var(--v2-red); }
.v2-btn--success { background: var(--v2-green); }
.v2-btn--teal { background: var(--v2-teal); color: var(--v2-navy); }

.v2-row-action {
  padding: 3px 8px;
  border-radius: var(--v2-radius-sm);
  font-size: 0.7rem;
  font-weight: 500;
  border: 1px solid var(--v2-border);
  background: var(--v2-bg-card);
  color: var(--v2-text-secondary);
  cursor: pointer;
  white-space: nowrap;
  font-family: var(--v2-font);
}
.v2-row-action:hover { background: var(--v2-bg-hover); color: var(--v2-text); }
.v2-row-action--nudge { color: var(--v2-orange); border-color: rgba(232, 119, 34, 0.3); }
.v2-row-action--nudge:hover { background: var(--v2-orange-bg); }

/* ---------- Banner ----------
   Banners use DARK body text on a tinted background, with the count
   number / label kept in the accent color. PMs read these in Texas
   sun on a job site — orange-on-cream and yellow-on-cream both fail
   WCAG AA in those conditions. Pattern reference: GitHub flash
   alerts, Stripe Dashboard banner alerts. Both ship dark slate body
   text + colored accent on light-tint backgrounds. */
.v2-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 16px;
  background: var(--v2-orange-bg);
  border: 1px solid rgba(232, 119, 34, 0.2);
  border-radius: var(--v2-radius);
  margin-bottom: 12px;
  font-size: 0.85rem;
  color: #1a1a1a;
}
.v2-banner strong { color: var(--v2-orange); font-weight: 700; }
[data-theme="dark"] .v2-banner { color: var(--v2-text); }
[data-theme="dark"] .v2-banner strong { color: var(--v2-orange); }

/* Warning variant — unclear-names. Body text dark for sunlight
   readability; the count number stays in amber for emphasis. */
.v2-banner--warning {
  background: rgba(245, 158, 11, 0.10);
  border-color: rgba(245, 158, 11, 0.35);
  color: #1a1a1a;
}
.v2-banner--warning strong { color: #92400e; } /* amber-800 — readable on tint AND in sun */
[data-theme="dark"] .v2-banner--warning { color: var(--v2-text); }
[data-theme="dark"] .v2-banner--warning strong { color: #fcd34d; } /* amber-300 on dark card */
.v2-banner--warning .v2-banner-action {
  background: #92400e;
  color: white;
}
[data-theme="dark"] .v2-banner--warning .v2-banner-action {
  background: #fcd34d;
  color: #1a2332;
}
.v2-banner-action {
  margin-left: auto;
  background: var(--v2-orange);
  color: white;
  border: none;
  padding: 4px 12px;
  border-radius: var(--v2-radius-sm);
  font-size: 0.8rem;
  font-weight: 500;
  cursor: pointer;
  font-family: var(--v2-font);
}
.v2-banner-dismiss {
  background: none;
  border: none;
  color: var(--v2-orange);
  font-size: 1.2rem;
  cursor: pointer;
  padding: 0 4px;
  line-height: 1;
}

/* ---------- Bulk Select / Bulk Close (2026-04-26) ----------------
   Multi-row close so PMs can triage many commitments at once. The
   bar shows when ≥1 row is selected and offers Fulfilled / Partial /
   Missed / Clear. Distinct from the inbox bulk-confirm bar so PMs
   know they're acting on confirmed commitments, not pending inbox. */
.v2-row-select {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  width: 28px;
  flex-shrink: 0;
}
.v2-bulk-select-cb {
  width: 16px;
  height: 16px;
  cursor: pointer;
  accent-color: var(--v2-orange, #f97316);
  margin: 0;
}
.v2-row--selected {
  background: rgba(249, 115, 22, 0.06);
  border-left: 3px solid var(--v2-orange, #f97316);
}
.v2-bulk-select-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 16px;
  background: rgba(249, 115, 22, 0.10);
  border: 1px solid rgba(249, 115, 22, 0.35);
  border-left: 4px solid var(--v2-orange, #f97316);
  border-radius: var(--v2-radius);
  margin-bottom: 12px;
  font-size: 0.85rem;
  color: var(--v2-text, #1e293b);
  position: sticky;
  top: 0;
  z-index: 50;
}
.v2-bulk-select-count strong { color: var(--v2-orange, #f97316); }
/* Keyboard-shortcut hint chip — Linear / Gmail style */
.v2-bulk-select-shortcuts {
  display: inline-flex;
  gap: 6px;
  margin-left: 12px;
  font-size: 0.72rem;
  color: var(--v2-text-muted, #94a3b8);
  align-items: center;
}
.v2-bulk-select-shortcuts kbd {
  display: inline-block;
  padding: 1px 6px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--v2-border, #e2e8f0);
  border-radius: 3px;
  font-family: ui-monospace, monospace;
  font-size: 0.68rem;
  color: var(--v2-text-secondary, #64748b);
}
} /* close @layer components */

@layer mobile-overrides {
@media (max-width: 600px) {
  .v2-bulk-select-shortcuts { display: none; }
}
}

@layer components {
.v2-bulk-select-actions {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
} /* close @layer components */

@layer mobile-overrides {
@media (max-width: 600px) {
  .v2-bulk-select-bar {
    flex-direction: column;
    align-items: stretch;
  }
  .v2-bulk-select-actions {
    justify-content: space-between;
  }
  .v2-bulk-select-actions .v2-btn { flex: 1; min-width: 0; }
}
}

@layer components {

/* ---------- Modal factory (window.openModal) ----------------------
   Canonical native-<dialog> styling shared by every modal migrated
   off the legacy `.v2-modal-overlay` scaffold. Pairs with
   src/public/js/components/modal.js.

   Pattern reference: Radix Dialog + WAI-ARIA APG Modal Dialog Pattern.
   The native <dialog> + showModal() handles top-layer rendering,
   focus trap, focus restore, Esc, and scroll lock — these styles
   only handle visual chrome.

   Note: do NOT remove the older .v2-modal-overlay rules below —
   ~17 unmigrated modals still depend on them. This block is purely
   additive. Migrated modals are pinned in
   tests/services/v2ModalFactory.test.js.
*/
dialog.v2-modal {
  border: none;
  background: transparent;
  padding: 0;
  inset: 0;
  margin: auto;
  max-width: 100vw;
  max-height: 100vh;
  overflow: visible;
  color: var(--v2-text, #1e293b);
}
dialog.v2-modal:not([open]) { display: none; }
dialog.v2-modal::backdrop {
  background: rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(2px);
}
.v2-modal-card {
  background: var(--bg-card, #1e293b);
  border: 1px solid var(--v2-border, #e2e8f0);
  border-radius: 12px;
  max-width: 520px;
  width: min(92vw, 520px);
  max-height: 90vh;
  overflow-y: auto;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
  display: flex;
  flex-direction: column;
}
dialog.v2-modal--wide .v2-modal-card { max-width: 720px; width: min(92vw, 720px); }
dialog.v2-modal--narrow .v2-modal-card { max-width: 380px; width: min(92vw, 380px); }
.v2-modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 20px;
  border-bottom: 1px solid var(--v2-border, #e2e8f0);
}
.v2-modal-title {
  margin: 0;
  color: var(--text-primary, #f1f5f9);
  font-size: 1.05rem;
  font-weight: 600;
}
.v2-modal-close {
  background: transparent;
  border: none;
  color: var(--v2-text-secondary, #64748b);
  font-size: 1.5rem;
  cursor: pointer;
  padding: 0 4px;
  line-height: 1;
}
.v2-modal-close:hover { color: var(--text-primary, #f1f5f9); }
.v2-modal-body {
  padding: 16px 20px;
  flex: 1;
}
.v2-modal-foot {
  padding: 12px 20px;
  border-top: 1px solid var(--v2-border, #e2e8f0);
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  align-items: center;
}

/* ---------- Legacy modal bridge (dialog.v2-modal-legacy) -----------
   Migration shim used by modals ported off the legacy
   `<div class="v2-modal-overlay">` flex-overlay scaffold to native
   <dialog>. Each ported modal is now `<dialog class="v2-modal-legacy">`
   and its inner card retains the original inline-styled `.v2-modal`
   div, so we don't risk regressing the per-modal layout during the
   mechanical Esc / scroll-lock / focus-trap upgrade.

   Pattern reference: same as dialog.v2-modal above (Radix Dialog,
   WAI-ARIA APG Modal Dialog, MDN <dialog>) — this shim just keeps
   the historical inner-card markup intact while the outer frame
   becomes a real top-layer dialog.

   Migrated 2026-04-26 (Phase 2 of the modal-factory rollout).
*/
dialog.v2-modal-legacy {
  border: none;
  background: transparent;
  padding: 16px;
  inset: 0;
  margin: auto;
  max-width: 100vw;
  max-height: 100vh;
  overflow: visible;
  color: var(--v2-text, #1e293b);
  /* Recreate the legacy overlay's flex-centered layout (only when open) so
     the inner inline-styled card stays vertically + horizontally centered.
     When NOT open, native <dialog> is display:none by default, which is
     what we want — so no need to re-declare it here. */
  justify-content: center;
  align-items: center;
}
dialog.v2-modal-legacy[open] {
  display: flex;
  width: 100vw;
  height: 100vh;
}
dialog.v2-modal-legacy::backdrop {
  background: rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(2px);
}

/* ---------- Reason picker dialog (miss reason + partial reason) ----
   Native <dialog> shared by promptMissReason + promptPartialReason
   via the consolidated promptReasonModal helper. Free top-layer,
   focus-trap, scroll-lock, Esc, focus-restore via .showModal().
*/
dialog.v2-reason-modal {
  border: none;
  background: transparent;
  padding: 0;
  inset: 0;
  margin: auto;
  max-width: 100vw;
  max-height: 100vh;
  overflow: visible;
}
dialog.v2-reason-modal:not([open]) { display: none; }
dialog.v2-reason-modal::backdrop {
  background: rgba(0, 0, 0, 0.7);
}
.v2-reason-modal-card {
  background: var(--v2-bg-card, #ffffff);
  color: var(--v2-text, #1e293b);
  border: 1px solid var(--v2-border, #e2e8f0);
  border-radius: 10px;
  max-width: 520px;
  width: 92vw;
  padding: 18px;
  max-height: 90vh;
  overflow-y: auto;
}
.v2-reason-modal-title {
  font-weight: 700;
  font-size: 1rem;
  margin-bottom: 4px;
}
.v2-reason-modal-desc {
  font-size: 0.78rem;
  color: var(--v2-text-muted, #94a3b8);
  margin-bottom: 14px;
  line-height: 1.4;
}
.v2-reason-modal-options {
  display: grid;
  gap: 6px;
  margin-bottom: 12px;
}
.v2-reason-modal-option {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--v2-border, #e2e8f0);
  border-radius: 6px;
  cursor: pointer;
  font-size: 0.86rem;
}
.v2-reason-modal-option input[type="radio"] { margin-top: 3px; }
.v2-reason-modal-option:hover { background: rgba(255, 255, 255, 0.03); }
.v2-reason-modal-label { font-weight: 600; }
.v2-reason-modal-detail {
  color: var(--v2-text-muted, #94a3b8);
  font-size: 0.74rem;
  margin-top: 2px;
}
.v2-reason-modal-detail-input {
  margin-bottom: 12px;
}
.v2-reason-modal-detail-input label {
  display: block;
  font-size: 0.78rem;
  color: var(--v2-text-secondary, #64748b);
  margin-bottom: 4px;
}
.v2-reason-modal-detail-input input {
  width: 100%;
  padding: 8px 10px;
  background: var(--v2-bg, #dfe4ec);
  color: var(--v2-text, #1e293b);
  border: 1px solid var(--v2-border, #e2e8f0);
  border-radius: 6px;
  font-size: 0.85rem;
}
.v2-reason-modal-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}
.v2-reason-modal-actions button {
  padding: 8px 16px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 0.86rem;
  font-weight: 600;
  border: 1px solid transparent;
}
.v2-reason-modal-actions button[data-reason-cancel] {
  background: var(--v2-bg, #dfe4ec);
  color: var(--v2-text, #1e293b);
  border-color: var(--v2-border, #e2e8f0);
  font-weight: 400;
}
.v2-reason-modal-actions button[data-reason-save] {
  color: white;
}

/* Status Picker modal CSS removed 2026-04-26 in the Option D
   refactor; Option D popover removed 2026-04-27 in favor of
   always-visible .v2-pill action buttons. Per-row status now lives
   on the .v2-row-pills cluster — see above. */

/* ---------- Auth Warning Banner (Q2 substrate-readiness) ----------
   Sits at the top of the dashboard tab above PPC and Due-Today. Amber
   gradient + animated pulse so it can't be scrolled past. Click anywhere
   on the banner routes to the flagged-inbox view. */
.v2-auth-warning-banner {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 18px;
  margin-bottom: 12px;
  background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);
  border: 2px solid #f59e0b;
  border-left: 6px solid #d97706;
  border-radius: var(--v2-radius);
  box-shadow: 0 2px 8px rgba(245, 158, 11, 0.25);
  cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
  animation: v2-auth-warning-pulse 2.4s ease-in-out infinite;
}
.v2-auth-warning-banner:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(245, 158, 11, 0.4);
}
.v2-auth-warning-banner-icon {
  font-size: 1.6rem;
  flex-shrink: 0;
}
.v2-auth-warning-banner-body { flex: 1; min-width: 0; }
.v2-auth-warning-banner-title {
  font-size: 1rem;
  font-weight: 700;
  color: #78350f;
  margin-bottom: 2px;
}
.v2-auth-warning-banner-sub {
  font-size: 0.8rem;
  color: #92400e;
  line-height: 1.35;
}
.v2-auth-warning-banner-cta {
  flex-shrink: 0;
  background: #d97706;
  color: white;
  border: none;
  padding: 8px 16px;
  border-radius: 6px;
  font-weight: 600;
  font-size: 0.85rem;
  cursor: pointer;
  transition: background 0.12s ease;
}
.v2-auth-warning-banner-cta:hover { background: #b45309; }
@keyframes v2-auth-warning-pulse {
  0%, 100% { box-shadow: 0 2px 8px rgba(245, 158, 11, 0.25); }
  50%      { box-shadow: 0 2px 16px rgba(245, 158, 11, 0.55); }
}

/* ---------- Today's Hot List Hero (Chunk 1, 2026-04-28) ----------
   Orange-bordered triage block at the top of the Dashboard tab. Combines
   overdue + due-today across both directions; reuses the .v2-pill /
   .v2-row-pills primitives from chunk 3 so click handlers stay shared. */
.v2-hotlist {
  display: flex;
  flex-direction: column;
  background: var(--v2-bg-card);
  border: 1px solid var(--v2-orange);
  border-left: 4px solid var(--v2-orange);
  border-radius: 8px;
  margin-bottom: 14px;
  overflow: hidden;
}
.v2-hotlist-header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  background: var(--v2-orange-bg, rgba(232, 119, 34, 0.10));
  border-bottom: 1px solid var(--v2-border);
}
.v2-hotlist-title {
  font-weight: 700;
  font-size: 0.78rem;
  letter-spacing: 0.4px;
  color: var(--v2-orange);
  text-transform: uppercase;
}
.v2-hotlist-meta {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--v2-text);
}
.v2-hotlist-overdue { color: var(--v2-red); }
.v2-hotlist-due-today { color: var(--v2-yellow, #f59e0b); }
.v2-hotlist-spacer { flex: 1; }
.v2-hotlist-window {
  font-size: 0.74rem;
  color: var(--v2-text-muted);
}
.v2-hotlist-list { display: flex; flex-direction: column; }
.v2-hotlist-item {
  display: grid;
  grid-template-columns: 12px auto 1fr 90px;
  gap: 12px;
  align-items: center;
  padding: 10px 16px;
  border-bottom: 1px solid var(--v2-border);
  font-size: 0.85rem;
}
.v2-hotlist-item:last-child { border-bottom: none; }
.v2-hotlist-item:hover { background: rgba(255, 255, 255, 0.018); }
.v2-hotlist-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  justify-self: center;
}
.v2-hotlist-dot--overdue { background: var(--v2-red); }
.v2-hotlist-dot--soon    { background: var(--v2-yellow, #f59e0b); }
.v2-hotlist-body { min-width: 0; }
.v2-hotlist-meta-row {
  display: flex;
  gap: 6px;
  align-items: baseline;
  font-size: 0.78rem;
}
.v2-hotlist-who { color: var(--v2-text); font-weight: 600; }
.v2-hotlist-arrow { color: var(--v2-orange); font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.4px; }
.v2-hotlist-what {
  font-weight: 500;
  color: var(--v2-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.v2-hotlist-due {
  font-size: 0.78rem;
  font-weight: 600;
  text-align: right;
  white-space: nowrap;
}
.v2-hotlist-due--late  { color: var(--v2-red); }
.v2-hotlist-due--today { color: var(--v2-yellow, #f59e0b); }

/* ---------- Due Today Hero ---------- */
.v2-due-today {
  background: var(--v2-bg-card);
  border: 1px solid var(--v2-orange);
  border-left: 4px solid var(--v2-orange);
  border-radius: var(--v2-radius);
  margin-bottom: 12px;
  box-shadow: var(--v2-shadow-sm);
  overflow: hidden;
}
.v2-due-today-header {
  padding: 10px 16px;
  border-bottom: 1px solid var(--v2-border-light);
}
.v2-due-today-header h3 {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--v2-orange);
}
.v2-due-today-count {
  background: var(--v2-orange);
  color: white;
  font-size: 0.75rem;
  font-weight: 700;
  padding: 1px 7px;
  border-radius: var(--v2-radius-pill);
  min-width: 20px;
  text-align: center;
}
.v2-due-today-list {
  padding: 0;
}
.v2-due-today-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 16px;
  border-bottom: 1px solid var(--v2-border-light);
  font-size: 0.85rem;
  cursor: pointer;
  transition: background 0.15s;
}
.v2-due-today-item:last-child { border-bottom: none; }
.v2-due-today-item:hover { background: var(--v2-bg-hover); }
.v2-due-today-who {
  font-weight: 600;
  color: var(--v2-text);
  min-width: 90px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.v2-due-today-what {
  flex: 1;
  color: var(--v2-text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.v2-due-today-action {
  background: var(--v2-green);
  color: white;
  border: none;
  padding: 3px 10px;
  border-radius: var(--v2-radius-sm);
  font-size: 0.75rem;
  font-weight: 500;
  cursor: pointer;
  font-family: var(--v2-font);
  white-space: nowrap;
}
.v2-due-today-action:hover { opacity: 0.85; }

/* ---------- At-Risk Commitments ---------- */
/* Predictive risk alerts card. Sits below PPC/Synthesis, above Due Today.
   Mirrors v2-due-today density and the v2-synthesis-card collapse pattern.
   Red left border because at-risk items are strictly high/medium risk. */
.v2-at-risk-card {
  background: var(--v2-bg-card);
  border: 1px solid var(--v2-red);
  border-left: 4px solid var(--v2-red);
  border-radius: var(--v2-radius);
  margin-bottom: 12px;
  box-shadow: var(--v2-shadow-sm);
  overflow: hidden;
}
.v2-at-risk-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--v2-border-light);
  cursor: pointer;
  user-select: none;
}
.v2-at-risk-title-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.v2-at-risk-toggle {
  background: transparent;
  border: none;
  color: var(--v2-text-secondary);
  cursor: pointer;
  padding: 2px;
  display: inline-flex;
  align-items: center;
  transition: transform 0.15s;
}
.v2-at-risk-card[aria-collapsed="true"] .v2-at-risk-toggle { transform: rotate(-90deg); }
.v2-at-risk-title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--v2-red);
}
.v2-at-risk-count {
  background: var(--v2-red);
  color: white;
  font-size: 0.75rem;
  font-weight: 700;
  padding: 1px 7px;
  border-radius: var(--v2-radius-pill);
  min-width: 20px;
  text-align: center;
}
.v2-at-risk-summary {
  font-size: 0.75rem;
  color: var(--v2-text-muted);
  white-space: nowrap;
}
.v2-at-risk-body { padding: 0; }
.v2-at-risk-list { display: flex; flex-direction: column; }
.v2-at-risk-item {
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  align-items: center;
  gap: 10px;
  padding: 8px 16px;
  border-bottom: 1px solid var(--v2-border-light);
  font-size: 0.85rem;
  cursor: pointer;
  transition: background 0.15s;
}
.v2-at-risk-item:last-child { border-bottom: none; }
.v2-at-risk-item:hover { background: var(--v2-bg-hover); }
.v2-at-risk-pill {
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  padding: 2px 8px;
  border-radius: var(--v2-radius-pill);
  letter-spacing: 0.03em;
}
.v2-at-risk-pill--critical,
.v2-at-risk-pill--high {
  background: var(--v2-red-bg);
  color: var(--v2-red);
  border: 1px solid var(--v2-red);
}
.v2-at-risk-pill--medium {
  background: var(--v2-yellow-bg);
  color: var(--v2-yellow);
  border: 1px solid var(--v2-yellow);
}
.v2-at-risk-main {
  display: flex;
  flex-direction: column;
  min-width: 0;
  gap: 2px;
}
.v2-at-risk-what {
  color: var(--v2-text);
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.v2-at-risk-meta {
  color: var(--v2-text-secondary);
  font-size: 0.75rem;
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.v2-at-risk-reason {
  color: var(--v2-text-muted);
  font-size: 0.72rem;
  font-style: italic;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 280px;
}
.v2-at-risk-due {
  color: var(--v2-text-secondary);
  font-size: 0.78rem;
  white-space: nowrap;
}
.v2-at-risk-due--overdue { color: var(--v2-red); font-weight: 600; }

/* ---------- Row risk indicator (dot on direction badge) ---------- */
/* Mirrors the v2-row--overdue / --due-soon pattern on the row left
   border. The risk dot sits inline on the direction cell so it's
   visible on desktop (horizontal row) and also on mobile card Line 1. */
.v2-risk-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-right: 6px;
  vertical-align: middle;
  box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.05);
}
.v2-risk-dot--critical,
.v2-risk-dot--high { background: var(--v2-red); }
.v2-risk-dot--medium { background: var(--v2-yellow); }
} /* close @layer components */

@layer mobile-overrides {
@media (max-width: 600px) {
  .v2-at-risk-item {
    grid-template-columns: auto 1fr auto;
    row-gap: 2px;
  }
  .v2-at-risk-reason { max-width: 100%; grid-column: 1 / -1; }
  .v2-at-risk-summary { display: none; }
}
}

@layer components {

/* ---------- Pagination ---------- */
.v2-pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 16px 0;
  font-size: 0.85rem;
  color: var(--v2-text-secondary);
}
.v2-page-info {
  min-width: 80px;
  text-align: center;
}

/* ---------- Closed Footer (Chunk 3, 2026-04-28) ----------
   Tappable Fulfilled / Partial / Missed pills with one shared expandable
   panel. Pattern: Slack emoji-reactions / Linear status filters — single-
   select pill bar. Replaces the prior twin accordions (v2-completed-hero
   + v2-missed-hero). Mockup canon: /mockups/dashboard-hotlist.html. */
.v2-closed-footer {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
  margin-top: 14px;
  padding: 14px 18px;
  background: var(--v2-bg-card);
  border: 1px solid var(--v2-border);
  border-radius: 8px;
  color: var(--v2-text-muted);
  font-size: 0.85rem;
}
.v2-closed-footer-label {
  color: var(--v2-text-faint, #64748b);
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  margin-right: 6px;
  font-weight: 600;
}
.v2-closed-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 12px;
  border-radius: 999px;
  border: 1px solid var(--v2-border);
  background: transparent;
  color: var(--v2-text-muted);
  font-size: 0.8rem;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
  font-family: inherit;
}
.v2-closed-pill:hover { color: var(--v2-text); border-color: var(--v2-text-muted); }
.v2-closed-pill[aria-pressed="true"] {
  background: var(--v2-orange-bg, rgba(232, 119, 34, 0.12));
  border-color: var(--v2-orange);
  color: var(--v2-text);
}
.v2-closed-pill:focus-visible {
  outline: 2px solid var(--v2-orange);
  outline-offset: 1px;
}
.v2-closed-count {
  font-size: 0.72rem;
  font-weight: 600;
  padding: 1px 7px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.06);
  color: inherit;
}
.v2-closed-pill--fulfilled .v2-closed-count { background: rgba(34, 197, 94, 0.18); color: var(--v2-green); }
.v2-closed-pill--partial   .v2-closed-count { background: rgba(245, 158, 11, 0.18); color: var(--v2-yellow, #f59e0b); }
.v2-closed-pill--missed    .v2-closed-count { background: rgba(239, 68, 68, 0.18); color: var(--v2-red); }
.v2-closed-footer-spacer { flex: 1; }
.v2-closed-footer-window {
  font-size: 0.74rem;
  color: var(--v2-text-faint, #64748b);
}

/* Expandable panel — single panel, content swapped per active pill. */
.v2-closed-panel {
  margin-top: -1px;
  background: var(--v2-bg-card);
  border: 1px solid var(--v2-border);
  border-top: none;
  border-radius: 0 0 8px 8px;
  overflow: hidden;
  padding: 8px 18px 12px;
}
.v2-closed-empty {
  padding: 24px;
  text-align: center;
  color: var(--v2-text-muted);
  font-size: 0.88rem;
}
.v2-closed-empty-glyph {
  font-size: 1.4rem;
  margin-bottom: 6px;
  color: var(--v2-green);
}
.v2-closed-empty-sub {
  margin-top: 8px;
  font-size: 0.78rem;
  color: var(--v2-text-faint, #64748b);
}
.v2-closed-empty strong { color: var(--v2-text); }

/* Done-row item — same shape as the legacy completed/missed-list rows
   so existing data-undo-completed / data-undo-missed handlers keep working. */
.v2-closed-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--v2-border);
}
.v2-closed-item:last-child { border-bottom: none; }
.v2-closed-item-body { flex: 1; min-width: 0; }
.v2-closed-item-meta {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
  font-size: 0.78rem;
  color: var(--v2-text-secondary);
}
.v2-closed-item-who { font-weight: 500; }
.v2-closed-item-date {
  color: var(--v2-text-muted);
  font-size: 0.72rem;
}
.v2-closed-item-what {
  font-size: 0.86rem;
  color: var(--v2-text);
  margin-top: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.v2-closed-item-undo { font-size: 0.72rem; padding: 4px 10px; flex-shrink: 0; }

/* Status glyph inside the panel — replaces the action pills (read-only). */
.v2-status-glyph {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 700;
  color: white;
}
.v2-status-glyph--done    { background: var(--v2-green); }
.v2-status-glyph--partial { background: var(--v2-yellow, #f59e0b); }
.v2-status-glyph--missed  { background: var(--v2-red); }

/* Closed-row inline status badge */
.v2-closed-badge {
  font-size: 0.68rem;
  padding: 1px 7px;
  border-radius: 9999px;
  font-weight: 600;
}
.v2-closed-badge--ontime  { background: rgba(34, 197, 94, 0.14);  color: var(--v2-green); }
.v2-closed-badge--late    { background: rgba(234, 179, 8, 0.14); color: #eab308; }
.v2-closed-badge--partial { background: rgba(245, 158, 11, 0.14); color: var(--v2-yellow, #f59e0b); }
.v2-closed-badge--missed  { background: rgba(239, 68, 68, 0.14);  color: var(--v2-red); }
/* (Mobile breakpoint for the closed footer lives in the @layer
   mobile-overrides block at the bottom of this file — see the
   v2CssLayers test that pins this convention.) */

/* ---------- Empty States ---------- */
.v2-empty {
  text-align: center;
  padding: 32px 16px;
  color: var(--v2-text-muted);
  font-size: 0.9rem;
}
.v2-empty-state {
  text-align: center;
  padding: 48px 16px;
  color: var(--v2-text-muted);
}
.v2-empty-state h3 { color: var(--v2-text); margin: 16px 0 8px; font-size: 1.1rem; }
.v2-empty-state p { margin: 0 0 16px; font-size: 0.9rem; }

/* ---------- Toast ---------- */
.v2-toast-container {
  position: fixed;
  bottom: 20px;
  right: 20px;
  z-index: 10000;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.v2-toast {
  background: var(--v2-bg-card);
  border: 1px solid var(--v2-border);
  border-radius: var(--v2-radius);
  padding: 10px 16px;
  box-shadow: var(--v2-shadow-md);
  font-size: 0.85rem;
  animation: v2-slide-in 0.2s ease-out;
}
.v2-toast--success { border-left: 3px solid var(--v2-green); }
.v2-toast--error { border-left: 3px solid var(--v2-red); }

/* Undo toast (5-second window). Sits in same container as regular
   toasts but carries an inline Undo button. See showUndoToast() in
   dashboard-v2.js + tests/services/v2UndoOutcome.test.js. */
.v2-toast--undo {
  display: flex;
  align-items: center;
  gap: 14px;
  min-width: 220px;
}
.v2-toast-undo-btn {
  background: transparent;
  border: 1px solid var(--v2-border, #e2e8f0);
  color: var(--v2-accent, #f97316);
  font-weight: 600;
  font-size: 0.78rem;
  padding: 4px 10px;
  border-radius: 4px;
  cursor: pointer;
  letter-spacing: 0.3px;
  text-transform: uppercase;
}
.v2-toast-undo-btn:hover {
  background: var(--v2-bg-hover, rgba(0,0,0,0.05));
  border-color: var(--v2-accent, #f97316);
}

@keyframes v2-slide-in {
  from { transform: translateX(100%); opacity: 0; }
  to { transform: translateX(0); opacity: 1; }
}

/* ---------- Tick Banner (autonomous intelligence alerts) ---------- */
.v2-tick-banner {
  background: var(--v2-bg-card);
  border: 1px solid var(--v2-blue);
  border-radius: var(--v2-radius);
  margin-bottom: 12px;
  overflow: hidden;
  box-shadow: var(--v2-shadow-sm);
}
.v2-tick-header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 16px;
  background: var(--v2-blue-bg);
  /* Body text dark for sunlight readability — blue-on-blue-tint
     fails WCAG AA outdoors. The "Redas noticed:" label stays in
     bold orange via the strong rule below to pop as the prefix. */
  color: #1a1a1a;
  font-size: 0.85rem;
}
.v2-tick-header strong {
  color: var(--v2-orange);
  font-weight: 700;
}
[data-theme="dark"] .v2-tick-header { color: var(--v2-text); }
[data-theme="dark"] .v2-tick-header strong { color: var(--v2-orange); }
.v2-tick-dismiss {
  margin-left: auto;
  background: none;
  border: none;
  color: var(--v2-blue);
  font-size: 1.2rem;
  cursor: pointer;
  padding: 0 4px;
  line-height: 1;
}

/* ---------- Status Pills (for tables) ---------- */
.v2-status {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 10px;
  font-size: 0.75rem;
  font-weight: 600;
}
.v2-status--open { background: var(--v2-blue-bg); color: var(--v2-blue); }
.v2-status--in-progress { background: var(--v2-yellow-bg); color: var(--v2-yellow); }
.v2-status--done { background: var(--v2-green-bg); color: var(--v2-green); }
.v2-status--failed { background: var(--v2-red-bg); color: var(--v2-red); }
.v2-status--processing { background: var(--v2-orange-bg); color: var(--v2-orange); }

/* ============================================================
   RESPONSIVE — Mobile First
   ============================================================ */
} /* close @layer components */

@layer mobile-overrides {
/* Tablet */
@media (max-width: 1024px) {
  .v2-col-headers .v2-h-notes { display: none; }
  .v2-row-notes { display: none; }
}

/* Mobile */
@media (max-width: 640px) {
  .v2-container { padding: 8px; }

  /* Stats: 2x2 grid. Hide the reliability breakdown ("2 on time · 6
     late · 10 missed") on mobile — it overflowed the card boundary
     and made the reliability tile taller than its three siblings.
     The breakdown is reachable on tap (full reliability tab) so
     no information is lost. */
  .v2-stats { grid-template-columns: repeat(2, 1fr); gap: 8px; align-items: stretch; }
  .v2-stat { padding: 10px 12px; gap: 8px; }
  .v2-stat-value { font-size: 1.1rem; }
  .v2-stat-icon { width: 30px; height: 30px; }
  .v2-stat-breakdown { display: none; }

  /* Banner mobile layout — text on top, button(s) full-width below.
     The horizontal layout fights for space on portrait phones; the
     "Resolve" / "Review Now" labels were getting clipped. Stacking
     gives each line breathing room. */
  .v2-banner {
    flex-wrap: wrap;
    align-items: stretch;
  }
  .v2-banner > span {
    flex: 1 1 100%;
  }
  .v2-banner-action {
    flex: 1 1 auto;
    margin-left: 0;
    text-align: center;
    padding: 10px 14px;
    font-size: 0.85rem;
  }
  .v2-banner-dismiss {
    flex: 0 0 auto;
  }

  /* Column headers hidden on mobile */
  .v2-col-headers { display: none; }

  /* Commitment rows stack on mobile */
  .v2-row {
    flex-wrap: wrap;
    padding: 10px 12px;
    gap: 2px 0;
  }
  .v2-row-check { width: 28px; }
  .v2-row-dir { width: calc(100% - 28px); font-size: 0.8rem; order: 1; }
  .v2-row-what { width: calc(100% - 28px); margin-left: 28px; white-space: normal; order: 2; font-size: 0.85rem; }
  .v2-row-due { width: auto; margin-left: 28px; text-align: left; font-size: 0.75rem; order: 3; }
  .v2-row-notes { width: calc(100% - 28px); margin-left: 28px; padding-left: 0; order: 4; }
  /* Pre-2026-04-26 the kebab was hidden on tablet/phone, leaving no
     path to Mark Fulfilled/Partial/Missed without the small checkbox
     (which users didn't recognize as tappable). Field report: "kebab
     menu is being blocked." Now: always show the kebab. */
  .v2-row-actions { display: flex; }

  /* Tables scroll horizontally */
  .v2-table { min-width: 600px; }

  /* Calendar grid: 1 column */
  .v2-cal-grid { grid-template-columns: 1fr; }

  /* Schedule actions stack */
  .v2-schedule-actions { flex-direction: column; }
  .v2-schedule-actions .v2-btn--sm { width: 100%; justify-content: center; }

  /* Reliability */
  .v2-rel-summary { grid-template-columns: repeat(2, 1fr); gap: 8px; }
  .v2-rel-grid { grid-template-columns: 1fr; }

  /* Filter bar — allow wrap on mobile so everything is reachable
   * without horizontal swipe. Compact selects and search inputs so
   * they don't hoard width. */
  .v2-filter-bar {
    flex-wrap: wrap;
    overflow-x: visible;
    padding-bottom: 4px;
    gap: 6px;
  }
  .v2-filter { white-space: nowrap; flex-shrink: 0; }
  .v2-filter-search {
    min-width: 0;
    width: 100%;
    flex-basis: 100%;
  }
  .v2-select {
    min-width: 0;
    flex: 1 1 auto;
  }

  /* Toolbar stacks */
  .v2-tab-toolbar { flex-direction: column; }
  .v2-toolbar-right { width: 100%; }
}

/* Small mobile */
@media (max-width: 380px) {
  .v2-stats { grid-template-columns: repeat(2, 1fr); gap: 6px; }
  .v2-stat { padding: 8px 10px; }
  .v2-stat-value { font-size: 1rem; }
  .v2-stat-label { font-size: 0.7rem; }
  .v2-meeting-header { padding: 6px 10px; }
  .v2-row { padding: 8px 10px; }
}
}

@layer components {

/* ---------- Collapse/Expand Bar ---------- */
.v2-collapse-bar {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-bottom: 8px;
}

/* ---------- Completion Suggestions ---------- */
.v2-completion-banner {
  background: var(--v2-bg-card);
  border: 1px solid var(--v2-green);
  border-radius: var(--v2-radius);
  margin-bottom: 12px;
  overflow: hidden;
  box-shadow: var(--v2-shadow-sm);
}
.v2-completion-header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 16px;
  background: var(--v2-green-bg);
  color: var(--v2-green);
  font-size: 0.85rem;
  font-weight: 500;
}
.v2-completion-item {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 16px;
  border-top: 1px solid var(--v2-border-light);
}
.v2-completion-item:hover { background: var(--v2-bg-hover); }

.v2-completion-info { flex: 1; min-width: 0; }
.v2-completion-what { font-weight: 600; font-size: 0.85rem; margin-bottom: 2px; }
.v2-completion-excerpt {
  font-size: 0.78rem;
  color: var(--v2-text-secondary);
  font-style: italic;
  margin-bottom: 2px;
  line-height: 1.4;
}
.v2-completion-reasoning {
  font-size: 0.72rem;
  color: var(--v2-text-muted);
}
.v2-completion-confidence {
  font-size: 0.65rem;
  font-weight: 600;
  padding: 2px 6px;
  border-radius: 8px;
  background: var(--v2-green-bg);
  color: var(--v2-green);
}
.v2-completion-actions {
  display: flex;
  gap: 6px;
  flex-shrink: 0;
  align-items: center;
}

/* ---------- Inbox Items ---------- */
.v2-inbox-item {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 16px;
  background: var(--v2-bg-card);
  border-radius: var(--v2-radius);
  border-left: 3px solid var(--v2-orange);
  margin-bottom: 8px;
  box-shadow: var(--v2-shadow-sm);
  transition: box-shadow 0.15s;
}
.v2-inbox-item:hover { box-shadow: var(--v2-shadow-md); }
.v2-inbox-content { flex: 1; min-width: 0; }
.v2-inbox-actions {
  display: flex;
  gap: 6px;
  flex-shrink: 0;
  align-items: center;
}

} /* close @layer components */

@layer mobile-overrides {
@media (max-width: 640px) {
  .v2-inbox-item { flex-direction: column; }
  .v2-inbox-actions { width: 100%; justify-content: flex-end; }
}
}

@layer components {

/* ============================================================
   Inline Editing & Date Picker
   ============================================================ */

/* Inline editable fields */
.v2-editable { cursor: pointer; border-radius: 2px; transition: background 0.15s; }
.v2-editable:hover { background: var(--v2-bg-hover); }

.v2-inline-input {
  background: var(--v2-bg-input);
  border: 1px solid var(--v2-orange);
  border-radius: 3px;
  color: var(--v2-text);
  font: inherit;
  padding: 1px 4px;
  width: 100%;
  outline: none;
}

@keyframes v2-flash {
  0% { background: var(--v2-orange-bg); }
  100% { background: transparent; }
}

/* Date picker inline — compact quick-select row + optional custom row.
   Common construction deadlines (today/tomorrow/this Fri/next wk) are
   one tap; the calendar is opt-in via "Pick date". */
.v2-date-picker {
  margin-top: 4px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.v2-date-quick {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.v2-date-quick-pill {
  background: var(--v2-bg-input);
  border: 1px solid var(--v2-border);
  border-radius: 999px;
  color: var(--v2-text);
  padding: 6px 10px;
  font-size: 0.78rem;
  font-family: var(--v2-font);
  cursor: pointer;
  line-height: 1;
  min-height: 32px;
}
.v2-date-quick-pill:hover {
  border-color: var(--v2-orange);
  color: var(--v2-orange);
}
.v2-date-quick-pill--custom {
  border-style: dashed;
  opacity: 0.85;
}
.v2-date-custom {
  display: none;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
.v2-date-custom.open { display: flex; }
.v2-date-input {
  background: var(--v2-bg-input);
  border: 1px solid var(--v2-orange);
  border-radius: var(--v2-radius-sm);
  color: var(--v2-text);
  padding: 4px 6px;
  font-size: 0.78rem;
  width: auto;
  font-family: var(--v2-font);
  flex: 0 0 auto;
}
.v2-date-save,
.v2-date-cancel { flex: 0 0 auto; }

} /* close @layer components */

@layer mobile-overrides {
@media (max-width: 600px) {
  .v2-date-quick-pill { min-height: 36px; padding: 8px 12px; font-size: 0.85rem; }
  .v2-date-input { font-size: 16px; padding: 6px 8px; }
  .v2-date-save, .v2-date-cancel { min-height: 36px; }
}

/* Mobile: show notes (they're hidden on tablet but should show on mobile) */
@media (max-width: 640px) {
  .v2-row-notes { display: block; }
}
}

@layer components {

/* ============================================================
   Action Items Tab — Polish
   ============================================================ */
.v2-action-items-table td.v2-desc-cell {
  max-width: 360px;
  white-space: normal;
  word-break: break-word;
  line-height: 1.4;
}
.v2-resolution-notes {
  display: block;
  font-size: 0.75rem;
  color: var(--v2-text-muted);
  font-style: italic;
  margin-top: 4px;
  line-height: 1.3;
}
.v2-action-empty {
  text-align: center;
  padding: 48px 16px;
  color: var(--v2-text-muted);
}
.v2-action-empty svg { opacity: 0.35; margin-bottom: 12px; }
.v2-action-empty h3 { color: var(--v2-text); margin: 8px 0; font-size: 1.1rem; }
.v2-action-empty p { margin: 0 0 16px; font-size: 0.88rem; }

/* ============================================================
   Contracts Tab — Polish
   ============================================================ */
.v2-contract-summary {
  display: block;
  font-size: 0.75rem;
  color: var(--v2-text-muted);
  margin-top: 3px;
  line-height: 1.3;
  max-width: 280px;
  white-space: normal;
}
.v2-risk-badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 10px;
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
}
.v2-risk-badge--high { background: var(--v2-red-bg); color: var(--v2-red); }
.v2-risk-badge--medium { background: var(--v2-yellow-bg); color: var(--v2-yellow); }
.v2-risk-badge--low { background: var(--v2-green-bg); color: var(--v2-green); }
.v2-contract-meta {
  font-size: 0.72rem;
  color: var(--v2-text-muted);
}
.v2-contracts-empty-state {
  text-align: center;
  padding: 56px 16px;
  color: var(--v2-text-muted);
}
.v2-contracts-empty-state svg { opacity: 0.3; margin-bottom: 12px; }
.v2-contracts-empty-state h3 { color: var(--v2-text); margin: 12px 0 6px; font-size: 1.15rem; }
.v2-contracts-empty-state p { margin: 0 0 8px; font-size: 0.88rem; line-height: 1.5; }

/* ============================================================
   Reliability Tab — Polish
   ============================================================ */
.v2-rel-card { cursor: pointer; }
.v2-rel-card-expanded {
  width: 100%;
  border-top: 1px solid var(--v2-border-light);
  padding: 10px 0 4px;
  display: none;
}
.v2-rel-card.expanded .v2-rel-card-expanded { display: block; }
.v2-rel-commitment-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 4px 0;
  font-size: 0.78rem;
  border-bottom: 1px solid var(--v2-border-light);
}
.v2-rel-commitment-row:last-child { border-bottom: none; }
.v2-rel-commitment-what { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v2-rel-commitment-status { flex-shrink: 0; margin-left: 8px; }
.v2-sparkline-wrap {
  margin-top: 6px;
  height: 24px;
  overflow: hidden;
}
.v2-no-data-text {
  font-size: 0.78rem;
  color: var(--v2-text-muted);
  font-style: italic;
  padding: 2px 0;
}

/* ============================================================
   Inbox Tab — Polish
   ============================================================ */
.v2-inbox-item--high {
  border-left-color: var(--v2-green);
}
.v2-inbox-item--low {
  border-left-color: var(--v2-yellow);
}
.v2-inbox-quote {
  background: var(--v2-bg-hover);
  border-left: 2px solid var(--v2-text-muted);
  padding: 6px 10px;
  margin-top: 6px;
  border-radius: 0 var(--v2-radius-sm) var(--v2-radius-sm) 0;
  font-size: 0.78rem;
  color: var(--v2-text-secondary);
  font-style: italic;
  line-height: 1.4;
}
.v2-inbox-source-link {
  font-size: 0.75rem;
  color: var(--v2-blue);
  text-decoration: none;
  cursor: pointer;
}
.v2-inbox-source-link:hover { text-decoration: underline; }
.v2-inbox-confidence-bar {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 4px;
}
.v2-inbox-section-label {
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--v2-text-muted);
  padding: 12px 0 6px;
  border-bottom: 1px solid var(--v2-border-light);
  margin-bottom: 8px;
}
.v2-inbox-section-label:first-child { padding-top: 0; }
.v2-bulk-confirm-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 16px;
  background: var(--v2-green-bg);
  border: 1px solid rgba(34, 197, 94, 0.2);
  border-radius: var(--v2-radius);
  margin-bottom: 12px;
  font-size: 0.85rem;
  color: var(--v2-green);
}
.v2-bulk-confirm-bar .v2-btn { flex-shrink: 0; }

/* ============================================
   FAB Buttons (Voice Memo + Call)
   Ported from dashboard.css for V2 parity.
   ============================================ */
.fab-container {
  position: fixed;
  bottom: 24px;
  right: 24px;
  display: flex;
  flex-direction: row;
  gap: 12px;
  z-index: 9000;
}
.fab {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  transition: transform 0.2s, box-shadow 0.2s;
}
.fab:hover { transform: scale(1.1); box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2); }
.fab:active { transform: scale(0.95); }
.fab-record {
  background: linear-gradient(135deg, #ef4444, #dc2626);
  color: white;
  box-shadow: 0 4px 12px rgba(239, 68, 68, 0.4);
}
.fab-record:hover { box-shadow: 0 6px 16px rgba(239, 68, 68, 0.5); }
.fab-record.recording { animation: recordPulse 1s ease-in-out infinite; }
@keyframes recordPulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.1); } }

.fab-call {
  background: linear-gradient(135deg, #22c55e, #16a34a);
  color: white;
  box-shadow: 0 4px 12px rgba(34, 197, 94, 0.4);
}
.fab-call:hover { box-shadow: 0 6px 16px rgba(34, 197, 94, 0.5); }

#call-modal.show { display: flex !important; }

.v2-container { padding-bottom: 100px; }

/* Speaker tags in recording overlay */
.speaker-tag {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 10px;
  background: rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  font-size: 0.8rem;
  color: white;
}
.speaker-tag-time { color: #94a3b8; font-size: 0.7rem; }

/* Live feed items */
.live-feed-item {
  padding: 6px 10px;
  background: rgba(255, 255, 255, 0.05);
  border-radius: 6px;
  font-size: 0.8rem;
}
.live-feed-who { font-weight: 600; color: #e87722; font-size: 0.75rem; }
.live-feed-what { color: #e2e8f0; margin-top: 2px; }

/* Mute button active state */
#call-mute-btn.active { background: rgba(239, 68, 68, 0.3); }

/**
 * Hide FABs on portrait-mobile viewports (<768px) to prevent pocket
 * activation. A PM in the field has the phone in their pocket; the
 * record/call FABs sit exactly where a thumb lands when fishing the
 * phone out. Field feedback from V1 was that accidental recording
 * was more annoying than the loss of tap-to-record. Desktop and
 * tablets (>=768px) keep both FABs.
 *
 * The call modal, recording overlay, and all downstream handlers
 * stay in the DOM so they work if we later add a gesture-guarded
 * variant (e.g. long-press to activate).
 */
} /* close @layer components */

@layer mobile-overrides {
@media (max-width: 768px) {
  /* 2026-05-03: reverted from hold-to-record to V1's tap-to-toggle.
     The call FAB is gesture-gated by its existing modal flow
     (tap → modal → tap dial). Pocket activation risk on the mic
     FAB is the trade-off accepted for V1-flow simplicity. */
  .fab-container,
  .v2-fab-container {
    /* Slightly lift away from the bottom safe area on iOS PWAs
       so the home-bar gesture doesn't overlap the FABs. The
       mobile-overrides @layer already wins over the components
       layer (see top-of-file @layer order), so no !important. */
    bottom: calc(env(safe-area-inset-bottom, 0px) + 16px);
  }
}
}

@layer components {

/* ============================================
   V2 Call modal recipient picker (project members)
   ============================================ */
.v2-call-picker-row {
  display: flex;
  gap: 8px;
  margin-bottom: 10px;
}
.v2-call-picker-row select {
  flex: 1;
  padding: 10px 12px;
  background: var(--v2-bg-input, #f8fafc);
  border: 1px solid var(--v2-border, #e2e8f0);
  border-radius: 8px;
  color: var(--text-primary, #f1f5f9);
  font-size: 0.9rem;
  outline: none;
  box-sizing: border-box;
  font-family: inherit;
}
.v2-call-picker-divider {
  text-align: center;
  font-size: 0.75rem;
  color: var(--v2-text-secondary, #64748b);
  margin: 8px 0;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* ============================================================
 * PORTRAIT-MOBILE COMMITMENT CARD LAYOUT (< 600px)
 *
 * ONLY applies to narrow portrait viewports. Landscape mobile
 * (width > 600px) already works — keeps the horizontal row
 * layout untouched. This block transforms rows into 2-line
 * cards only when the viewport is actually too narrow for a
 * row to breathe (iPhone 14/15 portrait ≈ 390-430px).
 *
 * Density target: 5-6 collapsed cards visible on a 844px-tall
 * portrait viewport. Each card is 2-3 lines tall collapsed,
 * expands on tap to full detail.
 * ============================================================ */

/* Status pill — mobile-only (desktop hides via below) */
.v2-status-pill {
  display: none;
  padding: 1px 7px;
  border-radius: 10px;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.3px;
  text-transform: uppercase;
  vertical-align: middle;
  white-space: nowrap;
  margin-left: 6px;
}
.v2-status-pill--done   { background: rgba(110,118,129,0.2);   color: #8b949e; }
.v2-status-pill--missed { background: rgba(248,81,73,0.15);    color: #f85149; }
.v2-status-pill--soft   { background: rgba(247,131,22,0.15);   color: #f78316; border: 1px solid rgba(247,131,22,0.35); }
.v2-status-pill--firm   { background: rgba(46,160,67,0.15);    color: #2ea043; }

/* Red Team adversarial-review pill — credibility signal, surfaces on
   every commitment row that has a red_team_review JSONB. Three states
   per migration 147 + sprint brief §3.3:
     weak     → ✓ Red Team    (green / Validated)
     moderate → ⚠ Review       (yellow / Review Recommended)
     strong   → ⚠ Disputed     (red / Disputed Interpretation)
   Shows on both desktop and mobile (unlike status pill which is mobile-only)
   because the Red Team signal is a load-bearing credibility primitive. */
.v2-red-team-pill {
  display: inline-flex;
  align-items: center;
  padding: 1px 7px;
  border-radius: 10px;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.3px;
  text-transform: uppercase;
  vertical-align: middle;
  white-space: nowrap;
  margin-left: 6px;
  cursor: help;
}
.v2-red-team-pill--validated { background: rgba(46,160,67,0.15);  color: #2ea043; }
.v2-red-team-pill--review    { background: rgba(247,131,22,0.15); color: #f78316; border: 1px solid rgba(247,131,22,0.35); }
.v2-red-team-pill--disputed  { background: rgba(248,81,73,0.15);  color: #f85149; border: 1px solid rgba(248,81,73,0.35); }

/* Detail-modal Red Team Review panel — full breakdown with challenges
   list + rationale paragraph. Renders below the hash row. */
.v2-red-team-panel {
  margin: 12px 0;
  padding: 12px;
  border-radius: 8px;
  border: 1px solid var(--v2-border, #334155);
  background: rgba(15, 23, 42, 0.5);
  font-size: 0.82rem;
}
.v2-red-team-panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
  font-weight: 600;
  color: var(--v2-text, #e2e8f0);
}
.v2-red-team-rationale {
  color: var(--v2-text-secondary, #94a3b8);
  font-style: italic;
  line-height: 1.5;
  margin: 6px 0 8px;
}
.v2-red-team-challenges {
  list-style: none;
  padding: 0;
  margin: 0;
}
.v2-red-team-challenges li {
  display: flex;
  gap: 8px;
  padding: 4px 0;
  color: var(--v2-text, #e2e8f0);
  font-size: 0.78rem;
  line-height: 1.4;
}
.v2-red-team-challenges .severity {
  flex-shrink: 0;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 0 6px;
  border-radius: 3px;
}
.v2-red-team-challenges .severity-high { background: rgba(248,81,73,0.18);   color: #f85149; }
.v2-red-team-challenges .severity-med  { background: rgba(247,131,22,0.18);  color: #f78316; }
.v2-red-team-challenges .severity-low  { background: rgba(110,118,129,0.18); color: #8b949e; }

/* ---------- Risk brief closure form ---------- */
.v2-risk-draft-area {
  width: 100%; padding: 8px;
  background: var(--v2-bg); color: var(--v2-text);
  border: 1px solid var(--v2-border); border-radius: 6px;
  font-size: 0.78rem; font-family: inherit;
  resize: vertical;
}
.v2-risk-closure-row1 {
  display: flex; gap: 6px; align-items: center; margin-top: 6px;
}
.v2-risk-channel {
  font-size: 0.78rem; padding: 4px 6px;
  background: var(--v2-bg); color: var(--v2-text);
  border: 1px solid var(--v2-border); border-radius: 4px;
}
.v2-risk-recipient {
  flex: 1; min-width: 180px;
  font-size: 0.78rem; padding: 4px 8px;
  background: var(--v2-bg); color: var(--v2-text);
  border: 1px solid var(--v2-border); border-radius: 4px;
}
.v2-risk-closure-row2 {
  display: flex; gap: 6px; margin-top: 6px;
}

} /* close @layer components */

@layer mobile-overrides {
@media (max-width: 600px) {
  /* Channel + recipient stack vertically — recipient is long, can't
   * share a row with select at 390px. */
  .v2-risk-closure-row1 { flex-direction: column; align-items: stretch; }
  .v2-risk-channel, .v2-risk-recipient {
    width: 100%; min-width: 0;
    font-size: 16px;    /* kill iOS zoom */
    padding: 10px 12px;
    min-height: 44px;
  }
  .v2-risk-draft-area { font-size: 16px; }
  /* Action row — three buttons equal-flex so none wrap off-screen. */
  .v2-risk-closure-row2 {
    gap: 4px;
  }
  .v2-risk-btn {
    flex: 1 1 0;
    font-size: 0.82rem;
    padding: 10px 6px;
    white-space: nowrap;
    min-height: 44px;
  }
}
}

@layer components {

/* ---------- Inbox details collapsible ---------- */
/* Desktop: open by default and visually flat (no chevron).
 * Mobile:  collapsed by default with a visible chevron summary
 *          so inbox rows stay dense. */
.v2-inbox-details { margin-top: 6px; }
.v2-inbox-details[open] .v2-inbox-details-summary { margin-bottom: 6px; }
.v2-inbox-details-summary {
  cursor: pointer;
  font-size: 0.76rem;
  color: var(--v2-text-muted, #94a3b8);
  user-select: none;
  list-style: none;
}
.v2-inbox-details-summary::-webkit-details-marker { display: none; }
.v2-inbox-details-summary::before { content: '▸ '; color: var(--v2-text-muted); font-size: 0.7rem; }
.v2-inbox-details[open] .v2-inbox-details-summary::before { content: '▾ '; }

.v2-inbox-followup {
  padding: 8px 10px; margin-top: 4px;
  border-left: 3px solid #f78316;
  background: rgba(247,131,22,0.06);
  border-radius: 4px; font-size: 0.78rem;
}
.v2-inbox-followup-head { color: #e87722; font-weight: 600; margin-bottom: 2px; }
.v2-inbox-followup-by { margin-top: 4px; color: var(--v2-text-secondary); }

.v2-inbox-conditions {
  padding: 8px 10px; margin-top: 6px;
  border-left: 3px solid #2ea043;
  background: rgba(46,160,67,0.05);
  border-radius: 4px; font-size: 0.78rem; line-height: 1.4;
}
.v2-inbox-conditions-head {
  color: #2ea043; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.3px; font-size: 0.7rem; margin-bottom: 2px;
}

} /* close @layer components */

@layer mobile-overrides {
/* Desktop: force details open + hide the chevron summary entirely —
 * the two blocks just render stacked, same as before. Lives in the
 * mobile-overrides layer so all @media branches share the same
 * cascade lane (mobile-overrides last-wins applies symmetrically). */
@media (min-width: 601px) {
  .v2-inbox-details > .v2-inbox-details-summary { display: none; }
  .v2-inbox-details:not([open]) > .v2-inbox-details-body { display: block; }
}
}

@layer components {

/* ---------- PPC card ---------- */
.v2-ppc-card {
  background: var(--v2-bg-card, #ffffff);
  border: 1px solid var(--v2-border, #e2e8f0);
  border-radius: 10px;
  padding: 14px 18px;
  margin-bottom: 14px;
}
.v2-ppc-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.v2-ppc-hero { display: flex; align-items: center; gap: 16px; }
.v2-ppc-value { font-size: 2.2rem; font-weight: 800; line-height: 1; color: var(--v2-text, #1e293b); }
.v2-ppc-label { font-size: 0.72rem; color: var(--v2-text-muted, #94a3b8); text-transform: uppercase; letter-spacing: 0.5px; margin-top: 3px; }
.v2-ppc-bench { font-weight: 700; font-size: 0.9rem; }
.v2-ppc-counts { font-size: 0.78rem; color: var(--v2-text-secondary, #64748b); margin-top: 3px; }
.v2-ppc-explainer { font-size: 0.72rem; color: var(--v2-text-muted, #94a3b8); text-align: right; max-width: 260px; line-height: 1.4; }
.v2-ppc-explainer strong { color: var(--v2-text-secondary, #64748b); }
.v2-ppc-reasons { margin-top: 12px; font-size: 0.78rem; color: var(--v2-text-secondary, #64748b); }
} /* close @layer components */

@layer mobile-overrides {
@media (max-width: 600px) {
  .v2-ppc-card { padding: 12px 14px; }
  .v2-ppc-value { font-size: 1.7rem; }
  .v2-ppc-hero { gap: 12px; }
  /* Explainer becomes a demoted caption under the counts, left-aligned,
   * shrunk. No more right-stranded text block. */
  .v2-ppc-explainer {
    text-align: left;
    max-width: none;
    flex-basis: 100%;
    font-size: 0.68rem;
    order: 3;
  }
  .v2-ppc-reasons { font-size: 0.72rem; }
}
}

@layer components {

/* Line-1 vs Line-2 badge visibility — desktop shows both inline with
 * the description; portrait mobile moves category + status to Line 2
 * and suppresses REQUESTED/FOLLOW UP badges entirely (they live in
 * the expanded view). */
.v2-mobile-only-inline { display: none; }
.v2-desktop-only-inline { display: inline-block; }

} /* close @layer components */

@layer mobile-overrides {
/* Category badge: shrink on portrait so it doesn't dominate line 2 */
@media (max-width: 600px) {
  .v2-mobile-only-inline { display: inline-block; }
  .v2-desktop-only-inline { display: none; }

  .v2-cat-badge {
    font-size: 0.62rem;
    padding: 1px 6px;
    letter-spacing: 0.3px;
  }
  .v2-status-pill { display: inline-block; }

  /* Hide the desktop header row — columns aren't a mobile concept */
  .v2-thead, .v2-thead-row { display: none; }

  /* Card reshape */
  .v2-row {
    display: block;
    padding: 10px 12px;
    padding-left: 14px;
    /* Right padding reserves a 40px gutter for the absolutely-positioned
       .v2-row-actions kebab (right: 12px + 28px button width = 40px).
       Without this, description text wraps full-width and runs UNDER
       the kebab on mobile — Michael's field report 2026-05-01:
       "kebabs are still blocking the commitment text on the mobile app". */
    padding-right: 44px;
    /* Thinned from 4px → 3px (2026-05-01). The .v2-meeting parent
       already carries a 3px border-left for status; combined the two
       were 7px of color on the left edge, which read as "thick border
       eating content" on portrait phones. 3px on the row preserves
       per-row urgency signal without doubling the color band. */
    border-left: 3px solid transparent;
    border-bottom: 1px solid var(--v2-border);
    position: relative;
    touch-action: pan-y;
    cursor: pointer;
    transition: transform 0.18s ease, background 0.12s ease;
  }

  /* Hide desktop-only row chrome */
  .v2-row-check { display: none; }
  /* Pre-2026-04-26 the kebab was hidden on portrait mobile, forcing
     users to discover the v2-row--expanded-mobile state before they
     could see status actions. Now: always show the kebab — it's the
     only obvious tap-target for Mark Fulfilled/Partial/Missed. */
  .v2-row-actions { display: flex; }

  /* Bulk-select checkbox — pin to top-left of each card on mobile.
     Field report 2026-04-26: the per-row select column collapsed to
     0px on portrait because the card layout went `display: block`,
     which stacked v2-row-select above the description and ate its
     own width. Position it absolutely so it stays visible. The card
     itself reserves room with padding-left:36px. */
  .v2-row {
    padding-left: 36px;
  }
  .v2-row-select {
    position: absolute;
    top: 10px;
    left: 10px;
    width: 22px;
    z-index: 2;
  }
  .v2-bulk-select-cb { width: 18px; height: 18px; }

  /* Line 1: direction (truncated) + description (truncated) */
  .v2-row-dir {
    display: inline;
    width: auto;
    padding: 0;
    font-size: 0.78rem;
    color: var(--v2-text-secondary);
  }
  .v2-row-dir .v2-dir-verb,
  .v2-row-dir .v2-dir-company { display: none; }
  .v2-row-dir .v2-dir-to { display: none; }
  .v2-row-dir .v2-dir-from {
    display: inline-block;
    color: var(--v2-text);
    font-weight: 600;
    /* Cap the counterparty name width so it can't eat the description.
     * 35% gives names up to ~90-110px on a 390px viewport; longer names
     * ellipsize while description still owns the majority of the line. */
    max-width: 35%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: bottom;
  }
  .v2-row-dir .v2-dir-from::after { content: ' →'; color: var(--v2-text-muted); font-weight: normal; }

  .v2-row-what {
    display: inline;
    padding: 0;
    font-weight: 500;
    font-size: 0.85rem;
    color: var(--v2-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
  }
  /* Keep Line-1 inline badges invisible on mobile even if a caller
   * forgot the .v2-desktop-only-inline class — no badges on Line 1. */
  .v2-row-what .v2-request-badge,
  .v2-row-what .v2-followup-badge,
  .v2-row-what .v2-cat-badge:not(.v2-mobile-only-inline) {
    display: none;
  }

  /* Line 2: due date + category + status pill — all inline */
  .v2-row-due {
    display: block;
    width: auto;
    margin-top: 4px;
    font-size: 0.76rem;
    padding: 0;
    white-space: normal;
  }

  /* Collapsed-only — hide notes + everything that would blow density */
  .v2-row-notes { display: none; }
  .v2-row > .v2-dir-company { display: none; }

  /* Expanded state — tap to reveal full detail */
  .v2-row--expanded-mobile {
    background: var(--v2-bg-hover);
    padding-bottom: 14px;
  }
  .v2-row--expanded-mobile .v2-row-what {
    display: block;
    white-space: normal;
    overflow: visible;
    margin-top: 4px;
    font-size: 0.92rem;
    line-height: 1.4;
  }
  .v2-row--expanded-mobile .v2-row-dir {
    display: block;
    font-size: 0.72rem;
    margin-bottom: 2px;
  }
  .v2-row--expanded-mobile .v2-row-dir .v2-dir-verb { display: inline-block; }
  .v2-row--expanded-mobile .v2-row-dir .v2-dir-from::after { content: ''; }
  .v2-row--expanded-mobile .v2-row-dir .v2-dir-to,
  .v2-row--expanded-mobile .v2-row-dir .v2-dir-company { display: inline; }
  .v2-row--expanded-mobile .v2-row-notes {
    display: block;
    margin-top: 8px;
  }
  .v2-row--expanded-mobile .v2-row-actions {
    display: flex;
    /* Override the base position:absolute (right:12px; top:2px;) which
       was anchoring the action buttons over the row's description on
       mobile-expanded rows — visible bug 2026-04-26 where Run Domain
       Analysis / View Related / Detail / Flag rendered on top of the
       commitment text. Static lets them flow below the row content.
       Layer order does the work — no !important needed. */
    position: static;
    right: auto;
    top: auto;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 8px;
  }

  /* Urgency color-coded left border */
  .v2-row--overdue  { border-left-color: #f85149; }
  .v2-row--due-soon { border-left-color: #e6a700; }
  .v2-row--on-track { border-left-color: transparent; }

  /* Project header — make the toggle arrow bigger + clearer */
  .v2-meeting-toggle {
    font-size: 0.75rem;
    margin-right: 8px;
    color: var(--v2-text-muted);
    transition: transform 0.15s ease;
    display: inline-block;
  }
  .v2-meeting--collapsed .v2-meeting-toggle { transform: rotate(-90deg); }
  .v2-meeting--collapsed .v2-meeting-body { display: none; }

  /* Swipe feedback — row transforms left/right during gesture */
  .v2-row--swiping-right { background: rgba(46,160,67,0.12); }
  .v2-row--swiping-left  { background: rgba(248,81,73,0.12); }

  /* Inbox density — also tighten */
  .v2-inbox-item { padding: 10px 12px; }
}
}

@layer components {

/* ===========================================================================
   Domain Personas (Reinforcement Learning Engine — Phase 2)
   The 4-lens output panel that appears below a commitment row when the user
   clicks "Run Domain Analysis". Lightweight by design — collapsible <details>
   tags, no extra deps.
   =========================================================================== */
.v2-row-action--personas {
  background: rgba(120, 90, 200, 0.12);
  border: 1px solid rgba(120, 90, 200, 0.4);
  color: #c8b8ff;
}
.v2-row-action--personas:hover { background: rgba(120, 90, 200, 0.22); }

.v2-persona-panel {
  grid-column: 1 / -1;
  margin: 8px 0 0 0;
  padding: 12px 14px;
  background: rgba(120, 90, 200, 0.06);
  border: 1px solid rgba(120, 90, 200, 0.18);
  border-radius: 6px;
  font-size: 0.85rem;
}
.v2-persona-loading { color: var(--v2-text-muted, #94a3b8); font-style: italic; }
.v2-persona-error   { color: #f99; }
.v2-persona-empty   { color: var(--v2-text-muted, #94a3b8); padding: 4px 0; }

.v2-persona-header {
  font-size: 0.72rem;
  color: var(--v2-text-muted, #94a3b8);
  margin-bottom: 8px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.v2-persona-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 10px;
}

.v2-persona-lens {
  background: rgba(0,0,0,0.25);
  border-radius: 5px;
  padding: 8px 10px;
}
.v2-persona-lens summary {
  cursor: pointer;
  font-weight: 600;
  padding: 2px 0;
  user-select: none;
}
.v2-persona-section { margin-top: 8px; }
.v2-persona-section-label {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--v2-text-muted, #94a3b8);
  margin-bottom: 4px;
}
.v2-persona-lens ul { margin: 4px 0 0 16px; padding: 0; }
.v2-persona-lens li { margin: 4px 0; line-height: 1.35; }

.v2-persona-sev {
  display: inline-block;
  padding: 1px 6px;
  border-radius: 3px;
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.v2-persona-sev--high   { background: rgba(248, 81, 73, 0.25); color: #ffa8a3; }
.v2-persona-sev--medium { background: rgba(220, 165, 60, 0.25); color: #ffd88a; }
.v2-persona-sev--low    { background: rgba(46, 160, 67, 0.25); color: #9be0a3; }


/* ===========================================================
   PM Synthesis Engine — collapsible card on dashboard tab
   ===========================================================
   Lives between the PPC card and the Due-Today hero. Stays
   collapsed by default so it doesn't fight the existing layout
   for vertical real estate. Mobile: stacks the four columns.
*/
.v2-synthesis-card {
  /* Was var(--v2-card-bg, #161b22) — orphan token name (real token is
     --v2-bg-card) caused the dark hex fallback to win in light mode,
     producing the "Synthesis bar is black in a white page" bug. */
  background: var(--v2-bg-card);
  border: 1px solid var(--v2-border);
  border-radius: 8px;
  margin: 12px 0;
  overflow: hidden;
  color: var(--v2-text);
}
.v2-synthesis-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 14px;
  cursor: pointer;
  gap: 12px;
}
.v2-synthesis-title-row { display: flex; align-items: center; gap: 8px; min-width: 0; }
.v2-synthesis-title {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 8px;
}
.v2-synthesis-toggle {
  background: none;
  border: none;
  color: inherit;
  cursor: pointer;
  padding: 2px 4px;
  display: flex;
  align-items: center;
}
.v2-synthesis-toggle[aria-expanded="true"] svg { transform: rotate(180deg); }
.v2-synthesis-toggle svg { transition: transform 0.15s ease; }
.v2-synthesis-degraded {
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  background: rgba(220, 165, 60, 0.2);
  color: #ffd88a;
  padding: 1px 6px;
  border-radius: 3px;
}
.v2-synthesis-actions { display: flex; align-items: center; gap: 10px; }
.v2-synthesis-meta {
  font-size: 0.72rem;
  color: var(--v2-text-muted, #94a3b8);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 260px;
}
.v2-synthesis-body {
  padding: 6px 14px 14px;
  border-top: 1px solid var(--v2-border, #e2e8f0);
}
.v2-synthesis-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px;
}
.v2-synthesis-col h4 {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--v2-text-muted, #94a3b8);
  margin: 8px 0 6px;
}
.v2-synthesis-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-height: 260px;
  overflow-y: auto;
}
.v2-synthesis-list li {
  background: rgba(255, 255, 255, 0.02);
  border-left: 2px solid #2a3038;
  padding: 6px 8px;
  border-radius: 3px;
  font-size: 0.78rem;
  line-height: 1.35;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 6px;
}
/* Specificity-bumped (0,2,1) to defeat .v2-synthesis-list li (0,1,1)
   without !important. Same component layer either way. */
.v2-synthesis-list li.v2-synthesis-empty {
  font-style: italic;
  color: var(--v2-text-muted, #94a3b8);
  background: none;
  border-left: 2px solid transparent;
}
.v2-syn-if { font-weight: 500; }
.v2-syn-then { color: var(--v2-text-muted, #94a3b8); }
.v2-syn-conf {
  font-size: 0.6rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 1px 5px;
  border-radius: 3px;
}
.v2-syn-conf--high { background: rgba(46, 160, 67, 0.25); color: #9be0a3; }
.v2-syn-conf--med  { background: rgba(220, 165, 60, 0.25); color: #ffd88a; }
.v2-syn-conf--low  { background: rgba(120, 130, 140, 0.25); color: #c0c8d0; }
.v2-syn-tag {
  font-size: 0.6rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 1px 5px;
  border-radius: 3px;
}
.v2-syn-tag--high { background: rgba(248, 81, 73, 0.22); color: #ffa8a3; }
.v2-syn-tag--med  { background: rgba(220, 165, 60, 0.22); color: #ffd88a; }
.v2-syn-tag--low  { background: rgba(46, 160, 67, 0.22); color: #9be0a3; }
.v2-syn-upside {
  display: block;
  width: 100%;
  font-size: 0.72rem;
  color: var(--v2-text-muted, #94a3b8);
  font-style: italic;
}
.v2-synthesis-categories {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.v2-syn-cat {
  padding: 6px 10px;
  border-radius: 4px;
  font-size: 0.78rem;
  border-left: 3px solid;
}
.v2-syn-cat strong { font-size: 0.95rem; margin-right: 6px; }
.v2-syn-cat--control   { border-left-color: #2ea043; background: rgba(46, 160, 67, 0.07); }
.v2-syn-cat--influence { border-left-color: #58a6ff; background: rgba(88, 166, 255, 0.07); }
.v2-syn-cat--monitor   { border-left-color: #d29922; background: rgba(210, 153, 34, 0.07); }
.v2-syn-cat--accept    { border-left-color: #8b949e; background: rgba(139, 148, 158, 0.07); }

} /* close @layer components */

@layer mobile-overrides {
@media (max-width: 768px) {
  .v2-synthesis-grid { grid-template-columns: 1fr; }
  .v2-synthesis-meta { max-width: 140px; }
  /* Allow the actions side to shrink so the meta can ellipsize before
     it ever overlaps the title. Without min-width:0 the flex item
     refuses to go below its intrinsic content size and the truncated
     meta string ("…ce Memo · 4/25/2026…") visually crashed into the
     "Synthesis" title on portrait phones. */
  .v2-synthesis-actions { min-width: 0; }
  .v2-synthesis-title-row { flex: 1 1 auto; min-width: 0; }
}
/* Below ~480px (portrait phone) hide the meta entirely. The title,
   degraded chip, and Regenerate button are the only things that
   fit cleanly on a 375px viewport without truncation collisions. */
@media (max-width: 480px) {
  .v2-synthesis-meta { display: none; }
}
}

@layer components {

/* ===========================================================
 * Commitment Threads (cross-meeting threading)
 *
 * Covers three surfaces:
 *   1. Inline "thread chip" on a commitment row when c.thread_id set
 *   2. Thread list inside the commitment detail modal
 *   3. Thread View modal (linked commitments + timeline) + Related modal
 *
 * Dark-theme only; all colors bound to existing --v2-* tokens so this
 * inherits any future light-theme work without changes. */

.v2-thread-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  margin-left: 6px;
  border-radius: 10px;
  background: rgba(232, 119, 34, 0.15);
  color: #fdba74;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.3px;
  cursor: pointer;
  border: 1px solid rgba(232, 119, 34, 0.3);
  text-decoration: none;
  line-height: 1.4;
  max-width: 160px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.v2-thread-chip:hover { background: rgba(232, 119, 34, 0.25); }
.v2-thread-chip-icon { font-size: 0.75rem; line-height: 1; }

.v2-row-action--threads {
  background: transparent;
  border: 1px solid var(--v2-border, #e2e8f0);
  color: var(--v2-text-secondary, #64748b);
}
.v2-row-action--threads:hover {
  background: rgba(232, 119, 34, 0.1);
  color: #fdba74;
  border-color: rgba(232, 119, 34, 0.4);
}

.v2-thread-card {
  background: var(--v2-bg-input, #f8fafc);
  border: 1px solid var(--v2-border, #e2e8f0);
  border-radius: 8px;
  padding: 10px 12px;
  margin-bottom: 8px;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.v2-thread-card:hover {
  border-color: #e87722;
  background: rgba(232, 119, 34, 0.05);
}
.v2-thread-card-title {
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--text-primary, #f1f5f9);
  margin-bottom: 4px;
}
.v2-thread-card-meta {
  font-size: 0.72rem;
  color: var(--v2-text-muted, #64748b);
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}
.v2-thread-card-summary {
  font-size: 0.82rem;
  color: var(--v2-text-secondary, #64748b);
  margin-top: 6px;
  line-height: 1.45;
}
.v2-thread-confidence {
  padding: 1px 6px;
  border-radius: 3px;
  font-size: 0.65rem;
  font-weight: 600;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  background: rgba(46, 160, 67, 0.2);
  color: #86efac;
}
.v2-thread-confidence--med { background: rgba(220, 165, 60, 0.2); color: #fbbf24; }
.v2-thread-confidence--low { background: rgba(148, 163, 184, 0.15); color: #94a3b8; }

.v2-thread-commitments {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.v2-thread-commit-item {
  border-left: 3px solid var(--v2-border, #e2e8f0);
  padding: 8px 10px;
  background: var(--v2-bg-input, #f8fafc);
  border-radius: 0 6px 6px 0;
  font-size: 0.85rem;
  color: var(--text-primary, #f1f5f9);
}
.v2-thread-commit-item--fulfilled { border-left-color: #22c55e; }
.v2-thread-commit-item--missed    { border-left-color: #ef4444; }
.v2-thread-commit-item--open      { border-left-color: #e87722; }
.v2-thread-commit-head {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  flex-wrap: wrap;
  font-size: 0.72rem;
  color: var(--v2-text-muted, #64748b);
  margin-bottom: 4px;
}
.v2-thread-commit-status {
  padding: 1px 6px;
  border-radius: 3px;
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  font-weight: 600;
}
.v2-thread-commit-status--fulfilled { background: rgba(34, 197, 94, 0.15); color: #86efac; }
.v2-thread-commit-status--missed    { background: rgba(239, 68, 68, 0.15); color: #fca5a5; }
.v2-thread-commit-status--open      { background: rgba(232, 119, 34, 0.15); color: #fdba74; }

.v2-thread-events {
  position: relative;
  padding-left: 14px;
  border-left: 2px solid var(--v2-border, #e2e8f0);
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.v2-thread-event {
  position: relative;
  font-size: 0.82rem;
  color: var(--text-primary, #f1f5f9);
  line-height: 1.45;
}
.v2-thread-event::before {
  content: '';
  position: absolute;
  left: -20px;
  top: 6px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #e87722;
  border: 2px solid var(--bg-card, #1e293b);
}
.v2-thread-event-meta {
  font-size: 0.68rem;
  color: var(--v2-text-muted, #64748b);
  text-transform: uppercase;
  letter-spacing: 0.4px;
  margin-bottom: 2px;
}
.v2-thread-event-body {
  font-size: 0.82rem;
  color: var(--v2-text-secondary, #64748b);
}

.v2-threads-empty {
  padding: 12px;
  text-align: center;
  font-size: 0.82rem;
  color: var(--v2-text-muted, #64748b);
  font-style: italic;
  background: var(--v2-bg-input, #f8fafc);
  border: 1px dashed var(--v2-border, #e2e8f0);
  border-radius: 6px;
}

} /* close @layer components */

@layer mobile-overrides {
@media (max-width: 600px) {
  .v2-thread-chip {
    max-width: 120px;
    font-size: 0.62rem;
    padding: 1px 6px;
  }
}
}

@layer components {

/* ===========================================================
 * Commitment Dependency Graph (cascade-impact UI)
 *
 * Surfaces:
 *   1. Inline `.v2-dep-chip` chain-link icon on a commitment row
 *      when commitment_dependencies has any edge for that id
 *      (orange = non-blocking, red = upstream is blocking)
 *   2. `.v2-dep-section` inside the detail modal — two subsections
 *      (This depends on / This blocks) + cascade banner
 *
 * Dark-theme native; mirrors the threading chip pattern so visual
 * weight is consistent. Mobile rules under the 600px breakpoint. */

.v2-dep-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  margin-left: 6px;
  border-radius: 10px;
  /* Warning orange #f59e0b — non-blocking edges */
  background: rgba(245, 158, 11, 0.15);
  color: #fbbf24;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.3px;
  cursor: pointer;
  border: 1px solid rgba(245, 158, 11, 0.35);
  text-decoration: none;
  line-height: 1.4;
  white-space: nowrap;
}
.v2-dep-chip:hover { background: rgba(245, 158, 11, 0.25); }
.v2-dep-chip-icon { font-size: 0.78rem; line-height: 1; }
.v2-dep-chip--blocking {
  /* Red #ef4444 — this commitment is blocked by an upstream item */
  background: rgba(239, 68, 68, 0.15);
  color: #fca5a5;
  border-color: rgba(239, 68, 68, 0.4);
}
.v2-dep-chip--blocking:hover { background: rgba(239, 68, 68, 0.25); }

.v2-dep-section { /* container styled inline; left here for future overrides */ }

.v2-dep-banner {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border-radius: 8px;
  font-size: 0.85rem;
  line-height: 1.45;
  margin-bottom: 4px;
}
.v2-dep-banner--risk {
  background: rgba(239, 68, 68, 0.12);
  border: 1px solid rgba(239, 68, 68, 0.35);
  color: #fca5a5;
}
.v2-dep-banner-icon { font-size: 1rem; line-height: 1; }

.v2-dep-item {
  border-left: 3px solid var(--v2-border, #e2e8f0);
  padding: 8px 10px;
  background: var(--v2-bg-input, #f8fafc);
  border-radius: 0 6px 6px 0;
  font-size: 0.85rem;
  color: var(--text-primary, #f1f5f9);
  margin-bottom: 6px;
}
.v2-dep-item--fulfilled { border-left-color: #22c55e; }
.v2-dep-item--missed    { border-left-color: #ef4444; }
.v2-dep-item--open      { border-left-color: #f59e0b; }
.v2-dep-item-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  margin-bottom: 3px;
}
.v2-dep-item-owner {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--v2-text-secondary, #64748b);
}
.v2-dep-item-status {
  padding: 1px 6px;
  border-radius: 3px;
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  font-weight: 600;
}
.v2-dep-item-status--fulfilled { background: rgba(34, 197, 94, 0.15);  color: #86efac; }
.v2-dep-item-status--missed    { background: rgba(239, 68, 68, 0.15);  color: #fca5a5; }
.v2-dep-item-status--open      { background: rgba(245, 158, 11, 0.15); color: #fbbf24; }
.v2-dep-item-desc { font-size: 0.85rem; line-height: 1.4; }
.v2-dep-item-meta {
  font-size: 0.7rem;
  color: var(--v2-text-muted, #64748b);
  margin-top: 3px;
}

} /* close @layer components */

@layer mobile-overrides {
@media (max-width: 600px) {
  .v2-dep-chip {
    font-size: 0.62rem;
    padding: 1px 6px;
  }
}
}

@layer components {

/* ============================
 * Gollwitzer Implementation Intentions (migration 129)
 * ============================
 *
 * 1) Inline lightning-bolt chip (#f59e0b yellow) on commitment rows
 *    that have ≥1 armed intention attached.
 * 2) "Armed Plans" dashboard card listing the user's armed if/then plans.
 * 3) "Implementation Intention" section inside the commitment detail
 *    modal — list + inline create form + per-row "I did it" / "I didn't".
 *
 * Dark-theme native; mirrors the chip pattern so visual weight is
 * consistent with thread + dependency chips. Mobile rules under 600px. */

.v2-intent-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  margin-left: 6px;
  border-radius: 10px;
  background: rgba(245, 158, 11, 0.15);
  color: #fbbf24;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.3px;
  border: 1px solid rgba(245, 158, 11, 0.35);
  line-height: 1.4;
  white-space: nowrap;
}
.v2-intent-chip-icon { font-size: 0.78rem; line-height: 1; }

/* --- Armed Plans dashboard card --- */
.v2-armed-plans-card {
  background: var(--v2-bg-card, #ffffff);
  border: 1px solid rgba(245, 158, 11, 0.35);
  border-left: 4px solid #f59e0b;
  border-radius: var(--v2-radius, 8px);
  margin-bottom: 12px;
  box-shadow: var(--v2-shadow-sm, 0 1px 3px rgba(0,0,0,0.2));
  overflow: hidden;
}
.v2-armed-plans-head {
  padding: 10px 16px;
  border-bottom: 1px solid var(--v2-border-light, #f1f5f9);
}
.v2-armed-plans-title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: 0.95rem;
  font-weight: 600;
  color: #fbbf24;
}
.v2-armed-plans-count {
  background: #f59e0b;
  color: #0f172a;
  font-size: 0.75rem;
  font-weight: 700;
  padding: 1px 7px;
  border-radius: var(--v2-radius-pill, 999px);
  min-width: 20px;
  text-align: center;
}
.v2-armed-plans-sub {
  font-size: 0.72rem;
  color: var(--v2-text-muted, #64748b);
  margin-top: 4px;
}
.v2-armed-plans-list { padding: 0; }
.v2-armed-plan-item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px 16px;
  border-bottom: 1px solid var(--v2-border-light, #f1f5f9);
  font-size: 0.85rem;
  line-height: 1.4;
}
.v2-armed-plan-item:last-child { border-bottom: none; }
.v2-armed-plan-if {
  color: #fbbf24;
  font-weight: 600;
  font-size: 0.78rem;
}
.v2-armed-plan-then {
  color: var(--text-primary, #f1f5f9);
}

/* --- Implementation Intention section inside the commitment detail modal --- */
.v2-intent-section {
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid var(--v2-border, #e2e8f0);
}
.v2-intent-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}
.v2-intent-header-title {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--v2-text-muted, #64748b);
  display: flex;
  align-items: center;
  gap: 6px;
}
.v2-intent-list { display: flex; flex-direction: column; gap: 8px; }
.v2-intent-row {
  background: var(--v2-bg-input, #f8fafc);
  border: 1px solid var(--v2-border, #e2e8f0);
  border-left: 3px solid #f59e0b;
  border-radius: 6px;
  padding: 8px 10px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.v2-intent-row-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: 0.85rem;
}
.v2-intent-row-if {
  color: #fbbf24;
  font-weight: 600;
  font-size: 0.78rem;
}
.v2-intent-row-then { color: var(--text-primary, #f1f5f9); }
.v2-intent-row-meta {
  display: flex;
  gap: 8px;
  align-items: center;
  font-size: 0.7rem;
  color: var(--v2-text-muted, #64748b);
}
.v2-intent-status-pill {
  font-size: 0.65rem;
  font-weight: 700;
  text-transform: uppercase;
  padding: 1px 7px;
  border-radius: var(--v2-radius-pill, 999px);
  letter-spacing: 0.3px;
}
.v2-intent-status-pill--armed     { background: rgba(245, 158, 11, 0.18); color: #fbbf24; border: 1px solid rgba(245, 158, 11, 0.4); }
.v2-intent-status-pill--fulfilled { background: rgba(34, 197, 94, 0.18);  color: #86efac; border: 1px solid rgba(34, 197, 94, 0.4); }
.v2-intent-status-pill--missed    { background: rgba(239, 68, 68, 0.18);  color: #fca5a5; border: 1px solid rgba(239, 68, 68, 0.4); }
.v2-intent-status-pill--abandoned { background: rgba(100, 116, 139, 0.2); color: #94a3b8; border: 1px solid rgba(100, 116, 139, 0.4); }

.v2-intent-row-actions {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.v2-intent-action-btn {
  font-size: 0.72rem;
  padding: 4px 10px;
  border-radius: 4px;
  border: 1px solid var(--v2-border, #e2e8f0);
  background: transparent;
  color: var(--v2-text-secondary, #64748b);
  cursor: pointer;
}
.v2-intent-action-btn:hover { background: var(--v2-bg-hover, rgba(0, 0, 0, 0.05)); }
.v2-intent-action-btn--did   { color: #86efac; border-color: rgba(34, 197, 94, 0.4); }
.v2-intent-action-btn--didnt { color: #fca5a5; border-color: rgba(239, 68, 68, 0.4); }

.v2-intent-form {
  background: var(--v2-bg-input, #f8fafc);
  border: 1px solid var(--v2-border, #e2e8f0);
  border-radius: 6px;
  padding: 10px;
  margin-top: 8px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.v2-intent-form label {
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--v2-text-muted, #64748b);
  display: block;
  margin-bottom: 4px;
}
.v2-intent-form textarea {
  width: 100%;
  background: var(--bg-card, #1e293b);
  border: 1px solid var(--v2-border, #e2e8f0);
  color: var(--text-primary, #f1f5f9);
  border-radius: 4px;
  padding: 6px 8px;
  font-size: 0.85rem;
  resize: vertical;
  min-height: 36px;
  font-family: inherit;
}
.v2-intent-form-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}
.v2-intent-empty {
  font-size: 0.82rem;
  color: var(--v2-text-muted, #64748b);
  font-style: italic;
  padding: 8px 0;
}

} /* close @layer components */

@layer mobile-overrides {
@media (max-width: 600px) {
  .v2-intent-chip { font-size: 0.62rem; padding: 1px 6px; }
  .v2-armed-plans-title { font-size: 0.88rem; }
  .v2-armed-plan-item { font-size: 0.82rem; padding: 8px 12px; }
}
}

@layer components {

/* ============================================================
   Auto-Record Header Strip (V2 port of V1 dashboard.html:70-94).
   Composed of an inline REC badge + a per-bot list + a Stop button.
   Hidden via inline `display:none` until JS detects an active bot.
   See dashboard-v2.html for the markup contract and
   tests/services/v2AutoRecordWidget.test.js for the assertions that
   pin these selectors.
   ============================================================ */
.v2-auto-record-strip {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  margin: 0 0 14px;
  background: linear-gradient(90deg, rgba(239, 68, 68, 0.10), rgba(15, 23, 42, 0.0));
  border: 1px solid rgba(239, 68, 68, 0.45);
  border-left-width: 4px;
  border-radius: 8px;
  font-size: 0.85rem;
}
.v2-auto-record-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-weight: 700;
  font-size: 0.78rem;
  letter-spacing: 0.5px;
  color: #ef4444;
  text-transform: uppercase;
  flex-shrink: 0;
}
.v2-auto-record-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #ef4444;
  box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7);
  animation: v2-rec-pulse 1.4s infinite;
}
@keyframes v2-rec-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.6); }
  70%  { box-shadow: 0 0 0 10px rgba(239, 68, 68, 0); }
  100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0); }
}
.v2-auto-record-count {
  font-size: 0.7rem;
  background: rgba(239, 68, 68, 0.18);
  color: #ef4444;
  border-radius: 10px;
  padding: 1px 6px;
  min-width: 18px;
  text-align: center;
}
.v2-auto-record-list {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.v2-auto-record-item {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.82rem;
  color: var(--v2-text, #1e293b);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.v2-auto-record-title {
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
}
.v2-auto-record-elapsed {
  color: #ef4444;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}
.v2-auto-record-meeting-link {
  color: #60a5fa;
  text-decoration: none;
  font-size: 0.75rem;
  flex-shrink: 0;
}
.v2-auto-record-meeting-link:hover { text-decoration: underline; }
.v2-btn--danger {
  background: #dc2626;
  color: #fff;
  border: 1px solid #b91c1c;
}
.v2-btn--danger:hover { background: #b91c1c; }
} /* close final @layer components */

@layer mobile-overrides {
@media (max-width: 600px) {
  .v2-auto-record-strip { padding: 8px 10px; gap: 8px; font-size: 0.78rem; }
  .v2-auto-record-item  { font-size: 0.74rem; }
  .v2-auto-record-meeting-link { display: none; }
  /* Closed footer (Chunk 3) — keep pill bar wrapping cleanly + drop the
     window label on narrow viewports. */
  .v2-closed-footer { padding: 10px 12px; }
  .v2-closed-footer-window { display: none; }
  .v2-closed-item-what { white-space: normal; }
  /* Hot List (Chunk 1) — narrower viewport, drop the right-side
     "overdue + due today" subtitle, tighten the row grid so pills
     don't push the description offscreen, and let .what wrap. */
  .v2-hotlist-window { display: none; }
  .v2-hotlist-item {
    grid-template-columns: 8px auto 1fr;
    grid-template-rows: auto auto;
    row-gap: 4px;
  }
  .v2-hotlist-due { grid-column: 3; justify-self: end; font-size: 0.74rem; }
  .v2-hotlist-what { white-space: normal; }
}
}
