/* ================================================================
   Klaros — Dashboard Styles
   Canonical light design system (see docs/design-system.md)
   ================================================================ */
/* Fonts are requested via <link> in creator-dashboard.html, not @import. An @import here
   cannot begin downloading until this file is fetched and parsed, serialising the type
   system behind the stylesheet. Keep the two in sync when changing families or weights. */

/* Colours, radii, fonts and status tints live in css/tokens.css, loaded before this file.
   Only app-shell dimensions that no other surface has are declared here. */
:root {
  --sidebar-width: 260px;
  --status-rail-width: 268px;
}

/* Theme-aware logo + header toggle */
.dash-logo .logo-dark {
  display: none;
}
/* The logo files carry their own background (black in the dark one, near-white in the light one),
   which drew a box in the header (2026-10-21). Blended, the background takes the header's colour. */
.dash-logo .logo-light {
  mix-blend-mode: multiply;
}
.dash-logo .logo-dark {
  mix-blend-mode: lighten;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .logo-light {
    display: none;
  }
  :root:not([data-theme='light']) .logo-dark {
    display: inline-block;
  }
}
:root[data-theme='dark'] .logo-light {
  display: none;
}
:root[data-theme='dark'] .logo-dark {
  display: inline-block;
}
:root[data-theme='light'] .logo-light {
  display: inline-block;
}
:root[data-theme='light'] .logo-dark {
  display: none;
}
#btn-theme {
  background: none;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  width: 30px;
  height: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--text-secondary);
  padding: 0;
}
#btn-theme:hover {
  background: var(--surface-2);
  color: var(--text);
}
#btn-theme svg {
  width: 16px;
  height: 16px;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
#btn-theme .icon-sun {
  display: none;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) #btn-theme .icon-moon {
    display: none;
  }
  :root:not([data-theme='light']) #btn-theme .icon-sun {
    display: inline;
  }
}
:root[data-theme='dark'] #btn-theme .icon-moon {
  display: none;
}
:root[data-theme='dark'] #btn-theme .icon-sun {
  display: inline;
}
:root[data-theme='light'] #btn-theme .icon-moon {
  display: inline;
}
:root[data-theme='light'] #btn-theme .icon-sun {
  display: none;
}

*,
*::before,
*::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
html {
  font-size: 15px;
}
body {
  font-family: var(--font-body);
  background: var(--bg);
  color: var(--text);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  -webkit-font-smoothing: antialiased;
}

/* ΓÇöΓÇöΓÇö Header ΓÇöΓÇöΓÇö */
/* --banner-h is 0px unless a banner is on screen, so every calc below resolves to exactly the
   values this file has always used and a workspace with no banner is untouched. It is set by
   ui.js when the trial banner renders.

   Why it is needed: the trial banner is prepended to <body> and the header is position:fixed at
   top:0, so the two occupied the same 34px and the banner (z-index 122) painted over the header
   (z-index 100). Measured 2026-09-10: 34px of vertical overlap, and elementFromPoint inside the
   header's right-hand controls returned the banner — so those buttons were not merely hidden,
   they were swallowing the clicks, for every trial user. */
.dash-header {
  height: 56px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 20px;
  position: fixed;
  top: var(--banner-h, 0px);
  left: 0;
  right: 0;
  z-index: 100;
}
.dash-header-left {
  display: flex;
  align-items: center;
  gap: 16px;
}
.dash-logo {
  display: flex;
  align-items: center;
}
.dash-logo img {
  display: block;
}
.dash-header-center {
  display: flex;
  align-items: center;
  gap: 8px;
}
.sync-indicator {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-sm);
  color: var(--dim);
  padding: 4px 10px;
  background: var(--surface-2);
  border-radius: 20px;
}
.sync-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--primary);
  animation: sync-pulse 2s infinite;
}
.sync-dot.offline {
  background: var(--red);
  animation: none;
}
@keyframes sync-pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.4;
  }
}
.dash-header-right {
  display: flex;
  align-items: center;
  gap: 12px;
}
.dash-user {
  font-size: var(--text-base);
  color: var(--text-secondary);
}

/* ΓÇöΓÇöΓÇö Layout ΓÇöΓÇöΓÇö */
.dash-layout {
  display: flex;
  margin-top: calc(56px + var(--banner-h, 0px));
  min-height: calc(100vh - 56px - var(--banner-h, 0px));
}

/* ΓÇöΓÇöΓÇö Sidebar ΓÇöΓÇöΓÇö */
.dash-sidebar {
  width: var(--sidebar-width);
  background: var(--surface);
  border-inline-end: 1px solid var(--border);
  padding: 16px 0;
  position: fixed;
  top: calc(56px + var(--banner-h, 0px));
  bottom: 0;
  left: 0;
  overflow-y: auto;
  z-index: 50;
  transition: transform 0.3s ease;
  display: flex;
  flex-direction: column;
}
.sidebar-help {
  margin-top: auto;
  padding: 12px 16px;
  border-top: 1px solid var(--border);
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--text-xs);
  color: var(--dim);
  text-decoration: none;
  transition: color 0.15s ease;
}
.sidebar-help:hover {
  color: var(--green);
}
.sidebar-help svg {
  flex-shrink: 0;
}
.nav-section {
  padding: 0 12px;
  margin-bottom: 8px;
}
.nav-section-title {
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--dim);
  padding: 8px 12px 4px;
}
.nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  font-size: 0.9rem;
  cursor: pointer;
  transition: var(--transition);
  text-decoration: none;
}
.nav-item:hover {
  background: var(--surface-2);
  color: var(--text);
}
.nav-item.active {
  background: var(--primary-glow);
  color: var(--primary);
  font-weight: 600;
}
.nav-icon {
  width: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.nav-icon svg {
  width: 18px;
  height: 18px;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.nav-badge {
  margin-inline-start: auto;
  font-size: var(--text-2xs);
  padding: 1px 6px;
  border-radius: 10px;
  background: var(--amber);
  color: var(--on-primary);
  font-weight: 700;
}
.nav-item:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: -2px;
}
/* The Execution/Status rail is only meaningful on Overview; collapse it elsewhere to reclaim the 268px. */
body.rail-collapsed {
  --status-rail-width: 0px;
}
body.rail-collapsed #orchestration-panel {
  display: none;
}

/* ΓÇöΓÇöΓÇö Main content ΓÇöΓÇöΓÇö */
.dash-main {
  flex: 1;
  min-width: 0;
  margin-inline-start: var(--sidebar-width);
  margin-inline-end: var(--status-rail-width);
  padding: 24px;
  max-width: none;
}
.dash-tab {
  display: none;
  animation: tab-fade 0.3s ease;
}
.dash-tab.active {
  display: block;
}
@keyframes tab-fade {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
.tab-title {
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 700;
  margin-bottom: 20px;
}

/* ΓÇöΓÇöΓÇö Stats cards ΓÇöΓÇöΓÇö */
.stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 14px;
  margin-bottom: 24px;
}
.stat-card {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px;
  position: relative;
  overflow: hidden;
  transition: var(--transition);
}
.stat-card:hover {
  border-color: var(--border-light);
  transform: translateY(-2px);
}
.stat-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--primary);
  opacity: 0;
  transition: var(--transition);
}
.stat-card:hover::before {
  opacity: 1;
}
.stat-card-value {
  font-family: var(--font-display);
  font-size: 1.8rem;
  font-weight: 700;
  color: var(--text);
}
.stat-card-label {
  font-size: var(--text-xs);
  color: var(--dim);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-top: 4px;
}
.stat-card-icon {
  position: absolute;
  top: 14px;
  right: 14px;
  font-size: 1.5rem;
  opacity: 0.3;
}
.stat-card-icon svg {
  width: 22px;
  height: 22px;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.stat-card-drilldown {
  cursor: pointer;
}
.stat-card-drilldown:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}
.stat-card-hint {
  margin-top: 8px;
  font-size: var(--text-xs);
  color: var(--primary);
  letter-spacing: 0.03em;
  opacity: 0.8;
}

/* ΓÇöΓÇöΓÇö Application overview ΓÇöΓÇöΓÇö */
.overview-command-strip {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 16px;
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}
.overview-eyebrow {
  font-size: var(--text-2xs);
  color: var(--dim);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-weight: 700;
}
.overview-command-title {
  margin-top: 4px;
  font-family: var(--font-display);
  font-size: 1.15rem;
  font-weight: 700;
}
.overview-command-meta {
  margin-top: 4px;
  color: var(--text-secondary);
  font-size: var(--text-base);
}
.overview-command-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: flex-end;
}
.overview-metric-grid,
.asset-summary-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 12px;
  margin-bottom: 16px;
}
.asset-summary-grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
/* An author display: rule always beats the UA [hidden]{display:none} default (see the origin-order
   comment near .filter-toggle-count[hidden]) — .overview-metric-grid predates the agent-view work
   (§9.3 Phase 3) and was never toggled via .hidden before, so this guard was never added. Without
   it, #app-overview-grid.hidden = true (set for agents in ADMIN_ONLY_SECTIONS) silently does
   nothing — the grid stays visually shown even though the JS believes it's hidden. Found via live
   Playwright verification 2026-08-26, not by inspection — the numbers inside stay zeroed for
   agents regardless (network-stats is never fetched for them), so this was a visual/UX bug, not a
   data leak, but a real one: confirmed via screenshot after the initDashboard() race fix finally
   let a correctly-role-resolved render through for the first time. */
.overview-metric-grid[hidden] {
  display: none;
}
.overview-metric-card {
  min-width: 0;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  transition: var(--transition);
}
.overview-metric-card:hover {
  border-color: var(--border-light);
  background: var(--surface-3);
}
.overview-metric-label {
  color: var(--dim);
  font-size: var(--text-2xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 700;
}
.overview-metric-value {
  margin-top: 6px;
  font-family: var(--font-display);
  font-size: 1.55rem;
  font-weight: 700;
  color: var(--text);
}
.overview-metric-sub {
  margin-top: 3px;
  color: var(--text-secondary);
  font-size: var(--text-sm);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.asset-board {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
  gap: 14px;
  margin-bottom: 16px;
}
.asset-board {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.overview-panel {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  padding: 14px;
}
.overview-panel-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}
.overview-panel-title {
  margin-top: 3px;
  font-family: var(--font-display);
  font-size: 1rem;
}
.overview-panel-link {
  color: var(--primary);
  font-size: var(--text-sm);
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
}
.overview-status-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.overview-status-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 9px 10px;
  border: 1px solid rgba(0, 0, 0, 0.07);
  border-radius: var(--radius-sm);
  background: rgba(0, 0, 0, 0.02);
}
.overview-status-row span {
  color: var(--text-secondary);
  font-size: var(--text-sm);
}
.overview-status-row strong {
  font-size: var(--text-sm);
  color: var(--text);
  text-align: end;
}
.overview-list,
.asset-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.overview-list-item,
.asset-list-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px;
  border: 1px solid rgba(0, 0, 0, 0.07);
  border-radius: var(--radius-sm);
  background: rgba(0, 0, 0, 0.02);
  color: inherit;
  text-decoration: none;
}
.overview-list-main,
.asset-list-main {
  min-width: 0;
  max-width: 100%;
  display: flex;
  flex-direction: column;
}
.overview-list-title,
.asset-list-title {
  display: block;
  max-width: 100%;
  color: var(--text);
  font-weight: 700;
  font-size: var(--text-base);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.overview-list-meta,
.asset-list-meta {
  display: block;
  max-width: 100%;
  margin-top: 3px;
  color: var(--dim);
  font-size: var(--text-xs);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.overview-list-value,
.asset-list-value {
  flex-shrink: 0;
  color: var(--text-secondary);
  font-size: var(--text-sm);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 3px 8px;
}
.overview-empty {
  color: var(--dim);
  font-size: var(--text-sm);
  padding: 10px;
  border: 1px dashed var(--border);
  border-radius: var(--radius-sm);
}
/* A list still loading draws the shape of its rows, not the word (2026-10-21). The words stay in the
   DOM, invisible, so a screen reader still says what is loading. */
.overview-empty.is-loading {
  min-height: 92px;
  padding: 0;
  border: none;
  color: transparent;
  user-select: none;
  background:
    linear-gradient(var(--border) 0 0) 0 6px / 100% 14px no-repeat,
    linear-gradient(var(--border) 0 0) 0 40px / 78% 14px no-repeat,
    linear-gradient(var(--border) 0 0) 0 74px / 56% 14px no-repeat;
  animation: skeleton-breathe 1.4s ease-in-out infinite;
}
td.overview-empty.is-loading { height: 92px; }
@keyframes skeleton-breathe {
  50% { opacity: 0.55; }
}
@media (prefers-reduced-motion: reduce) {
  .overview-empty.is-loading { animation: none; }
}
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 6px;
  padding: 34px 20px;
  color: var(--text-secondary);
}
.empty-state-icon {
  width: 44px;
  height: 44px;
  border-radius: 12px;
  background: var(--surface-2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--dim);
  margin-bottom: 4px;
}
.empty-state-icon svg {
  width: 22px;
  height: 22px;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.empty-state-title {
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--text);
}
.empty-state-body {
  font-size: var(--text-base);
  max-width: 44ch;
  line-height: 1.5;
}
.empty-state-action {
  margin-top: 10px;
}
/* ——— Inbox keyboard triage ——— */
.inbox-convo.kbd-selected {
  box-shadow: inset 0 0 0 2px var(--primary);
}
.inbox-help {
  position: fixed;
  inset: 0;
  z-index: 4500;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(17, 24, 39, 0.4);
}
.inbox-help[hidden] {
  display: none;
}
.inbox-help-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.25);
  padding: 20px 24px;
  min-width: 320px;
}
.inbox-help-title {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 700;
  margin-bottom: 12px;
}
.inbox-help ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 9px;
}
.inbox-help li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  font-size: var(--text-base);
  color: var(--text);
}
.inbox-help-keys {
  display: inline-flex;
  gap: 4px;
  color: var(--dim);
}
.inbox-help kbd {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  padding: 1px 6px;
  min-width: 20px;
  text-align: center;
}
.overview-timeline {
  margin-top: 4px;
}

/* ——— Overview: Layer D, grouped learning feed (docs/master_design_doc.md §6.1, §9.1 Phase 4) ———
   Groups sit inside the existing .timeline container, so the connecting line (.timeline::before)
   and dot positioning are untouched — only a label + spacing between date buckets is new. */
.ov-feed-group + .ov-feed-group {
  margin-top: 18px;
}
.ov-feed-group-label {
  font-size: var(--text-2xs);
  color: var(--dim);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 700;
  margin-bottom: 8px;
}
.ov-feed-more {
  display: block;
  margin-top: 14px;
  font-size: var(--text-sm);
  color: var(--primary);
  text-decoration: none;
  font-weight: 600;
}
.ov-feed-more:hover {
  text-decoration: underline;
}

/* ——— Overview: WhatsApp Business vitals pills (quality rating + sends left) ——— */
.ov-vitals {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}
.ov-vital-pill {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text-secondary);
  font-size: var(--text-sm);
  font-weight: 700;
  cursor: pointer;
  transition: var(--transition);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.ov-vital-pill:hover {
  border-color: var(--border-light);
}
.ov-vital-pill[hidden] {
  display: none;
}
.ov-vital-pill:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}
.ov-health-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--dim);
  flex-shrink: 0;
}
.ov-vital-pill[data-tone='success'] {
  color: var(--primary-dark);
  border-color: rgba(5, 150, 105, 0.4);
  background: var(--primary-glow);
}
.ov-vital-pill[data-tone='success'] .ov-health-dot {
  background: var(--primary);
}
.ov-vital-pill[data-tone='warning'] {
  color: #b45309;
  border-color: rgba(217, 119, 6, 0.4);
  background: var(--amber-glow);
}
.ov-vital-pill[data-tone='warning'] .ov-health-dot {
  background: var(--amber);
}
.ov-vital-pill[data-tone='error'] {
  color: var(--danger-fg-strong);
  border-color: rgba(220, 38, 38, 0.4);
  background: var(--red-glow);
}
.ov-vital-pill[data-tone='error'] .ov-health-dot {
  background: var(--red);
}
.ov-health-details {
  margin: -8px 0 16px;
}
.ov-health-details[hidden] {
  display: none;
}

/* ——— Overview: Layer A win-state signal dot (docs/master_design_doc.md §9.1 Phase 1) ———
   Reuses the same tone tokens as .ov-health-dot rather than inventing a new palette. The dot is
   aria-hidden — the headline text next to it (app-overview-primary) always states the same
   condition in words, so color is never the only carrier of meaning (§4.9 rule 1). */
.ov-win-state {
  display: flex;
  align-items: center;
  gap: 8px;
}
.ov-win-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--dim);
  flex-shrink: 0;
}
.ov-win-dot[data-state='loading'] {
  background: var(--dim);
  animation: ov-win-pulse 1.4s ease-in-out infinite;
}
.ov-win-dot[data-state='green'] {
  background: var(--primary);
}
.ov-win-dot[data-state='amber'] {
  background: var(--amber);
}
.ov-win-dot[data-state='red'] {
  background: var(--red);
}
/* "new" = not started, distinct from green's calm/done meaning (§5.3) — reuses --blue, the token
   already used for informational/note timeline dots, rather than inventing a new color. Added
   2026-08-26 alongside computeWinState()'s new 'new' branch. */
.ov-win-dot[data-state='new'] {
  background: var(--blue);
}
@keyframes ov-win-pulse {
  0%,
  100% {
    opacity: 0.4;
  }
  50% {
    opacity: 1;
  }
}

/* ——— Overview: setup checklist close button ——— */
.ov-setup-close {
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text-secondary);
  font-size: var(--text-lg);
  line-height: 1;
  cursor: pointer;
  transition: var(--transition);
}
.ov-setup-close:hover {
  border-color: var(--border-light);
  background: var(--surface-3);
  color: var(--text);
}
.ov-setup-close:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

/* ——— Overview: Do-next action row ——— */
.ov-do-next {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 12px;
  margin-bottom: 16px;
}
.ov-do-next[hidden] {
  display: none;
}
.ov-action-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  text-align: start;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-inline-start: 3px solid var(--primary);
  border-radius: var(--radius);
  background: var(--surface);
  cursor: pointer;
  transition: var(--transition);
  width: 100%;
  font: inherit;
  color: inherit;
}
.ov-action-card:hover {
  border-color: var(--border-light);
  background: var(--surface-2);
  transform: translateY(-1px);
}
.ov-action-card[data-tone='urgent'] {
  border-inline-start-color: #e74c3c;
}
.ov-action-card[data-tone='calm'] {
  border-inline-start-color: var(--border-light);
  cursor: default;
}
.ov-action-card[data-tone='calm']:hover {
  transform: none;
  background: var(--surface);
}
.ov-action-main {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.ov-action-title {
  font-family: var(--font-display);
  font-size: var(--text-md);
  font-weight: 700;
  color: var(--text);
}
.ov-action-sub {
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.ov-action-cta {
  flex-shrink: 0;
  font-size: var(--text-sm);
  font-weight: 700;
  color: var(--primary);
  white-space: nowrap;
}
.ov-action-icon {
  flex-shrink: 0;
  display: inline-flex;
  color: var(--primary);
}
.ov-action-card[data-tone='urgent'] .ov-action-icon {
  color: var(--red);
}
.ov-action-card[data-tone='calm'] .ov-action-icon {
  color: var(--dim);
}
.ov-icon {
  width: 20px;
  height: 20px;
  stroke: currentColor;
  stroke-width: 2;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.ov-icon-sm {
  width: 16px;
  height: 16px;
}

/* ——— Overview: clickable metric / cost cards ——— */
.ov-metric-clickable {
  cursor: pointer;
}
.ov-metric-clickable:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}
.overview-metric-sub .ov-delta {
  color: var(--primary-dark);
  font-weight: 700;
}
/* Standalone .ov-delta (e.g. next to #ov-cost-amount) — §6.2 momentum, Q-07 resolved 2026-08-25.
   Direction is carried by the arrow glyph itself, not color alone (§4.9 rule 1). */
.ov-delta {
  font-weight: 700;
  font-size: var(--text-sm);
  margin-inline-start: 8px;
}
.ov-delta[data-dir='up'] {
  color: var(--primary-dark);
}
.ov-delta[data-dir='down'] {
  color: var(--red);
}
.ov-delta[hidden] {
  display: none;
}

/* Sprint 2C: renderDelta() \u2014 colorblind-safe semantic delta badges (\u00a713.4 Technique 6).
   Always symbol (\u25b2/\u25bc) + color, never color alone. higherIsBetter controls which direction is good. */
.ov-delta-up {
  font-weight: 700;
  font-size: var(--text-sm);
  color: var(--primary-dark);
}
.ov-delta-down {
  font-weight: 700;
  font-size: var(--text-sm);
  color: var(--red);
}
.ov-delta-na {
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

/* Sprint 2B: renderOutcomeBar() \u2014 segmented outcome bar replacing text sub-label (\u00a713.4 Technique 4).
   Replied | Read | Delivered | Failed \u2014 stacked left to right, proportional flex widths. */
.ov-outcome-bar {
  display: flex;
  height: 5px;
  border-radius: 3px;
  overflow: hidden;
  gap: 1px;
  margin-top: 6px;
  margin-bottom: 5px;
}
.ov-outcome-seg {
  min-width: 2px;
  border-radius: 2px;
  transition: flex 0.4s ease;
}
.ov-outcome-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 12px;
}
.ov-outcome-leg {
  font-size: var(--text-xs);
  color: var(--text-secondary);
}

/* Sprint 2E: qualitative metric insight line \u2014 third layer of the data story arc (\u00a713.5).
   Sits inside the metric card sub-line; uses italics to visually separate from the numbers. */
.ov-metric-insight {
  font-style: italic;
  color: var(--text-secondary);
}

/* ——— Overview: Automation panel + relationship pipeline ——— */
.ov-automation[hidden] {
  display: none;
}
.ov-automation-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.ov-automation-chip {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: inherit;
  text-align: start;
  cursor: pointer;
  font: inherit;
  transition: var(--transition);
  min-width: 0;
}
.ov-automation-chip:hover {
  border-color: var(--border-light);
  background: var(--surface-3);
}
.ov-automation-chip .ov-action-icon {
  color: var(--primary);
}
.ov-automation-chip-main {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.ov-automation-chip-value {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--text);
}
.ov-automation-chip-label {
  font-size: var(--text-xs);
  color: var(--text-secondary);
}
.ov-automation-empty {
  color: var(--text-secondary);
  font-size: var(--text-base);
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.ov-automation-empty a {
  color: var(--primary);
  font-weight: 700;
  text-decoration: none;
}

/* ——— Overview: Layer B, proof of work (docs/master_design_doc.md §6.1, §9.1 Phase 2) ———
   Reuses .ov-action-icon/.ov-icon conventions rather than a new icon treatment. Each row is a
   clickable link to the tab it's about — no separate drill-down surface needed, per §6.6. */
.ov-platform-work {
  margin-top: 16px;
}
.ov-work-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 0;
  border-top: 1px solid var(--border);
  text-align: start;
  width: 100%;
  background: none;
  border-inline-start: none;
  border-inline-end: none;
  border-bottom: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.ov-work-item:first-child {
  border-top: none;
  padding-top: 4px;
}
.ov-work-item:hover .ov-work-text {
  color: var(--primary-dark);
}
.ov-work-item:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}
.ov-work-icon {
  flex-shrink: 0;
  display: inline-flex;
  color: var(--primary);
  margin-top: 1px;
}
.ov-work-text {
  font-size: var(--text-base);
  color: var(--text);
}
.ov-pipeline {
  margin-top: 14px;
}
.ov-pipeline[hidden] {
  display: none;
}
.ov-pipeline-caption {
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 700;
  color: var(--dim);
  margin-bottom: 6px;
}
.ov-pipeline-bar {
  display: flex;
  height: 12px;
  border-radius: 999px;
  overflow: hidden;
  background: var(--surface-3);
}
.ov-pipeline-seg {
  min-width: 3px;
  transition: var(--transition);
}
.ov-pipeline-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 8px;
}
.ov-pipeline-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.76rem;
  color: var(--text-secondary);
}

/* ——— Overview: Layer C admin, conversion funnel (docs/master_design_doc.md §6.1, §9.1 Phase 3) ———
   Mirrors .overview-status-row's row treatment rather than inventing a new one. No delta/arrow
   styling here by design — see the HTML comment above #ov-funnel for why momentum is intentionally
   absent from this panel. */
.ov-funnel[hidden] {
  display: none;
}
.ov-funnel-steps {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.ov-funnel-step {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 10px;
  border: 1px solid rgba(0, 0, 0, 0.07);
  border-radius: var(--radius-sm);
  background: rgba(0, 0, 0, 0.02);
  text-decoration: none;
  color: inherit;
  cursor: pointer;
}
.ov-funnel-step:hover {
  border-color: var(--border-light);
}
.ov-funnel-step:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}
.ov-funnel-arrow {
  color: var(--dim);
  flex-shrink: 0;
}
.ov-funnel-label {
  font-size: var(--text-base);
  color: var(--text);
  flex: 1;
  min-width: 0;
}
.ov-funnel-value {
  font-weight: 700;
  color: var(--text);
  white-space: nowrap;
}
.ov-funnel-value .ov-funnel-pct {
  color: var(--text-secondary);
  font-weight: 400;
  font-size: var(--text-sm);
  margin-inline-start: 4px;
}

/* Sprint 2D: drop-off conversion label between funnel steps (\u00a713.4 Technique 5).
   "\u2193 67% converted" \u2014 the step-to-step rate is the key diagnostic insight in a funnel.
   Left border gives a visual ladder feel connecting the steps above and below it. */
.ov-funnel-drop {
  font-size: var(--text-xs);
  color: var(--text-secondary);
  padding: 2px 8px;
  margin: 0;
  border-inline-start: 2px solid var(--border);
  margin-inline-start: 10px;
}

/* ——— Overview: Agent Layer C (docs/master_design_doc.md §3.4, §6.1, §9.1 Phase 3, Q-08) ———
   Rows reuse .ov-funnel-step/-label/-value/-pct exactly as-is — no new row treatment needed, this
   is the same "clickable row with a right-aligned value" shape as the admin funnel above it. Only
   the section sub-label is new. */
.ov-agent-conv > * + * {
  margin-top: 14px;
}
.ov-agent-section-label {
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 700;
  color: var(--dim);
  margin-bottom: 6px;
}

/* ——— Overview: customization (docs/master_design_doc.md §6.3, §9.1 Phase 5) ——— */
.ov-customize-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 4px;
  background: none;
  border: none;
  color: var(--text-secondary);
  font-size: var(--text-sm);
  font-weight: 600;
  cursor: pointer;
  padding: 4px 2px;
}
.ov-customize-btn:hover {
  color: var(--primary-dark);
}
.ov-customize-btn[hidden] {
  display: none;
} /* same missing-guard class as .overview-metric-grid above — display: inline-flex silently defeats [hidden] without this */
.ov-customize-panel {
  margin-top: 8px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.ov-customize-panel[hidden] {
  display: none;
}
.ov-customize-row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--text-base);
  color: var(--text);
  cursor: pointer;
}

/* ——— Overview: win-state-driven Layer C collapse summary (docs/master_design_doc.md §9.3) ———
   [hidden] guard included from the start this time — .overview-metric-grid and .ov-customize-btn
   both shipped without one and silently failed to hide until that was caught via live screenshot. */
.ov-layer-c-collapsed {
  margin-bottom: 16px;
}
.ov-layer-c-collapsed[hidden] {
  display: none;
}
#ov-layer-c-reveal {
  width: 100%;
  text-align: start;
  background: var(--surface-2);
  border: 1px dashed var(--border);
  border-radius: var(--radius-sm);
  padding: 10px 14px;
  font-size: var(--text-sm);
  color: var(--text-secondary);
  cursor: pointer;
}
#ov-layer-c-reveal:hover {
  border-color: var(--border-light);
  color: var(--text);
}
#ov-layer-c-reveal:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}
.ov-pipeline-dot {
  width: 9px;
  height: 9px;
  border-radius: 3px;
  flex-shrink: 0;
}
.ov-pipeline-legend-item strong {
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

/* ——— Overview: zero-data billing upsell card (#ov-help-card, ui.js loadAppOverview).
   Spans the full metric grid width. Styles previously inline via style.cssText — moved
   to CSS by Sprint 3 cleanup per independent reviewer finding (2026-08-26). ——— */
.ov-help-card {
  grid-column: 1 / -1;
  background: var(--surface-alt);
  border-radius: var(--radius-sm);
  padding: 20px;
  text-align: center;
  margin-top: 8px;
}
.ov-help-card-title {
  font-weight: 700;
  font-size: 1rem;
  margin-bottom: 6px;
  color: var(--text);
}
.ov-help-card-body {
  font-size: var(--text-base);
  color: var(--text-secondary);
  margin-bottom: 14px;
}

/* ——— Overview: zero-markup cost strip ——— */
.ov-cost-strip {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding: 14px 16px;
  margin-bottom: 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: linear-gradient(120deg, rgba(5, 150, 105, 0.08), var(--surface));
}
.ov-cost-strip[hidden] {
  display: none;
}
.ov-cost-main {
  display: flex;
  align-items: baseline;
  gap: 10px;
  min-width: 0;
}
.ov-cost-label {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  font-weight: 600;
}
.ov-cost-amount {
  font-family: var(--font-display);
  font-size: 1.35rem;
  font-weight: 700;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.ov-cost-note {
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.ov-cost-markup {
  color: var(--primary-dark);
  font-weight: 700;
  border: 1px solid rgba(5, 150, 105, 0.4);
  border-radius: 999px;
  padding: 2px 8px;
  background: rgba(5, 150, 105, 0.08);
}

.priority-filter-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
  flex-wrap: wrap;
}

.priority-filter-label {
  font-size: var(--text-xs);
  color: var(--dim);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 700;
}

.priority-filter-pills {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.priority-filter-pills .btn {
  border-radius: 999px;
  min-width: 104px;
  justify-content: center;
}

.priority-sticky-actions {
  position: sticky;
  top: 68px;
  z-index: 8;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin: 8px 0 12px;
  padding: 10px;
  border: 1px solid rgba(0, 0, 0, 0.09);
  border-radius: var(--radius-sm);
  background: var(--surface);
  backdrop-filter: blur(8px);
}

.priority-sticky-meta {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 180px;
}

.priority-sticky-meta #media-selection-summary {
  color: var(--text);
  font-size: var(--text-sm);
  font-weight: 700;
}

.priority-sticky-meta #media-selection-hint {
  color: var(--dim);
  font-size: var(--text-xs);
}

.priority-sticky-buttons {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  justify-content: flex-end;
}

.priority-sticky-actions.has-selection {
  border-color: color-mix(in srgb, var(--primary) 30%, transparent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--primary) 12%, transparent) inset;
}

/* ΓÇöΓÇöΓÇö Orchestration guardrails ΓÇöΓÇöΓÇö */
.orchestration-panel {
  margin: 0;
}
.status-rail {
  position: fixed;
  top: calc(56px + var(--banner-h, 0px));
  right: 0;
  bottom: 0;
  width: var(--status-rail-width);
  overflow-y: auto;
  padding: 16px 12px;
  border-inline-start: 1px solid var(--border);
  background: var(--surface);
  z-index: 45;
}
.status-rail-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 12px;
  padding: 2px 2px 0;
}
.status-rail-eyebrow {
  font-size: var(--text-2xs);
  color: var(--dim);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-weight: 700;
}
.status-rail-title {
  font-family: var(--font-display);
  font-size: 1rem;
  line-height: 1.1;
  margin-top: 2px;
}
.orchestration-grid {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.orchestration-card {
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-2);
  padding: 11px;
  min-height: auto;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.025);
}
.orchestration-card:hover {
  border-color: var(--border-light);
  background: var(--surface-3);
}
.orchestration-runs-card {
  min-height: auto;
}
.orchestration-card-kicker {
  font-size: 0.64rem;
  color: var(--dim);
  text-transform: uppercase;
  letter-spacing: 0.09em;
  font-weight: 700;
  margin-bottom: 6px;
}
.orchestration-status {
  display: inline-flex;
  align-items: center;
  max-width: 100%;
  padding: 3px 8px;
  border-radius: 999px;
  font-size: var(--text-2xs);
  font-weight: 700;
  margin-bottom: 7px;
  border: 1px solid var(--border);
  color: var(--text-secondary);
}
.orchestration-status[data-tone='success'] {
  color: var(--primary);
  border-color: color-mix(in srgb, var(--primary) 35%, transparent);
  background: color-mix(in srgb, var(--primary) 10%, transparent);
}
.orchestration-status[data-tone='warning'] {
  color: #ffd17f;
  border-color: rgba(255, 184, 0, 0.35);
  background: rgba(255, 184, 0, 0.12);
}
.orchestration-status[data-tone='error'] {
  color: var(--danger-fg);
  border-color: color-mix(in srgb, var(--red) 40%, transparent);
  background: color-mix(in srgb, var(--red) 12%, transparent);
}
.orchestration-status[data-tone='info'] {
  color: #8ec5ff;
  border-color: rgba(59, 130, 246, 0.35);
  background: rgba(59, 130, 246, 0.12);
}
.orchestration-copy {
  color: var(--text-secondary);
  font-size: 0.76rem;
  line-height: 1.45;
}
.orchestration-runs {
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.orchestration-run-item {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 8px;
  border-radius: var(--radius);
  border: 1px solid rgba(0, 0, 0, 0.07);
  background: rgba(0, 0, 0, 0.02);
}
.orchestration-run-main {
  min-width: 0;
}
.orchestration-run-title {
  font-size: var(--text-sm);
  color: var(--text);
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.orchestration-run-meta {
  margin-top: 3px;
  color: var(--dim);
  font-size: var(--text-xs);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.orchestration-run-counts {
  display: flex;
  gap: 5px;
  align-items: center;
  color: var(--text-secondary);
  font-size: var(--text-2xs);
}
.orchestration-run-counts span {
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 2px 6px;
}

/* ΓÇöΓÇöΓÇö Operating model ΓÇöΓÇöΓÇö */
.operating-model {
  margin-bottom: 24px;
  padding: 16px;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--surface);
}
.operating-model-title {
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 700;
  margin-bottom: 4px;
}
.operating-model-subtitle {
  font-size: var(--text-base);
  color: var(--text-secondary);
  margin-bottom: 12px;
}
.operating-model-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}
.operating-model-card {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  padding: 12px;
}
.operating-model-card.define {
  border-inline-start: 3px solid var(--primary);
}
.operating-model-card.execute {
  border-inline-start: 3px solid var(--blue);
}
.operating-model-card h3 {
  font-family: var(--font-display);
  font-size: 0.9rem;
  margin-bottom: 8px;
}
.operating-model-list {
  margin-inline-start: 16px;
  color: var(--text-secondary);
  font-size: var(--text-base);
  line-height: 1.45;
}
.operating-model-list li + li {
  margin-top: 6px;
}
.operating-model-flow {
  margin-top: 12px;
  border: 1px dashed color-mix(in srgb, var(--primary) 30%, transparent);
  border-radius: var(--radius-sm);
  padding: 10px;
  background: color-mix(in srgb, var(--primary) 4%, transparent);
}
.operating-model-flow-title {
  font-size: var(--text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--primary);
  margin-bottom: 8px;
  font-weight: 600;
}
.operating-model-sequence {
  margin-inline-start: 16px;
  font-size: var(--text-base);
  color: var(--text);
  line-height: 1.45;
}
.operating-model-sequence li + li {
  margin-top: 4px;
}

/* ΓÇöΓÇöΓÇö Buttons ΓÇöΓÇöΓÇö */
.btn {
  padding: 8px 16px;
  border: none;
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 600;
  transition: var(--transition);
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
/* `display:inline-flex` above is an author rule, and an author rule always beats the user agent's
   `[hidden] { display: none }` — so every `<button class="btn" hidden>` in this app would render
   anyway. Caught by test/uni-cloud-hidden-attribute-guard.test.mjs on the EventsHub "Group
   attendees" button, which is hidden until an event is chosen. Stated once here for every .btn
   rather than per call site, since the next author to write `hidden` on a button will not know. */
.btn[hidden] {
  display: none;
}
.btn-primary {
  background: var(--primary);
  color: #000;
}
.btn-primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 16px var(--primary-glow);
}
.btn-secondary {
  background: var(--surface-2);
  color: var(--text);
  border: 1px solid var(--border);
}
.btn-secondary:hover {
  background: var(--surface-3);
  border-color: var(--border-light);
}
.btn-danger {
  background: rgba(255, 51, 102, 0.1);
  color: var(--red);
  border: 1px solid rgba(255, 51, 102, 0.2);
}
.btn-danger:hover {
  background: rgba(255, 51, 102, 0.2);
}
.btn-sm {
  padding: 6px 12px;
  font-size: var(--text-sm);
}
.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none !important;
}

/* ΓÇöΓÇöΓÇö Forms ΓÇöΓÇöΓÇö */
.form-group {
  margin-bottom: 16px;
}
.form-label {
  display: block;
  font-size: var(--text-sm);
  color: var(--dim);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-bottom: 6px;
}
.form-input,
.form-select,
.form-textarea {
  width: 100%;
  padding: 10px 14px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 0.9rem;
  outline: none;
  transition: var(--transition);
}
.form-input:focus,
.form-textarea:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-glow);
}
.form-input::placeholder {
  color: var(--dim);
}
.form-textarea {
  resize: vertical;
  min-height: 80px;
}
.form-row {
  display: flex;
  gap: 12px;
}
.form-row > * {
  flex: 1;
}
/* The sentence under a field that says what it is for. Every form in this app had been writing
   its own inline style for this, which is why no two of them matched. */
.form-hint {
  font-size: var(--text-sm);
  color: var(--dim);
  line-height: 1.5;
  margin-top: 6px;
}
.form-label .req {
  color: var(--red);
}

/* ΓÇöΓÇöΓÇö Cards grid ΓÇöΓÇöΓÇö */
.pages-action-banner {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 0 0 12px;
  padding: 10px 12px;
  border: 1px solid color-mix(in srgb, var(--primary) 35%, transparent);
  border-radius: 10px;
  background: color-mix(in srgb, var(--primary) 8%, transparent);
  color: var(--text);
}

.pages-action-banner strong {
  font-size: var(--text-sm);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--primary);
}

.pages-action-banner span {
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

.pages-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 14px;
}
.page-card-item {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px;
  transition: var(--transition);
}
.page-card-item:hover {
  border-color: var(--border-light);
}
.page-card-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
}
.page-card-avatar {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: var(--primary);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1rem;
  color: white;
  flex-shrink: 0;
}
.page-card-info {
  flex: 1;
  overflow: hidden;
}
.page-card-name {
  font-weight: 600;
  font-size: var(--text-md);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.page-card-phone {
  font-size: var(--text-sm);
  color: var(--dim);
}
.page-card-stats {
  display: flex;
  gap: 16px;
  font-size: var(--text-sm);
  color: var(--dim);
  margin-bottom: 12px;
}
.page-card-message-status {
  font-size: var(--text-sm);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 7px 9px;
  margin-bottom: 6px;
  color: var(--text-secondary);
  background: rgba(0, 0, 0, 0.02);
}
.page-card-message-status.none {
  color: var(--dim);
}
.page-card-message-status.sent {
  border-color: color-mix(in srgb, var(--primary) 35%, transparent);
  color: var(--primary);
  background: color-mix(in srgb, var(--primary) 10%, transparent);
}
.page-card-message-status.queued {
  border-color: rgba(255, 184, 0, 0.35);
  color: #ffd17f;
  background: rgba(255, 184, 0, 0.12);
}
.page-card-message-status.failed {
  border-color: color-mix(in srgb, var(--red) 40%, transparent);
  color: var(--danger-fg);
  background: color-mix(in srgb, var(--red) 12%, transparent);
}
.page-card-message-meta {
  font-size: var(--text-xs);
  color: var(--dim);
  margin-bottom: 12px;
}
/* Two real actions, then quieter text links. The row used to be seven equal buttons, which made
   every one of them look optional and hid the one that matters. */
.page-card-actions {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
}
.page-card-more {
  display: flex;
  gap: 14px;
  align-items: center;
  margin-inline-start: auto;
}
.page-card-link {
  background: none;
  border: 0;
  padding: 2px 0;
  cursor: pointer;
  font-family: inherit;
  font-size: var(--text-2xs);
  font-weight: 600;
  color: var(--dim);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.page-card-link:hover {
  color: var(--text);
}
.page-card-link.danger:hover {
  color: var(--danger, #b91c1c);
}

/* Share sheet: the five old distribution buttons, one level down, as a choice. */
.share-sheet-url {
  font-family: 'IBM Plex Mono', monospace;
  font-size: var(--text-2xs);
  color: var(--dim);
  word-break: break-all;
  margin: 0 0 16px;
}
.share-sheet-options {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.share-opt {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  text-align: start;
  padding: 12px 14px;
  border-radius: 10px;
  cursor: pointer;
  background: var(--surface);
  border: 1px solid var(--border);
  font-family: inherit;
  color: var(--text);
  transition: var(--transition);
}
.share-opt:hover {
  border-color: var(--primary);
  background: var(--surface-2);
}
.share-opt > span:first-child {
  font-size: 1.1rem;
  line-height: 1;
}
.share-opt b {
  display: block;
  font-size: var(--text-sm);
  font-weight: 600;
}
.share-opt small {
  display: block;
  font-size: var(--text-2xs);
  color: var(--dim);
  margin-top: 2px;
}

/* ΓÇöΓÇöΓÇö Status badges ΓÇöΓÇöΓÇö */
.badge {
  display: inline-flex;
  align-items: center;
  padding: 2px 8px;
  border-radius: 10px;
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.badge-claimed {
  background: color-mix(in srgb, var(--primary) 10%, transparent);
  color: var(--primary);
}
.badge-unclaimed {
  background: rgba(255, 184, 0, 0.1);
  color: var(--amber);
}
.badge-suspended {
  background: rgba(255, 51, 102, 0.1);
  color: var(--red);
}
.badge-pending {
  background: rgba(124, 58, 237, 0.1);
  color: var(--primary);
}
.badge-received {
  background: rgba(124, 58, 237, 0.1);
  color: var(--primary);
}
.badge-payment_requested {
  background: rgba(255, 184, 0, 0.1);
  color: var(--amber);
}
.badge-paid {
  background: color-mix(in srgb, var(--primary) 10%, transparent);
  color: var(--primary);
}
.badge-fulfilled {
  background: color-mix(in srgb, var(--primary) 15%, transparent);
  color: var(--primary);
}
.badge-cancelled {
  background: rgba(255, 51, 102, 0.1);
  color: var(--red);
}
.badge-expired {
  background: rgba(255, 51, 102, 0.08);
  color: var(--dim);
}

/* ΓÇöΓÇöΓÇö Activity timeline ΓÇöΓÇöΓÇö */
.timeline {
  position: relative;
  padding-inline-start: 28px;
}
.timeline::before {
  content: '';
  position: absolute;
  left: 8px;
  top: 6px;
  bottom: 6px;
  width: 2px;
  background: var(--border);
}
.timeline-item {
  position: relative;
  margin-bottom: 16px;
}
.timeline-dot {
  position: absolute;
  left: -24px;
  top: 4px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--primary);
  border: 2px solid var(--surface);
}
.timeline-dot.note {
  background: var(--blue);
}
.timeline-dot.reminder {
  background: var(--amber);
}
.timeline-dot.interaction {
  background: var(--primary);
}
.timeline-content {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 12px 14px;
}
.timeline-title {
  font-weight: 600;
  font-size: 0.9rem;
  margin-bottom: 2px;
}
.timeline-body {
  font-size: var(--text-base);
  color: var(--text-secondary);
}
.timeline-meta {
  font-size: var(--text-xs);
  color: var(--dim);
  margin-top: 6px;
}

/* ΓÇöΓÇöΓÇö Recommendation cards ΓÇöΓÇöΓÇö */
.rec-card {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px;
  margin-bottom: 10px;
  display: flex;
  gap: 14px;
  align-items: flex-start;
  transition: var(--transition);
}
.rec-card:hover {
  border-color: var(--border-light);
}
.rec-priority {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: var(--text-sm);
  flex-shrink: 0;
}
.rec-priority.high {
  background: rgba(255, 51, 102, 0.1);
  color: var(--red);
}
.rec-priority.medium {
  background: rgba(255, 184, 0, 0.1);
  color: var(--amber);
}
.rec-priority.low {
  background: color-mix(in srgb, var(--primary) 10%, transparent);
  color: var(--primary);
}
.rec-content {
  flex: 1;
}
.rec-title {
  font-weight: 600;
  font-size: 0.9rem;
  margin-bottom: 2px;
}
.rec-body {
  font-size: var(--text-base);
  color: var(--text-secondary);
}
.rec-actions {
  display: flex;
  gap: 6px;
  margin-top: 8px;
}

/* ΓÇöΓÇöΓÇö Modal ΓÇöΓÇöΓÇö */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.7);
  backdrop-filter: blur(4px);
  z-index: 200;
  display: none;
  align-items: center;
  justify-content: center;
}
.modal-overlay.active {
  display: flex;
}
/* The media picker is always opened FROM something, often another dialog (the event editor, a
   template form). At the same z-index it sat behind whichever dialog came later in the page: the
   event editor's "Choose image" opened an invisible picker. Just above ordinary dialogs, still below
   toasts and popovers (300+). */
#modal-media-picker.modal-overlay {
  z-index: 210;
}
.modal {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 28px;
  max-width: 500px;
  width: 90%;
  max-height: 85vh;
  overflow-y: auto;
  animation: modal-in 0.2s ease;
}
.modal-wide {
  max-width: 920px;
  width: min(96vw, 920px);
}
.modal-xl {
  max-width: 1180px;
  width: min(96vw, 1180px);
  padding: 0;
  max-height: 92vh;
  overflow: hidden;
  border-radius: var(--radius);
}
/* Flow preview: near-fullscreen-height flex layout so Meta's rendered form gets essentially all
   available vertical space (a fixed px guess didn't scale to real window/viewport sizes and
   left content clipped/scrolled inside the iframe). Close is a corner ✕, not a bottom action
   row, to reclaim every pixel of height for the iframe itself. */
.modal-flow-preview {
  max-width: 480px;
  width: 94vw;
  height: 96vh;
  max-height: 96vh;
  padding: 16px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.modal-flow-preview-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex: none;
  margin-bottom: 10px;
}
.modal-flow-preview-head .modal-title {
  margin-bottom: 0;
}
.modal-flow-preview-x {
  border: none;
  background: none;
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
  color: var(--dim);
  padding: 4px 9px;
  border-radius: var(--radius-sm);
}
.modal-flow-preview-x:hover {
  color: var(--text, #111827);
  background: var(--surface-2, rgba(0, 0, 0, 0.06));
}
.modal-flow-preview-body {
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.modal-flow-preview-body iframe {
  width: 100%;
  height: 100%;
}
@keyframes modal-in {
  from {
    opacity: 0;
    transform: scale(0.96);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}
.modal-title {
  font-family: var(--font-display);
  font-size: 1.2rem;
  font-weight: 700;
  margin-bottom: 16px;
}
.modal-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-top: 20px;
}

/* ΓÇöΓÇöΓÇö Sync explorer in-page ΓÇöΓÇöΓÇö */
.sync-explorer-panel {
  margin: 18px 0 22px;
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--surface);
}

.sync-explorer-headline {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
}

.sync-explorer-header {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 6px;
}

.sync-explorer-title {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 700;
  letter-spacing: 0.01em;
}

.sync-explorer-subtitle {
  font-size: var(--text-sm);
  color: var(--dim);
}

.sync-explorer-primary-controls {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.sync-explorer-primary-controls #sync-filter-toggle.active {
  border-color: color-mix(in srgb, var(--primary) 32%, transparent);
  color: var(--primary);
  background: color-mix(in srgb, var(--primary) 12%, transparent);
}

.sync-drill-type-toggle {
  display: inline-flex;
  gap: 6px;
  padding: 3px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.02);
}

.sync-drill-type-toggle .btn {
  border-radius: 999px;
  padding-inline: 12px;
}

.sync-drill-type-toggle .btn.active {
  background: color-mix(in srgb, var(--primary) 16%, transparent);
  border-color: color-mix(in srgb, var(--primary) 32%, transparent);
  color: var(--primary);
}

.sync-explorer-search-row {
  margin: 10px 0 8px;
}

.sync-filter-panel {
  border: 1px solid rgba(0, 0, 0, 0.08);
  border-radius: 10px;
  padding: 10px;
  margin-bottom: 8px;
  background: rgba(0, 0, 0, 0.02);
  animation: syncFilterPanelIn 160ms ease-out;
}

@keyframes syncFilterPanelIn {
  from {
    opacity: 0;
    transform: translateY(-4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.sync-filter-row {
  display: grid;
  gap: 10px;
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

.sync-filter-row.compact {
  margin-top: 8px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.sync-filter-row .form-group {
  margin-bottom: 0;
}

.sync-filter-limit-wrap .form-select {
  max-width: 108px;
}

.sync-active-only {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

.sync-filter-chips {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  min-height: 28px;
  margin-bottom: 10px;
}

.sync-filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--primary) 35%, transparent);
  background: color-mix(in srgb, var(--primary) 10%, transparent);
  color: var(--primary);
  font-size: var(--text-xs);
  line-height: 1;
  transition:
    transform 120ms ease,
    background 120ms ease;
}

.sync-filter-chip button {
  appearance: none;
  border: 0;
  background: transparent;
  color: inherit;
  padding: 0;
  cursor: pointer;
  font-size: var(--text-sm);
  line-height: 1;
}

.sync-filter-chip:hover {
  transform: translateY(-1px);
  background: color-mix(in srgb, var(--primary) 14%, transparent);
}

.sync-filter-chip-empty {
  font-size: var(--text-xs);
  color: var(--dim);
}

.sync-filter-chips > .btn {
  padding: 4px 10px;
  font-size: var(--text-xs);
}

.sync-drill-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: 12px;
}

.sync-drill-list-shell {
  border: 1px solid var(--border);
  border-radius: 10px;
  background: rgba(0, 0, 0, 0.015);
  overflow: hidden;
}

.sync-drill-head {
  display: grid;
  gap: 8px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  background: rgba(0, 0, 0, 0.2);
}

.sync-drill-head.contacts {
  grid-template-columns: 2fr 0.9fr 0.8fr 1fr;
}

.sync-drill-head.groups {
  grid-template-columns: 2.2fr 0.8fr 1fr;
}

.sync-drill-head-cell {
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--dim);
  font-weight: 600;
}

.sync-drill-list-wrap {
  height: min(50vh, 520px);
  overflow: auto;
}

.sync-virtual-row {
  display: grid;
  gap: 8px;
  align-items: center;
  padding: 10px 12px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.05);
  cursor: pointer;
  transition: background 130ms ease;
}

.sync-virtual-row.contacts {
  grid-template-columns: 2fr 0.9fr 0.8fr 1fr;
}

.sync-virtual-row.groups {
  grid-template-columns: 2.2fr 0.8fr 1fr;
}

.sync-virtual-row:hover {
  background: color-mix(in srgb, var(--primary) 5%, transparent);
}

.sync-virtual-row.is-selected {
  background: color-mix(in srgb, var(--primary) 10%, transparent);
}

.sync-virtual-cell {
  min-width: 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sync-virtual-cell.primary {
  color: var(--text);
}

.sync-virtual-cell.primary strong {
  display: block;
  font-size: var(--text-base);
  font-weight: 600;
}

.sync-drill-inline-meta {
  font-size: var(--text-xs);
  color: var(--dim);
  margin-top: 2px;
}

.sync-drill-empty {
  padding: 22px;
  text-align: center;
  color: var(--dim);
  font-size: var(--text-sm);
}

.sync-drill-chip {
  display: inline-flex;
  padding: 2px 7px;
  border-radius: 999px;
  border: 1px solid var(--border);
  font-size: var(--text-xs);
  color: var(--text-secondary);
  margin: 1px 4px 1px 0;
}

.sync-drill-chip.primary {
  color: var(--primary);
  border-color: color-mix(in srgb, var(--primary) 35%, transparent);
  background: color-mix(in srgb, var(--primary) 10%, transparent);
}

.sync-drill-chip.risk {
  color: var(--danger-fg);
  border-color: color-mix(in srgb, var(--red) 40%, transparent);
  background: color-mix(in srgb, var(--red) 12%, transparent);
}

.sync-drill-detail {
  border: 1px solid var(--border);
  border-radius: 10px;
  background: rgba(0, 0, 0, 0.015);
  padding: 12px;
  max-height: min(50vh, 520px);
  overflow: auto;
}

.sync-drill-detail-empty {
  color: var(--dim);
  font-size: var(--text-sm);
  line-height: 1.5;
}

.sync-drill-detail-title {
  font-family: var(--font-display);
  font-size: 1rem;
  margin-bottom: 8px;
}

.sync-drill-detail-content {
  display: flex;
  flex-direction: column;
}

.sync-drill-detail-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-bottom: 10px;
}

.sync-drill-detail-mode {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 8px;
  font-size: var(--text-xs);
  color: var(--dim);
}

.sync-drill-detail-mode-badge {
  display: inline-flex;
  align-items: center;
  border-radius: 999px;
  padding: 2px 8px;
  border: 1px solid var(--border);
  background: rgba(0, 0, 0, 0.04);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 0.62rem;
  color: var(--text-secondary);
}

.sync-drill-detail-mode-badge.prospecting {
  border-color: rgba(59, 130, 246, 0.35);
  color: #8ec5ff;
  background: rgba(59, 130, 246, 0.12);
}

.sync-drill-detail-mode-badge.follow-up {
  border-color: color-mix(in srgb, var(--primary) 35%, transparent);
  color: var(--primary);
  background: color-mix(in srgb, var(--primary) 12%, transparent);
}

.sync-drill-detail-mode-badge.risk-watch {
  border-color: color-mix(in srgb, var(--red) 40%, transparent);
  color: var(--danger-fg);
  background: color-mix(in srgb, var(--red) 14%, transparent);
}

.sync-drill-detail-mode-badge.group {
  border-color: rgba(255, 184, 0, 0.35);
  color: #ffd17f;
  background: rgba(255, 184, 0, 0.14);
}

.sync-drill-detail-section {
  margin-bottom: 10px;
}

.sync-drill-detail-kv {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px;
}

.sync-drill-detail-kv-item {
  border: 1px solid rgba(0, 0, 0, 0.07);
  border-radius: var(--radius);
  padding: 6px 8px;
  background: rgba(0, 0, 0, 0.015);
}

.sync-drill-detail-kv-key {
  display: block;
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--dim);
  margin-bottom: 2px;
}

.sync-drill-detail-kv-value {
  display: block;
  font-size: var(--text-sm);
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sync-drill-detail-label {
  color: var(--dim);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: var(--text-2xs);
  margin-bottom: 4px;
}

.sync-drill-detail-text {
  font-size: var(--text-sm);
  line-height: 1.5;
  color: var(--text-secondary);
  white-space: pre-wrap;
}

.sync-drill-detail-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.sync-source-badge {
  display: inline-flex;
  align-items: center;
  font-size: var(--text-xs);
  margin-inline-start: 3px;
  cursor: default;
  opacity: 0.8;
}

.sync-source-badges {
  display: inline-flex;
  gap: 2px;
  margin-inline-start: 6px;
  vertical-align: middle;
}

.sync-source-badge.wa-ok {
  color: #22c55e;
  font-weight: 700;
  font-size: var(--text-xs);
}

.sync-source-badge.wa-fail {
  color: #ef4444;
  font-weight: 700;
  font-size: var(--text-xs);
}

/* ═══ Connect sub-tabs (same pattern as Templates/Flows) ═══ */
.connect-subtabs {
  display: flex;
  gap: 8px;
  margin: 16px 0 18px;
  border-bottom: 1px solid var(--border);
}
.connect-subtab {
  font-size: var(--text-base);
  font-weight: 700;
  padding: 8px 4px;
  background: transparent;
  border: none;
  cursor: pointer;
  color: var(--dim);
  border-bottom: 2px solid transparent;
  transition:
    color 0.15s,
    border-color 0.15s;
}
.connect-subtab.is-active {
  color: var(--primary);
  border-bottom-color: var(--primary);
}
.connect-subtab-panel {
  display: none;
}
.connect-subtab-panel.is-active {
  display: block;
}

.connect-provider-strip {
  display: flex;
  gap: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  margin-bottom: 16px;
}
.connect-provider-tab {
  flex: 1;
  padding: 10px 6px;
  border: none;
  background: var(--bg);
  cursor: pointer;
  font-size: var(--text-sm);
  font-weight: 600;
  border-inline-end: 1px solid var(--border);
  transition: background 0.15s;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}
.connect-provider-tab:last-child {
  border-inline-end: none;
}
.connect-provider-icon {
  font-size: var(--text-lg);
}
.connect-provider-tab.active {
  background: var(--bg-card) !important;
  box-shadow: inset 0 -2px 0 var(--primary);
}
.connect-provider-tab:hover:not(.active) {
  background: rgba(255, 255, 255, 0.03) !important;
}

.connect-method-strip {
  display: flex;
  gap: 8px;
  margin-bottom: 14px;
}
.connect-method-tab {
  opacity: 0.6;
  border: 1px solid var(--border) !important;
}
.connect-method-tab.active {
  opacity: 1;
  background: var(--primary) !important;
  color: var(--on-primary) !important;
  border-color: var(--primary) !important;
}

.connect-guide {
  border-radius: var(--radius);
  padding: 12px 14px;
  margin-bottom: 14px;
  font-size: var(--text-sm);
  line-height: 1.6;
  color: var(--text-secondary);
}
.connect-guide strong {
  color: var(--text);
  font-size: var(--text-base);
}
.connect-guide ol,
.connect-guide ul {
  margin: 6px 0 0;
  padding-inline-start: 18px;
}
.connect-guide--green {
  background: color-mix(in srgb, var(--primary) 4%, transparent);
  border: 1px solid color-mix(in srgb, var(--primary) 15%, transparent);
}
.connect-guide--blue {
  background: rgba(59, 130, 246, 0.04);
  border: 1px solid rgba(59, 130, 246, 0.15);
}
.connect-guide--gray {
  background: rgba(148, 163, 184, 0.06);
  border: 1px solid rgba(148, 163, 184, 0.2);
}
.connect-guide--amber {
  background: rgba(255, 184, 0, 0.04);
  border: 1px solid rgba(255, 184, 0, 0.15);
}
.connect-guide-footer {
  margin-top: 8px;
  padding-top: 8px;
  font-size: var(--text-sm);
  color: var(--dim);
  border-top: 1px solid rgba(0, 0, 0, 0.06);
}

.sync-drill-action-stack {
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.sync-drill-action-target {
  font-size: var(--text-base);
  color: var(--text);
  line-height: 1.45;
}

.sync-drill-action-hint {
  font-size: var(--text-xs);
  color: var(--dim);
  line-height: 1.4;
}

.sync-drill-action-stack .btn {
  align-self: flex-start;
}

#sync-view-page-modal-target {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin-bottom: 6px;
}

#sync-view-page-status[data-tone='success'] {
  color: var(--primary);
}

#sync-view-page-status[data-tone='info'] {
  color: #8ec5ff;
}

#sync-view-page-status[data-tone='error'] {
  color: var(--danger-fg);
}

.sync-drill-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-top: 10px;
}

.sync-drill-footer-left {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.sync-drill-summary {
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

.sync-drill-page {
  font-size: var(--text-xs);
  color: var(--dim);
}

@media (max-width: 1080px) {
  .overview-metric-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .asset-board {
    grid-template-columns: minmax(0, 1fr);
  }

  .sync-drill-layout {
    grid-template-columns: minmax(0, 1fr);
  }

  .sync-drill-detail {
    max-height: none;
  }
}

@media (max-width: 1180px) {
  .dash-layout {
    display: block;
  }
  .dash-main {
    margin-inline-end: 0;
  }
  .overview-command-strip {
    flex-direction: column;
  }
  .overview-command-actions {
    justify-content: flex-start;
  }
  .status-rail {
    position: static;
    width: auto;
    margin: 0 24px 24px calc(var(--sidebar-width) + 24px);
    padding: 14px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--surface);
  }
  .orchestration-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 10px;
  }
}

@media (max-width: 900px) {
  .orchestration-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .sync-filter-row {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 768px) {
  .status-rail {
    margin: 0 16px 20px;
  }
}

@media (max-width: 780px) {
  .sync-explorer-headline {
    flex-direction: column;
    align-items: flex-start;
  }

  .sync-drill-head.contacts,
  .sync-virtual-row.contacts {
    grid-template-columns: 1.8fr 0.85fr 0.85fr;
  }

  .sync-drill-head.contacts .sync-drill-head-cell:nth-child(n + 4),
  .sync-virtual-row.contacts .sync-virtual-cell:nth-child(n + 4) {
    display: none;
  }

  .sync-drill-head.groups,
  .sync-virtual-row.groups {
    grid-template-columns: 1.9fr 0.9fr;
  }

  .sync-drill-head.groups .sync-drill-head-cell:nth-child(n + 3),
  .sync-virtual-row.groups .sync-virtual-cell:nth-child(n + 3) {
    display: none;
  }
}

@media (max-width: 560px) {
  .overview-metric-grid,
  .asset-summary-grid {
    grid-template-columns: minmax(0, 1fr);
  }
  .overview-list-item,
  .asset-list-item {
    align-items: stretch;
    flex-direction: column;
  }
  .overview-list-value,
  .asset-list-value {
    align-self: flex-start;
  }

  .priority-sticky-actions {
    flex-direction: column;
    align-items: stretch;
  }

  .priority-sticky-buttons {
    justify-content: flex-start;
  }

  .priority-filter-pills .btn {
    min-width: 0;
  }

  .sync-filter-row {
    grid-template-columns: minmax(0, 1fr);
  }

  .sync-filter-row.compact {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }

  .sync-drill-detail-kv {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ΓÇöΓÇöΓÇö Toast ΓÇöΓÇöΓÇö */
.toast-container {
  position: fixed;
  top: 70px;
  right: 20px;
  z-index: 300;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.toast {
  padding: 12px 16px;
  border-radius: var(--radius-sm);
  font-size: var(--text-base);
  font-weight: 500;
  animation: toast-in 0.3s ease;
  min-width: 250px;
  max-width: 400px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
}
@keyframes toast-in {
  from {
    opacity: 0;
    transform: translateX(20px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}
.toast.success {
  background: color-mix(in srgb, var(--primary) 12%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--primary) 35%, var(--border));
  color: var(--primary-dark);
}
.toast.error {
  background: color-mix(in srgb, var(--red) 10%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--red) 35%, var(--border));
  color: var(--red);
}
.toast.info {
  background: color-mix(in srgb, var(--blue) 10%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--blue) 35%, var(--border));
  color: #1d4ed8;
}
.toast.warning {
  background: color-mix(in srgb, var(--amber) 12%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--amber) 35%, var(--border));
  color: var(--amber);
}

/* ——— In-app dialogs (confirm / prompt) — branded, accessible replacement for native window.confirm/prompt ——— */
.uidlg-root {
  position: fixed;
  inset: 0;
  z-index: 4000;
  pointer-events: none;
}
.uidlg-root[aria-hidden='false'] {
  pointer-events: auto;
}
.uidlg-overlay {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(17, 24, 39, 0.45);
  opacity: 0;
  transition: opacity 0.16s ease;
}
.uidlg-overlay.is-open {
  opacity: 1;
}
.uidlg-card {
  width: 100%;
  max-width: 420px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.25);
  padding: 22px 22px 18px;
  transform: translateY(8px) scale(0.98);
  transition: transform 0.16s cubic-bezier(0.4, 0, 0.2, 1);
}
.uidlg-overlay.is-open .uidlg-card {
  transform: none;
}
.uidlg-title {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 700;
  color: var(--text);
}
.uidlg-msg {
  margin-top: 8px;
  font-size: 0.9rem;
  line-height: 1.55;
  color: var(--text-secondary);
}
.uidlg-field {
  display: block;
  margin-top: 14px;
}
.uidlg-input {
  width: 100%;
  padding: 9px 12px;
  border: 1px solid var(--border-light);
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: 0.9rem;
  color: var(--text);
  background: var(--surface-2);
}
.uidlg-input:focus {
  outline: 2px solid var(--primary);
  outline-offset: 1px;
  border-color: var(--primary);
}
.uidlg-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 20px;
}
.uidlg-btn {
  padding: 8px 16px;
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: var(--text-base);
  font-weight: 600;
  cursor: pointer;
  border: 1px solid var(--border-light);
  background: var(--surface);
  color: var(--text-secondary);
  transition: var(--transition);
}
.uidlg-btn:hover {
  background: var(--surface-2);
  color: var(--text);
}
.uidlg-ok {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--on-primary);
}
.uidlg-ok:hover {
  background: var(--primary-dark);
  border-color: var(--primary-dark);
  color: var(--on-primary);
}
.uidlg-ok.uidlg-danger {
  background: var(--red);
  border-color: var(--red);
}
.uidlg-ok.uidlg-danger:hover {
  background: var(--danger-fg-strong);
  border-color: var(--danger-fg-strong);
}
.uidlg-btn:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
  .uidlg-overlay,
  .uidlg-card {
    transition: none;
  }
}

/* ——— Command palette (Ctrl/Cmd-K) ——— */
.cmdk-trigger {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 30px;
  padding: 0 10px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--dim);
  border-radius: 20px;
  cursor: pointer;
  font: inherit;
  font-size: var(--text-sm);
}
.cmdk-trigger:hover {
  border-color: var(--border-light);
  color: var(--text-secondary);
}
.cmdk-trigger svg {
  width: 15px;
  height: 15px;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.cmdk-trigger kbd {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  padding: 1px 5px;
  color: var(--dim);
}
.cmdk-overlay {
  position: fixed;
  inset: 0;
  z-index: 5000;
  display: none;
  align-items: flex-start;
  justify-content: center;
  padding-top: 12vh;
  background: rgba(17, 24, 39, 0.4);
}
.cmdk-overlay.is-open {
  display: flex;
}
.cmdk-panel {
  width: 100%;
  max-width: 560px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.3);
  overflow: hidden;
}
.cmdk-input {
  width: 100%;
  border: none;
  border-bottom: 1px solid var(--border);
  padding: 16px 18px;
  font: inherit;
  font-size: 1rem;
  color: var(--text);
  background: transparent;
  outline: none;
}
.cmdk-list {
  list-style: none;
  margin: 0;
  padding: 6px;
  max-height: 50vh;
  overflow-y: auto;
}
.cmdk-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 9px 12px;
  border-radius: var(--radius);
  cursor: pointer;
  color: var(--text);
}
.cmdk-item[aria-selected='true'] {
  background: var(--primary-glow);
  color: var(--primary-dark);
}
.cmdk-item-label {
  font-size: 0.9rem;
  font-weight: 500;
}
.cmdk-item-group {
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--dim);
}
.cmdk-empty {
  padding: 20px;
  text-align: center;
  color: var(--dim);
  font-size: var(--text-base);
  list-style: none;
}
.cmdk-foot {
  display: flex;
  gap: 10px;
  align-items: center;
  padding: 8px 14px;
  border-top: 1px solid var(--border);
  font-size: var(--text-xs);
  color: var(--dim);
}
.cmdk-foot kbd {
  font-family: var(--font-mono);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  padding: 1px 5px;
}
@media (max-width: 560px) {
  .cmdk-trigger span,
  .cmdk-trigger kbd {
    display: none;
  }
}

/* ——— Header dropdowns: account menu + WhatsApp line indicator ——— */
.header-dd {
  position: relative;
  display: inline-flex;
}
.header-menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  min-width: 240px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.18);
  padding: 6px;
  z-index: 200;
}
.header-menu[hidden] {
  display: none;
}
.dd-chevron {
  width: 14px;
  height: 14px;
  stroke: currentColor;
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.7;
}
.account-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 32px;
  padding: 0 6px 0 4px;
  border: 1px solid var(--border);
  border-radius: 20px;
  background: var(--surface);
  cursor: pointer;
  color: var(--text-secondary);
}
.account-btn:hover {
  background: var(--surface-2);
}
.account-avatar {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--primary-glow);
  color: var(--primary);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.account-avatar svg {
  width: 15px;
  height: 15px;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.account-menu {
  min-width: 220px;
}
.account-menu-head {
  padding: 8px 10px 6px;
  color: var(--dim);
  font-size: var(--text-sm);
  border-bottom: 1px solid var(--border);
  margin-bottom: 4px;
}
.account-menu-head .dash-user {
  color: var(--text);
  font-weight: 600;
  font-size: var(--text-base);
}
.account-menu-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 10px;
  border: none;
  background: none;
  border-radius: 7px;
  cursor: pointer;
  font: inherit;
  font-size: var(--text-base);
  color: var(--text-secondary);
  text-align: start;
}
.account-menu-item:hover {
  background: var(--surface-2);
  color: var(--text);
}
.account-menu-item svg {
  width: 16px;
  height: 16px;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex: none;
}
.account-menu-item.danger {
  color: var(--red);
}
.account-menu-item.danger:hover {
  background: color-mix(in srgb, var(--red) 10%, var(--surface));
}
.account-menu-sep {
  height: 1px;
  background: var(--border);
  margin: 4px 0;
}
.line-indicator {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 30px;
  padding: 0 8px;
  border: 1px solid var(--border);
  border-radius: 20px;
  background: var(--surface-2);
  cursor: pointer;
  color: var(--text-secondary);
  font: inherit;
  font-size: var(--text-sm);
  max-width: 200px;
}
.line-indicator:hover {
  border-color: var(--border-light);
  color: var(--text);
}
.line-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.line-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex: none;
  background: var(--dim);
}
.line-dot.ok {
  background: var(--primary);
}
.line-dot.warn {
  background: var(--amber);
}
.line-dot.bad {
  background: var(--red);
}
.line-menu {
  min-width: 260px;
}
.line-menu-row {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 8px 10px;
}
.line-menu-row .line-dot {
  margin-top: 5px;
}
.line-menu-main {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}
.line-menu-label {
  font-size: var(--text-base);
  font-weight: 600;
  color: var(--text);
  display: flex;
  align-items: center;
  gap: 6px;
}
.line-default {
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--primary);
  border: 1px solid color-mix(in srgb, var(--primary) 40%, var(--border));
  border-radius: var(--radius-xs);
  padding: 0 4px;
  font-weight: 700;
}
.line-menu-sub {
  font-size: var(--text-xs);
  color: var(--dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.line-menu-manage {
  width: 100%;
  text-align: start;
  padding: 9px 10px;
  margin-top: 4px;
  border: none;
  border-top: 1px solid var(--border);
  background: none;
  cursor: pointer;
  font: inherit;
  font-size: var(--text-sm);
  color: var(--primary);
  font-weight: 600;
}
.line-menu-manage:hover {
  background: var(--surface-2);
}
@media (max-width: 780px) {
  .line-indicator .line-label {
    display: none;
  }
}

/* ΓÇöΓÇöΓÇö Table ΓÇöΓÇöΓÇö */
.data-table {
  width: 100%;
  border-collapse: collapse;
}
.data-table th {
  text-align: start;
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--dim);
  padding: 8px 12px;
  border-bottom: 1px solid var(--border);
}
.data-table td {
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  font-size: 0.9rem;
}
.data-table tr:hover td {
  background: var(--surface-2);
}

/* ΓÇöΓÇöΓÇö Empty state ΓÇöΓÇöΓÇö */
.empty-state {
  text-align: center;
  padding: 40px 20px;
  color: var(--dim);
}
.empty-icon {
  width: 48px;
  height: 48px;
  margin: 0 auto 12px;
  opacity: 0.15;
  background: url('/img/mark-light.png') center/contain no-repeat;
  font-size: 0;
  color: transparent;
  overflow: hidden;
}
@media (prefers-color-scheme: dark) {
  .empty-icon {
    background-image: url('/img/mark-dark.png');
  }
}
.empty-title {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 600;
  margin-bottom: 4px;
  color: var(--text-secondary);
}
.empty-desc {
  font-size: var(--text-base);
  margin-bottom: 16px;
}

/* ΓÇöΓÇöΓÇö Loader ΓÇöΓÇöΓÇö */
.loader {
  display: inline-block;
  width: 18px;
  height: 18px;
  border: 2px solid var(--border);
  border-top-color: var(--primary);
  border-radius: 50%;
  animation: spin 0.6s linear infinite;
}
@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

/* ΓÇöΓÇöΓÇö Search bar ΓÇöΓÇöΓÇö */
.search-bar {
  display: flex;
  gap: 8px;
  margin-bottom: 16px;
}
.search-input {
  flex: 1;
  padding: 8px 14px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 0.9rem;
  outline: none;
  transition: var(--transition);
}
.search-input:focus {
  border-color: var(--primary);
}
.search-input::placeholder {
  color: var(--dim);
}

/* ΓÇöΓÇöΓÇö Settings ΓÇöΓÇöΓÇö */
.section-group {
  margin-bottom: 36px;
}
.section-group + .section-group {
  margin-top: 8px;
  padding-top: 28px;
  border-top: 1px solid var(--border);
}
.section-group-title {
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: 0.2px;
  color: var(--primary);
  margin-bottom: 18px;
  padding-inline-start: 12px;
  border-inline-start: 4px solid var(--primary);
  line-height: 1.3;
}
.settings-section {
  margin-bottom: 24px;
}
.settings-section-title {
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 600;
  margin-bottom: 12px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--border);
}
.hint-text {
  font-size: var(--text-base);
  color: var(--text-secondary);
  margin-bottom: 14px;
}
.overview-panel + .overview-panel {
  margin-top: 16px;
}
.flex-row {
  display: flex;
  gap: 8px;
  align-items: center;
}
.flex-row-wrap {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
}
.tab-subheading {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  margin: 24px 0 12px;
}
.api-key-display {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: var(--text-base);
  color: var(--text-secondary);
}
.api-key-display .mask {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ═══ Switch — a shared control, not a Settings one ═══════════════════════════════════════════
   Styled directly ON an <input type=checkbox> via appearance:none, so adopting it is adding one
   class: no markup restructuring, no id changes, every existing .checked read keeps working.

   Use it ONLY where flipping it applies immediately. A checkbox inside a form you still have to
   submit, or one that selects rows out of a list, must stay a checkbox — a switch that needs a
   Save press afterwards promises something it does not do. (That rule is why most of this app's
   checkboxes correctly remain checkboxes: contact pickers, label pickers, weekday pickers.)

   Pair it with a <label for>: it is the control's accessible name AND a far larger hit target
   than the 40x23 switch itself. ═══════════════════════════════════════════════════════════════ */
.switch {
  appearance: none;
  -webkit-appearance: none;
  position: relative;
  flex: 0 0 auto;
  width: 40px;
  height: 23px;
  margin: 0;
  border-radius: 99px;
  background: var(--surface-3);
  border: 1px solid var(--border-light);
  cursor: pointer;
  transition:
    background 0.18s ease,
    border-color 0.18s ease;
}
.switch::before {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 17px;
  height: 17px;
  border-radius: 50%;
  background: var(--switch-knob);
  box-shadow: 0 1px 3px var(--switch-knob-shadow);
  transition: transform 0.18s ease;
}
.switch:checked {
  background: var(--primary);
  border-color: var(--primary);
}
.switch:checked::before {
  transform: translateX(17px);
}
.switch:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}
.switch:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
/* The painted switch is 40x23, under the 44px minimum this file enforces everywhere else. Rather
   than inflate the control (a chunky switch reads as a toy), ::after extends the hit area to 44px
   invisibly — clicks on a pseudo-element are still clicks on the input. */
.switch::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  min-width: 44px;
  min-height: 44px;
  width: 100%;
  height: 100%;
}

/* ═══════════════════════════════════════════════════════════════════════════
   SETTINGS COMPONENT SYSTEM (set-*)

   Settings previously carried 92 inline style= attributes, 6 different font
   sizes for the same "small text" job, 6 .btn class combinations and 15 raw
   checkboxes — because there was no primitive for "a setting", so every card
   was restyled by hand and every card drifted.

   These are that primitive. New settings markup uses ONLY these classes; the
   sizes come from the tokens.css type scale rather than fresh literals.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Two-column shell: nav rail + panel. Collapses to a stacked pill row at
      the mobile breakpoint (see the end-of-file mobile block). ── */
.set-layout {
  display: grid;
  grid-template-columns: 208px minmax(0, 1fr);
  gap: 32px;
  align-items: start;
}
.set-nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
  position: sticky;
  top: 12px;
}

/* The rail items keep the .settings-cat-btn/[data-cat] contract so the existing
   switcher in ui/settings.js keeps working untouched — only their look changes.
   .knw-cat-btn/.knw-category (AI Sources tab, ui/knowledge.js) share this same look via the
   comma rather than reusing the settings-* classes outright: settings.js's switcher queries
   .settings-category globally, and giving the AI Sources panels that literal class would make
   its own tablist toggle them too. */
.set-nav .settings-cat-btn,
.set-nav .knw-cat-btn,
.set-nav .eh-cat-btn {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 12px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 600;
  color: var(--text-secondary);
  text-align: start;
  cursor: pointer;
  transition: var(--transition);
}
.set-nav .settings-cat-btn:hover,
.set-nav .knw-cat-btn:hover,
.set-nav .eh-cat-btn:hover {
  background: var(--surface-2);
  color: var(--text);
}
.set-nav .settings-cat-btn.active,
.set-nav .knw-cat-btn.active,
.set-nav .eh-cat-btn.active {
  background: var(--primary-glow);
  color: var(--primary);
  font-weight: 700;
}
.set-nav-icon {
  flex: 0 0 16px;
  width: 16px;
  height: 16px;
  stroke: currentColor;
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.85;
}

.settings-category,
.knw-category,
.eh-category {
  display: none;
}
.settings-category.active,
.knw-category.active,
.eh-category.active {
  display: block;
}

/* ── Panel header: names the section and states what it answers ── */
.set-panel-head {
  margin-bottom: 18px;
}
.set-panel-title {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: 700;
  line-height: 1.25;
}
.set-panel-sub {
  margin-top: 3px;
  color: var(--dim);
  font-size: var(--text-base);
}

/* ── Card ── */
.set-card {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  padding: 16px 18px;
  margin-bottom: 14px;
}
.set-card-head {
  display: flex;
  align-items: center;
  gap: 10px;
}
.set-card-title {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 600;
  line-height: 1.3;
}
.set-card-desc {
  margin-top: 4px;
  color: var(--text-secondary);
  font-size: var(--text-base);
  line-height: 1.55;
}
.set-card-body {
  margin-top: 14px;
}
/* Body vanishes when collapsed; the header (and its status chip) stays readable. */
.set-card.is-collapsed .set-card-body {
  display: none;
}

/* ── Status chip: the whole config becomes scannable without opening a card ── */
.set-status {
  margin-inline-start: auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--dim);
  white-space: nowrap;
}
/* A card with nothing to report (Plan, Refer Klaros) must not leave a bare dot floating in its
   header — the ::before bullet renders even when the label is empty. */
.set-status:empty {
  display: none;
}
.set-status::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--border-light);
}
.set-status.is-on {
  color: var(--primary);
}
.set-status.is-on::before {
  background: var(--primary);
}
.set-status.is-warn {
  color: var(--amber);
}
.set-status.is-warn::before {
  background: var(--amber);
}
/* Saved / Saving / error feedback replaces the per-card save button. */
.set-status.is-saving {
  color: var(--dim);
}
.set-status.is-saved {
  color: var(--primary);
}
.set-status.is-error {
  color: var(--red);
}
.set-status.is-error::before {
  background: var(--red);
}
.set-undo {
  background: none;
  border: 0;
  padding: 0 0 0 2px;
  font: inherit;
  font-weight: 700;
  color: var(--primary);
  cursor: pointer;
  text-decoration: underline;
}
.set-status.is-error .set-undo {
  color: var(--red);
}
/* A failed save leaves the screen disagreeing with the server: the field shows your new value,
   the server still has the old one. Mark the card until it is actually reconciled, so a reload
   silently reverting it can't come as a surprise. */
.set-card.has-unsaved {
  border-color: var(--red);
  box-shadow: 0 0 0 3px var(--red-glow);
}
/* Not an error — a rule switched on before its message was written. Amber, because the fix is to
   finish typing, not to retry. */
.set-card.has-incomplete {
  border-color: var(--amber);
  box-shadow: 0 0 0 3px var(--amber-glow);
}

/* Rail attention: a section holding something unfinished (no Business context) or unsaved earns a
   dot, so you can see it without opening all six. */
.set-nav .settings-cat-btn,
.set-nav .knw-cat-btn,
.set-nav .eh-cat-btn {
  position: relative;
}
.set-nav .settings-cat-btn[data-attention]::after,
.set-nav .knw-cat-btn[data-attention]::after {
  content: '';
  position: absolute;
  top: 50%;
  right: 10px;
  transform: translateY(-50%);
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--amber);
}
.set-nav .settings-cat-btn[data-attention='error']::after,
.set-nav .knw-cat-btn[data-attention='error']::after {
  background: var(--red);
}

/* ── Row: ONE setting. Label+description left, control right. This single rule
      is what makes every setting in the page line up with every other one. ── */
.set-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20px;
  padding: 13px 0;
  border-top: 1px solid var(--border);
}
.set-card-body > .set-row:first-child {
  border-top: 0;
  padding-top: 0;
}
.set-row-main {
  min-width: 0;
  flex: 1;
}
.set-row-label {
  display: block;
  font-size: var(--text-base);
  font-weight: 600;
  color: var(--text);
}
/* A <label for> is the control's accessible name AND a second, much larger hit target than the
   switch itself — so it has to look clickable. */
label.set-row-label {
  cursor: pointer;
  width: fit-content;
  max-width: 100%;
}
.set-row-desc {
  margin-top: 3px;
  color: var(--dim);
  font-size: var(--text-sm);
  line-height: 1.5;
}
.set-row-control {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  max-width: 100%;
}
/* Wide inputs (textarea, long text) drop under the label instead of squeezing. */
.set-row.is-stacked {
  flex-direction: column;
  align-items: stretch;
  gap: 10px;
}
.set-row.is-stacked .set-row-control {
  width: 100%;
}
.set-row.is-stacked .set-row-control > .form-input,
.set-row.is-stacked .set-row-control > .form-select {
  width: 100%;
}
.set-row-error {
  margin-top: 6px;
  color: var(--red);
  font-size: var(--text-sm);
  font-weight: 600;
}

/* ── Sub-group: a labelled cluster inside a card (weekday pickers, hour ranges) ── */
.set-group {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  font-size: var(--text-base);
  color: var(--text-secondary);
}
.set-group-nowrap {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex-wrap: nowrap;
}
.set-check {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-base);
  color: var(--text);
  cursor: pointer;
}
.set-time {
  max-width: 92px;
}
.set-note {
  color: var(--dim);
  font-size: var(--text-sm);
  line-height: 1.5;
}
.set-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding-top: 13px;
  border-top: 1px solid var(--border);
}
.set-card-body > .set-actions:first-child {
  border-top: 0;
  padding-top: 0;
}

/* ─── Collapsible sections/groups ─── */
.section-group-title,
.settings-section-title,
.ac-panel-label,
.trust-section-label {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.section-group-title,
.settings-section-title,
.overview-panel-head,
.ac-panel-label,
.trust-section-label {
  cursor: pointer;
  user-select: none;
}
.section-group-title::after,
.settings-section-title::after,
.overview-panel-head::after,
.ac-panel-label::after,
.trust-section-label::after {
  content: '▾';
  font-size: 0.75em;
  opacity: 0.55;
  margin-inline-start: 8px;
  flex-shrink: 0;
  transition: transform 0.15s ease;
}
summary.trust-section-label {
  list-style: none;
}
summary.trust-section-label::-webkit-details-marker {
  display: none;
}
details:not([open]) > summary.trust-section-label::after {
  transform: rotate(-90deg);
}
.is-collapsed > .section-group-title::after,
.is-collapsed > .settings-section-title::after,
.is-collapsed > .overview-panel-head::after,
.is-collapsed > .ac-panel-label::after,
.is-collapsed > .trust-section-label::after {
  transform: rotate(-90deg);
}
/* !important: many children carry an inline style="display:flex" (checkbox rows, form rows
   throughout the app) which otherwise outranks this class-based rule and only partially collapses. */
.section-group.is-collapsed > *:not(.section-group-title),
.settings-section.is-collapsed > *:not(.settings-section-title),
.overview-panel.is-collapsed > *:not(.overview-panel-head),
.ac-panel-section.is-collapsed > *:not(.ac-panel-label),
.trust-section.is-collapsed > *:not(.trust-section-label) {
  display: none !important;
}
.danger-zone {
  border: 1px solid rgba(255, 51, 102, 0.2);
  border-radius: var(--radius);
  padding: 16px;
  background: rgba(255, 51, 102, 0.03);
}

/* ΓÇöΓÇöΓÇö Experience Navigator ΓÇöΓÇöΓÇö */
.experience-panel {
  position: fixed;
  top: 64px;
  right: 14px;
  width: min(420px, calc(100vw - 24px));
  max-height: calc(100vh - 80px);
  overflow: auto;
  z-index: 1800;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: 0 28px 56px rgba(0, 0, 0, 0.18);
  padding: 14px;
  display: none;
}

.experience-panel.visible {
  display: block;
  animation: experiencePanelIn 180ms ease-out;
}

@keyframes experiencePanelIn {
  from {
    opacity: 0;
    transform: translateY(-8px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

.experience-panel-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 12px;
}

.experience-panel-title {
  font-family: var(--font-display);
  font-size: 19px;
  font-weight: 600;
  color: var(--primary);
}

.experience-panel-subtitle {
  margin-top: 4px;
  font-size: 10px;
  line-height: 1.45;
  color: var(--dim);
}

.experience-metrics {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  margin-bottom: 12px;
}

.experience-chip {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--primary) 4%, transparent);
  padding: 8px;
}

.experience-chip span {
  display: block;
  font-size: 9px;
  color: var(--dim);
  text-transform: uppercase;
  letter-spacing: 1px;
  margin-bottom: 4px;
}

.experience-chip strong {
  font-size: 13px;
  color: var(--primary);
}

.experience-actions {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 10px;
  margin-bottom: 12px;
  background: rgba(0, 0, 0, 0.02);
}

.experience-actions .small-btn {
  margin: 0 0 8px;
  width: 100%;
  text-align: start;
  padding: 7px 9px;
  font-size: var(--text-base);
  background: color-mix(in srgb, var(--primary) 8%, transparent);
  border: 1px solid color-mix(in srgb, var(--primary) 15%, transparent);
  color: var(--primary);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: var(--transition);
}

.experience-actions .small-btn:hover {
  background: color-mix(in srgb, var(--primary) 15%, transparent);
  border-color: color-mix(in srgb, var(--primary) 30%, transparent);
}

.experience-actions .small-btn:last-child {
  margin-bottom: 0;
}

.experience-guide {
  border: 1px solid color-mix(in srgb, var(--primary) 20%, transparent);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--primary) 5%, transparent);
  padding: 10px;
}

.experience-guide-title {
  font-size: 9px;
  color: var(--primary);
  text-transform: uppercase;
  letter-spacing: 1px;
  margin-bottom: 8px;
  font-weight: 600;
}

.experience-guide-body {
  font-size: 11px;
  line-height: 1.55;
  color: var(--text);
  min-height: 54px;
  padding: 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: rgba(0, 0, 0, 0.18);
}

.experience-guide-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-top: 10px;
}

.ux-spotlight {
  position: relative;
  z-index: 1600;
  outline: 2px solid var(--primary);
  box-shadow:
    0 0 0 4px color-mix(in srgb, var(--primary) 20%, transparent),
    0 0 24px color-mix(in srgb, var(--primary) 40%, transparent);
  animation: uxPulse 1.2s ease-out 1;
}

@keyframes uxPulse {
  0% {
    box-shadow: 0 0 0 0 color-mix(in srgb, var(--primary) 45%, transparent);
  }
  100% {
    box-shadow:
      0 0 0 8px color-mix(in srgb, var(--primary) 0%, transparent),
      0 0 24px color-mix(in srgb, var(--primary) 25%, transparent);
  }
}
.danger-zone .settings-section-title {
  color: var(--red);
  border-bottom-color: var(--red-glow);
}

/* ΓÇöΓÇöΓÇö Responsive ΓÇöΓÇöΓÇö */
@media (max-width: 768px) {
  .dash-sidebar {
    transform: translateX(-100%);
    position: fixed;
    z-index: 60;
  }
  .dash-sidebar.open {
    transform: translateX(0);
  }
  .dash-main {
    margin-inline-start: 0;
    padding: 16px;
  }
  .stats-grid {
    grid-template-columns: repeat(2, 1fr);
  }
  .operating-model-grid {
    grid-template-columns: 1fr;
  }
  .sync-drill-layout {
    grid-template-columns: 1fr;
  }
  .sync-drill-detail {
    max-height: 26vh;
  }
  .sync-drill-action-stack .btn {
    align-self: stretch;
    justify-content: center;
  }
  .pages-grid {
    grid-template-columns: 1fr;
  }
  /* !important: individual .form-row usages set align-items:flex-end inline for the desktop
     side-by-side layout (aligning labels+inputs to a shared baseline). Once flex-direction flips
     to column here, align-items switches to the CROSS axis and that same flex-end value right-
     aligns every field's whole width instead of stretching it — inline style beats this class
     rule without !important, same fix as the collapse rule above. */
  .form-row {
    flex-direction: column;
    align-items: stretch !important;
  }
  .priority-sticky-actions {
    position: static;
    top: auto;
  }
  .menu-toggle {
    display: block;
  }
}
@media (min-width: 769px) {
  .menu-toggle {
    display: none;
  }
}
.menu-toggle {
  background: none;
  border: none;
  color: var(--text);
  font-size: 1.3rem;
  cursor: pointer;
  padding: 4px;
}
/* The nav-drawer scrim exists only in the mobile layout. .dash-layout is a flex container, so
   leaving this element in flow on desktop makes it a stray full-height flex item. */
.sidebar-scrim {
  display: none;
}

/* ΓÇöΓÇöΓÇö Registration overlay ΓÇöΓÇöΓÇö */
.reg-overlay {
  position: fixed;
  inset: 0;
  background: var(--bg);
  z-index: 500;
  display: flex;
  align-items: center;
  justify-content: center;
}
.reg-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 40px 32px;
  max-width: 440px;
  width: 90%;
  text-align: center;
}
.reg-logo {
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 2rem;
  color: var(--text);
  letter-spacing: -0.02em;
  margin-bottom: 8px;
}
.reg-subtitle {
  color: var(--dim);
  font-size: 0.9rem;
  margin-bottom: 28px;
}
.reg-key-display {
  background: var(--surface-2);
  border: 1px solid var(--primary);
  border-radius: var(--radius-sm);
  padding: 14px;
  margin: 16px 0;
  font-family: var(--font-mono);
  font-size: 0.9rem;
  color: var(--primary);
  word-break: break-all;
}
.reg-warning {
  color: var(--amber);
  font-size: var(--text-sm);
  margin-bottom: 16px;
}
.reg-signin { display: block; width: 100%; padding: 12px; text-align: center; text-decoration: none; }
.reg-more { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border); font-size: var(--text-sm); color: var(--dim); }
.reg-more > summary { cursor: pointer; }
.reg-more > summary:hover { color: var(--text); }
.reg-more[open] > summary { margin-bottom: 10px; }

/* ================================================================
   Trust Tab Styles
   ================================================================ */

/* Layout */
.trust-layout {
  display: grid;
  grid-template-columns: minmax(320px, 0.9fr) minmax(360px, 1.1fr);
  gap: 16px;
  height: calc(100vh - 210px);
  min-height: 480px;
  align-items: stretch;
}
@media (max-width: 1280px) {
  .trust-layout {
    grid-template-columns: 1fr;
    height: auto;
    min-height: 0;
  }
  .trust-contact-list {
    flex: initial;
    overflow: visible;
  }
  .trust-detail-panel {
    overflow: visible;
  }
}

/* Contact panel */
.trust-contact-panel {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
  box-shadow: none;
}
.trust-contact-panel .search-bar {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: 8px;
  padding: 8px;
  margin-bottom: 4px;
}
.trust-contact-panel .search-input {
  min-width: 0;
}
.trust-contact-panel .btn {
  white-space: nowrap;
}
.trust-contact-list {
  flex: 1;
  overflow-y: auto;
  padding: 10px;
}
.trust-list-footer {
  padding: 10px;
  border-top: 1px solid var(--border);
}

@media (max-width: 620px) {
  .trust-contact-panel .search-bar {
    grid-template-columns: 1fr 1fr;
  }
  .trust-contact-panel .search-input {
    grid-column: 1 / -1;
  }
}

/* Contact rows in list */
.trust-contact-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  padding: 12px;
  border-radius: 10px;
  cursor: pointer;
  gap: 10px;
  transition:
    background 0.12s ease,
    border-color 0.12s ease;
  border: 1px solid var(--border);
  margin-bottom: 8px;
  background: var(--surface-2);
}
.trust-contact-row:hover {
  background: var(--surface-3);
}
.trust-contact-row.selected {
  background: var(--surface-3);
  border-color: var(--primary);
  box-shadow: none;
}
.trust-contact-row.is-enriched {
  border-color: var(--border-light);
}
.trust-contact-row.is-plain {
  border-color: var(--border);
}
.trust-contact-row-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.trust-contact-row-name {
  font-size: var(--text-md);
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.trust-enrichment-state {
  display: inline-flex;
  align-self: flex-start;
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: 999px;
  margin-bottom: 6px;
  border: 1px solid transparent;
}
.trust-enrichment-state-enriched {
  color: #0a3a22;
  background: #9ff5ca;
  border-color: #37c87f;
}
.trust-enrichment-state-plain {
  color: #d6d6d6;
  background: var(--surface-3);
  border-color: var(--border);
}
.trust-contact-row-subline {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
  color: var(--dim);
  font-size: var(--text-xs);
  margin-top: 2px;
}
.trust-contact-row-source {
  font-weight: 500;
  color: var(--text-secondary);
}
.trust-contact-list-phone {
  font-size: var(--text-xs);
  color: var(--dim);
}
.trust-contact-list-freshness {
  font-size: var(--text-2xs);
  color: var(--primary);
}

/* Tier pill in list row */
.trust-tier-pill {
  font-size: var(--text-xs);
  font-weight: 600;
  padding: 3px 9px;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--tier-color, #666) 45%, transparent);
  color: var(--tier-color, #666);
  background: transparent;
  white-space: nowrap;
  flex-shrink: 0;
}

/* Tier badge (detail header) */
.trust-tier-badge {
  display: inline-block;
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 4px 10px;
  border-radius: 99px;
  border: 1px solid color-mix(in srgb, var(--tier-color, #666) 40%, transparent);
  color: var(--tier-color, #666);
  background: color-mix(in srgb, var(--tier-color, #666) 12%, transparent);
}

/* Detail panel */
.trust-detail-panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow-y: auto;
  padding: 22px;
  box-shadow: none;
}

/* Contact header in detail */
.trust-contact-header {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 24px;
}
.trust-contact-avatar {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: var(--surface-3);
  border: 1px solid var(--border-light);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.3rem;
  font-weight: 600;
  color: var(--primary);
  flex-shrink: 0;
}
.trust-contact-name {
  font-size: var(--text-lg);
  font-weight: 600;
  color: var(--text);
}
.trust-contact-phone {
  font-size: var(--text-base);
  color: var(--dim);
}
.trust-tier-badge-wrap {
  margin-inline-start: auto;
  text-align: end;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
}
.trust-detail-score {
  display: block;
  font-size: var(--text-base);
  line-height: 1.3;
  font-weight: 600;
  color: var(--text-secondary);
  margin-top: 2px;
  text-transform: none;
}
.trust-detail-meta {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin: 0 0 12px;
}
.trust-detail-meta-chip {
  font-size: var(--text-xs);
  padding: 4px 10px;
  border-radius: var(--radius);
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text-secondary);
}
.trust-detail-panel.is-enriched .trust-detail-meta-chip:first-child {
  background: color-mix(in srgb, var(--primary-glow) 60%, var(--surface));
  border-color: var(--primary);
  color: var(--text);
}
.trust-detail-panel.is-enriched {
  border-color: color-mix(in srgb, var(--primary) 32%, var(--border));
}
.trust-detail-panel.is-plain {
  border-color: color-mix(in srgb, #8f8f8f 30%, var(--border));
}

/* Sections */
.trust-section {
  margin-bottom: 20px;
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: 16px;
  background: color-mix(in srgb, var(--surface) 82%, transparent);
}
.trust-section-label {
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--dim);
  margin-bottom: 12px;
}

/* Current decision */
.trust-score-breakdown {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.trust-breakdown-row {
  display: flex;
  justify-content: space-between;
  font-size: var(--text-base);
  padding: 8px 10px;
  border-radius: var(--radius);
  background: var(--surface-2);
  border: 1px solid var(--border);
}
.trust-breakdown-name {
  color: var(--text-secondary);
}
.trust-breakdown-pts {
  color: var(--primary);
  font-weight: 600;
}
.trust-flag {
  font-size: var(--text-xs);
  color: var(--amber);
  margin-top: 4px;
  padding: 3px 8px;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--amber) 30%, transparent);
  background: color-mix(in srgb, var(--amber) 12%, transparent);
}
.trust-explanation {
  font-size: var(--text-base);
  color: var(--text-secondary);
  background: var(--surface-2);
  border-radius: var(--radius);
  padding: 12px;
  margin-top: 10px;
  border: 1px solid var(--border);
  line-height: 1.45;
}

/* Why / Next Step summary card */
.trust-summary-card {
  border: 1px solid color-mix(in srgb, var(--verdict-color, var(--border)) 40%, var(--border));
  background: color-mix(in srgb, var(--verdict-color, var(--surface-2)) 7%, var(--surface-2));
  border-radius: 10px;
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.trust-summary-meaning {
  font-size: var(--text-base);
  color: var(--text);
  font-weight: 500;
}
.trust-summary-reason {
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.trust-summary-next-step {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  padding-top: 6px;
  border-top: 1px solid var(--border);
  line-height: 1.4;
}
.trust-summary-next-step::before {
  content: '\21aa\0020';
  opacity: 0.6;
}
.trust-summary-ai-status {
  font-size: var(--text-sm);
  color: var(--amber);
  background: color-mix(in srgb, var(--amber) 8%, var(--surface-2));
  border: 1px solid color-mix(in srgb, var(--amber) 30%, var(--border));
  border-radius: var(--radius);
  padding: 8px 10px;
  margin-top: 8px;
}
.trust-summary-operator-note {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin-top: 8px;
  opacity: 0.88;
}

/* Secondary action button style for trust panel header buttons */
.btn-secondary-action {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-secondary);
  font-size: var(--text-sm);
  padding: 5px 12px;
  border-radius: var(--radius);
  cursor: pointer;
  transition:
    border-color 0.12s,
    color 0.12s;
}
.btn-secondary-action:hover {
  border-color: var(--primary);
  color: var(--primary);
}

.trust-profile-intel-content {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.trust-profile-intel-status {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: var(--text-sm);
  color: var(--text-secondary);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 10px 12px;
  background: var(--surface-2);
}
.trust-profile-intel-status[data-tone='success'] {
  border-color: color-mix(in srgb, var(--primary) 42%, var(--border));
  background: color-mix(in srgb, var(--primary) 10%, var(--surface-2));
}
.trust-profile-intel-status[data-tone='info'] {
  border-color: color-mix(in srgb, var(--primary) 42%, var(--border));
  background: color-mix(in srgb, var(--primary) 9%, var(--surface-2));
}
.trust-profile-intel-status[data-tone='warning'] {
  border-color: color-mix(in srgb, var(--amber) 45%, var(--border));
  background: color-mix(in srgb, var(--amber) 10%, var(--surface-2));
}
.trust-profile-intel-status strong {
  color: var(--text);
  font-size: 0.9rem;
}
.trust-profile-intel-empty {
  font-size: var(--text-sm);
  color: var(--dim);
  background: var(--surface-2);
  border: 1px dashed var(--border);
  border-radius: 12px;
  padding: 10px 12px;
}
.trust-profile-intel-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}
.trust-profile-intel-chip {
  font-size: var(--text-xs);
  color: var(--text-secondary);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 7px 9px;
}
.trust-profile-intel-observations {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.trust-profile-intel-observations span {
  font-size: 0.76rem;
  color: var(--text-secondary);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 7px 9px;
}
.trust-profile-intel-observations span[data-tone='warning'] {
  color: var(--amber);
  border-color: color-mix(in srgb, var(--amber) 35%, var(--border));
  background: color-mix(in srgb, var(--amber) 8%, var(--surface-2));
}
.trust-profile-intel-observations span[data-tone='success'] {
  color: #7ee2a8;
  border-color: color-mix(in srgb, var(--primary) 35%, var(--border));
  background: color-mix(in srgb, var(--primary) 8%, var(--surface-2));
}
.trust-profile-intel-snippet {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  background: var(--surface-2);
  border-inline-start: 3px solid var(--primary);
  border-radius: 10px;
  padding: 8px 10px;
}

/* Override row */
.trust-override-row {
  display: flex;
  gap: 8px;
  align-items: center;
}
.trust-advanced-section details > summary {
  cursor: pointer;
  user-select: none;
  margin-bottom: 0;
}
.trust-advanced-section details[open] > summary {
  margin-bottom: 12px;
}

/* Claims list */
.trust-claims-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.trust-claim-row {
  background: linear-gradient(180deg, var(--surface-2), color-mix(in srgb, var(--surface-2) 85%, var(--primary-glow)));
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 14px 16px;
}
.trust-claim-header {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 4px;
}
.trust-claim-type {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text);
  text-transform: capitalize;
}
.trust-claim-source {
  font-size: var(--text-xs);
  color: var(--dim);
}
.trust-claim-license {
  font-size: var(--text-2xs);
  color: var(--dim);
  background: var(--surface-3);
  padding: 1px 6px;
  border-radius: var(--radius-xs);
}
.trust-claim-confidence {
  font-size: var(--text-2xs);
  color: var(--dim);
  padding: 1px 5px;
}
.trust-claim-summary {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 4px;
}
.trust-claim-summary-chip {
  font-size: var(--text-xs);
  padding: 4px 9px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text-secondary);
}
.trust-claim-group {
  border: 1px solid var(--border);
  border-radius: 14px;
  background: color-mix(in srgb, var(--surface) 86%, transparent);
  padding: 10px;
}
.trust-claim-group-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  cursor: pointer;
  list-style: none;
}
.trust-claim-group-head::-webkit-details-marker {
  display: none;
}
.trust-claim-group-title {
  font-size: var(--text-sm);
  font-weight: 700;
  color: var(--text);
}
.trust-claim-group-meta {
  font-size: var(--text-xs);
  color: var(--dim);
}
.trust-claim-group .trust-claim-row {
  margin-top: 8px;
}
.trust-source-badge {
  font-size: var(--text-2xs);
  padding: 1px 7px;
  border-radius: 10px;
  border: 1px solid transparent;
}
.trust-source-ai {
  background: #1a1a3a;
  color: #818cf8;
  border-color: #3730a3;
}
.trust-source-wa {
  background: #052e16;
  color: #4ade80;
  border-color: #166534;
}
.trust-source-op {
  background: #1c1917;
  color: #a8a29e;
  border-color: #44403c;
}
.trust-claim-value {
  font-size: 0.9rem;
  color: var(--text-secondary);
  margin-bottom: 4px;
}
.trust-claim-url a {
  font-size: var(--text-xs);
  color: var(--primary);
  word-break: break-all;
}
.trust-claim-actions {
  display: flex;
  gap: 8px;
  margin-top: 8px;
}

.trust-empty-card {
  border-radius: 14px;
  border: 1px dashed var(--border);
  background: var(--surface-2);
}

/* Enrichment stats bar */
.trust-enrich-bar {
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--surface) 90%, var(--primary-glow)) 0%,
    var(--surface) 100%
  );
  border: 1px solid color-mix(in srgb, var(--border) 70%, var(--primary) 30%);
  border-radius: 16px;
  padding: 14px 16px;
  margin-bottom: 18px;
}
.trust-enrich-text {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
  font-size: var(--text-sm);
}
.trust-enrich-label {
  color: var(--text-secondary);
}
.trust-enrich-tiers {
  display: flex;
  gap: 10px;
}
.trust-enrich-tier-chip {
  font-size: var(--text-2xs);
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 99px;
  border: 1px solid color-mix(in srgb, var(--tier-color, #666) 35%, transparent);
  color: var(--tier-color, #666);
  background: color-mix(in srgb, var(--tier-color, #666) 10%, transparent);
}
.trust-enrich-track {
  height: 6px;
  background: var(--surface-2);
  border-radius: 99px;
  overflow: hidden;
}
.trust-enrich-fill {
  height: 100%;
  background: var(--primary);
  border-radius: 99px;
  transition: width 0.6s ease;
}
.trust-triage-note {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin: 0 0 14px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-2);
  color: var(--text-secondary);
  font-size: var(--text-base);
}
.trust-triage-note strong {
  color: var(--text);
  font-size: var(--text-base);
}
.trust-triage-note span {
  text-align: end;
}
@media (max-width: 700px) {
  .trust-triage-note {
    align-items: flex-start;
    flex-direction: column;
    gap: 4px;
  }
  .trust-triage-note span {
    text-align: start;
  }
}

/* Tab strip filter */
.trust-tab-strip {
  display: flex;
  gap: 6px;
  padding: 10px 10px 2px;
  border-top: 1px solid var(--border);
  flex-wrap: wrap;
}
.trust-tab-btn {
  font-size: var(--text-sm);
  font-weight: 600;
  padding: 6px 14px;
  border-radius: 99px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--dim);
  cursor: pointer;
  transition: all 0.15s ease;
}
.trust-tab-btn:hover {
  background: var(--surface-2);
  color: var(--text);
  transform: translateY(-1px);
}
.trust-tab-btn.active {
  background: var(--primary-glow);
  border-color: var(--primary);
  color: var(--primary);
  font-weight: 700;
  box-shadow: 0 8px 18px rgba(0, 0, 0, 0.12);
}
.trust-tab-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  border-radius: 99px;
  background: var(--primary);
  color: #000;
  font-size: var(--text-2xs);
  font-weight: 700;
  padding: 0 5px;
  margin-inline-start: 4px;
  line-height: 1;
}
.trust-tab-btn.active .trust-tab-count {
  background: #000;
  color: var(--primary);
}

/* Evidence checklist */
.trust-evidence-checklist {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 4px;
}
.trust-evidence-item {
  display: grid;
  grid-template-columns: 18px 1fr auto;
  align-items: center;
  gap: 8px;
  padding: 5px 0;
  border-bottom: 1px solid var(--border);
}
.trust-evidence-item:last-child {
  border-bottom: none;
}
.trust-evidence-icon {
  font-size: var(--text-sm);
  text-align: center;
}
.trust-evidence-item[data-status='ok'] .trust-evidence-icon {
  color: var(--primary);
}
.trust-evidence-item[data-status='missing'] .trust-evidence-icon {
  color: var(--dim);
  opacity: 0.5;
}
.trust-evidence-label {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text);
}
.trust-evidence-item[data-status='missing'] .trust-evidence-label {
  color: var(--dim);
}
.trust-evidence-note {
  font-size: var(--text-xs);
  color: var(--text-secondary);
  text-align: end;
}

/* ── Kanban Deals Board ────────────────────────────────────────────── */
.deals-board-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 16px;
  align-items: start;
  overflow-x: auto;
  padding-bottom: 20px;
}
.deals-kanban-column {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 12px;
  display: flex;
  flex-direction: column;
  min-height: 480px;
  transition:
    border-color 0.2s ease,
    background 0.2s ease;
}
.deals-kanban-column.drag-over {
  border-color: var(--primary);
  background: var(--primary-glow);
}
.deals-column-header {
  border-top: 3px solid var(--primary);
  border-radius: var(--radius-sm) 6px 0 0;
  padding: 8px 4px 12px 4px;
  margin-bottom: 8px;
  border-bottom: 1px solid var(--border);
}
.deals-stage-title {
  font-weight: 700;
  font-size: 0.9rem;
  color: var(--text);
}
.deals-stage-total {
  font-size: var(--text-lg);
  font-weight: 800;
  color: var(--text);
  margin-top: 4px;
}
.deals-card-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  flex: 1;
}
.deals-column-empty {
  font-size: var(--text-sm);
  color: var(--dim);
  text-align: center;
  padding: 30px 10px;
  border: 1px dashed var(--border);
  border-radius: var(--radius);
}
.deals-card {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px;
  cursor: grab;
  transition:
    transform 0.15s ease,
    box-shadow 0.15s ease,
    opacity 0.15s ease;
}
.deals-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);
  border-color: var(--border-light);
}
.deals-card.is-dragging {
  opacity: 0.45;
  cursor: grabbing;
}
.deals-card-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 8px;
  margin-bottom: 6px;
}
.deals-card-title {
  font-weight: 700;
  font-size: var(--text-base);
  color: var(--text);
}
.deals-card-amount {
  font-weight: 800;
  font-size: var(--text-base);
  color: var(--primary);
  background: var(--primary-glow);
  padding: 2px 6px;
  border-radius: var(--radius-sm);
}
.deals-card-contact {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin-bottom: 4px;
}
.deals-card-company {
  font-size: var(--text-sm);
  color: var(--dim);
}
.deals-card-notes {
  font-size: 0.76rem;
  color: var(--dim);
  margin: 6px 0 10px 0;
  background: var(--surface-3);
  padding: 6px 8px;
  border-radius: var(--radius-sm);
  border-inline-start: 2px solid var(--border-light);
}
.deals-card-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding-top: 8px;
  margin-top: 8px;
  border-top: 1px solid var(--border);
}
.deals-stage-select {
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: var(--text-xs);
  padding: 3px 6px;
  cursor: pointer;
}

/* Inline "Add signal" action button on evidence checklist row */
.trust-evidence-action-btn {
  font-size: var(--text-2xs);
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 99px;
  border: 1px solid var(--primary);
  background: transparent;
  color: var(--primary);
  cursor: pointer;
  white-space: nowrap;
  transition:
    background 0.12s ease,
    color 0.12s ease;
}
.trust-evidence-action-btn:hover {
  background: var(--primary);
  color: #000;
}

/* Evidence progress bar */
.trust-evidence-progress {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
}
.trust-evidence-progress-track {
  flex: 1;
  height: 5px;
  background: var(--surface-2);
  border-radius: 99px;
  overflow: hidden;
}
.trust-evidence-progress-fill {
  height: 100%;
  background: var(--primary);
  border-radius: 99px;
  transition: width 0.5s ease;
  min-width: 3px;
}
.trust-evidence-progress-label {
  font-size: var(--text-2xs);
  font-weight: 600;
  color: var(--dim);
  white-space: nowrap;
}

/* Back button in stacked detail panel */
.trust-detail-back-btn {
  margin-bottom: 12px;
  align-self: flex-start;
}

/* Inline claim chips in list rows */
.trust-contact-row-claims {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-top: 6px;
}
.trust-claim-chip {
  font-size: var(--text-2xs);
  padding: 2px 8px;
  border-radius: 99px;
  background: var(--surface-3);
  border: 1px solid var(--border);
  color: var(--text-secondary);
  max-width: 130px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Source indicator in tier pill */
.trust-tier-pill-wrap {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
}
.trust-source-dot {
  font-size: var(--text-2xs);
  opacity: 0.7;
}

/* Skeleton shimmer */
@keyframes trust-shimmer {
  0% {
    background-position: -400px 0;
  }
  100% {
    background-position: 400px 0;
  }
}
.trust-skeleton-row {
  height: 58px;
  border-radius: var(--radius-sm);
  margin-bottom: 4px;
  background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface-3) 50%, var(--surface-2) 75%);
  background-size: 800px 100%;
  animation: trust-shimmer 1.5s infinite linear;
}

/* Add claim form */
.trust-add-claim-form {
  background: var(--surface-2);
  border-radius: var(--radius-sm);
  padding: 14px;
}
.trust-add-claim-form .form-row {
  display: flex;
  gap: 8px;
  margin-bottom: 8px;
}
.trust-add-claim-form .form-row .form-input,
.trust-add-claim-form .form-row .form-select {
  flex: 1;
}

/* Pending banner */
.trust-banner {
  background: color-mix(in srgb, var(--amber) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--amber) 30%, transparent);
  color: var(--amber);
  border-radius: var(--radius-sm);
  padding: 10px 16px;
  margin-bottom: 16px;
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 0.9rem;
}

/* Filter row */
.trust-filter-row {
  display: flex;
  gap: 8px;
  padding: 8px;
  border-top: 1px solid var(--border);
}
.trust-filter-row .form-select {
  flex: 1;
}

/* Search bar reuse */
.search-bar {
  display: flex;
  gap: 8px;
  padding: 8px;
}
.search-input {
  flex: 1;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 8px 12px;
  color: var(--text);
  font-size: var(--text-base);
  outline: none;
}
.search-input:focus {
  border-color: var(--primary);
}

/* Tab eyebrow */
.tab-eyebrow {
  color: var(--dim);
  font-size: 0.9rem;
  margin: -8px 0 16px;
}

/* Claims count chip */
.trust-claims-count {
  color: var(--dim);
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
}

/* ================================================================
   ACTION CENTER — Hero Card, Confidence, Bottom Bar, Secondary Panel
   ================================================================ */

/* Layout */
.ac-layout {
  display: flex;
  gap: 0;
  min-height: calc(100vh - 56px - 48px);
  position: relative;
  padding-bottom: 84px;
}
.ac-main {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding: 24px 24px 0 24px;
  transition: margin-right 0.25s ease;
}

/* Hero Primary Card */
.hero-card {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: 36px 32px 32px;
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08);
  cursor: pointer;
  transition:
    transform 0.2s ease,
    box-shadow 0.25s ease,
    border-color 0.2s ease;
  margin-bottom: 16px;
  flex: 0 0 auto;
}
.hero-card:hover {
  transform: translateY(-2px);
  box-shadow:
    0 8px 32px rgba(0, 0, 0, 0.4),
    0 1px 0 rgba(255, 255, 255, 0.06) inset;
  border-color: var(--border-light);
}
.hero-card:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}
.hero-card.pulse-nudge {
  animation: hero-pulse 0.6s ease 3;
}
@keyframes hero-pulse {
  0%,
  100% {
    box-shadow: 0 4px 24px rgba(0, 0, 0, 0.3);
  }
  50% {
    box-shadow: 0 4px 24px color-mix(in srgb, var(--primary) 25%, transparent);
  }
}
.hero-card .hero-edit-hint {
  position: absolute;
  top: 16px;
  right: 20px;
  opacity: 0;
  transition: opacity 0.2s ease;
  font-size: var(--text-lg);
  color: var(--text-secondary);
  pointer-events: none;
}
.hero-card:hover .hero-edit-hint {
  opacity: 0.6;
}

/* Hero Content */
.hero-action-text {
  font-family: var(--font-body);
  font-size: 1.65rem;
  font-weight: 600;
  color: var(--text);
  line-height: 1.3;
  margin-bottom: 14px;
  letter-spacing: -0.01em;
}
.hero-meta-row {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  margin-bottom: 10px;
}
.confidence-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  border-radius: 999px;
  font-size: var(--text-sm);
  font-weight: 700;
  white-space: nowrap;
}
.confidence-pill.high {
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  color: var(--primary);
  border: 1px solid color-mix(in srgb, var(--primary) 30%, transparent);
}
.confidence-pill.medium {
  background: rgba(255, 184, 0, 0.12);
  color: var(--amber);
  border: 1px solid rgba(255, 184, 0, 0.3);
}
.confidence-pill.low {
  background: rgba(255, 51, 102, 0.12);
  color: var(--red);
  border: 1px solid rgba(255, 51, 102, 0.3);
}
.timing-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: var(--dim);
  font-size: var(--text-sm);
  font-weight: 500;
}
.timing-badge.urgent {
  color: var(--red);
}
.timing-badge.soon {
  color: var(--amber);
}
.hero-context-anchor {
  font-size: var(--text-md);
  color: var(--dim);
  font-style: italic;
  line-height: 1.4;
  margin-bottom: 14px;
}
.value-artifact-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 14px;
  border-radius: var(--radius);
  background: rgba(124, 58, 237, 0.08);
  border-inline-start: 3px solid var(--primary);
  font-size: var(--text-base);
  color: #c4b5fd;
  line-height: 1.4;
  margin-bottom: 8px;
  max-width: 100%;
}
.value-artifact-badge .va-icon {
  flex-shrink: 0;
}
.value-artifact-badge .va-text {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Empty state */
.ac-empty {
  text-align: center;
  padding: 60px 24px;
  color: var(--dim);
}
.ac-empty-icon {
  font-size: 3rem;
  margin-bottom: 14px;
}
.ac-empty-title {
  font-size: var(--text-lg);
  font-weight: 700;
  color: var(--text-secondary);
  margin-bottom: 6px;
}
.ac-empty-desc {
  font-size: var(--text-base);
}

/* Bottom Action Bar */
.action-bar {
  position: fixed;
  bottom: 0;
  left: var(--sidebar-width);
  right: var(--status-rail-width);
  height: 60px;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 0 28px;
  background: var(--surface);
  border-top: 1px solid var(--border);
  backdrop-filter: blur(12px);
  z-index: 60;
  transition: right 0.25s ease;
}
.action-bar-primary {
  padding: 10px 28px;
  border: none;
  border-radius: 10px;
  background: var(--primary);
  color: #000;
  font-family: var(--font-body);
  font-size: var(--text-md);
  font-weight: 700;
  cursor: pointer;
  transition:
    transform 0.15s ease,
    box-shadow 0.2s ease;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}
.action-bar-primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 6px 20px var(--primary-glow);
}
.action-bar-primary:active {
  transform: translateY(0);
}
.action-bar-secondary {
  background: none;
  border: none;
  color: var(--primary);
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 600;
  cursor: pointer;
  padding: 8px 4px;
  transition: opacity 0.15s ease;
  white-space: nowrap;
}
.action-bar-secondary:hover {
  opacity: 0.8;
  text-decoration: underline;
}
.action-bar-tertiary {
  background: none;
  border: 1px solid transparent;
  color: var(--dim);
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 500;
  cursor: pointer;
  padding: 8px 14px;
  border-radius: var(--radius);
  transition:
    color 0.15s ease,
    border-color 0.15s ease;
  white-space: nowrap;
}
.action-bar-tertiary:hover {
  color: var(--text-secondary);
  border-color: var(--border);
}
.action-bar-spacer {
  flex: 1;
}

/* Workflow Footer */
.workflow-footer {
  position: fixed;
  bottom: 60px;
  left: var(--sidebar-width);
  right: var(--status-rail-width);
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 28px;
  background: var(--surface-2);
  border-top: 1px solid var(--border);
  z-index: 58;
}
.workflow-stage-label {
  font-size: var(--text-2xs);
  color: var(--dim);
  cursor: pointer;
  transition: color 0.15s;
}
.workflow-stage-label:hover {
  color: var(--text-secondary);
}
.workflow-sync-dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--primary);
  animation: sync-pulse 2s infinite;
}
.workflow-sync-dot.synced {
  background: var(--primary);
  animation: none;
  opacity: 0.4;
}

/* Secondary Info Panel */
.ac-secondary-panel {
  width: 0;
  overflow: hidden;
  background: var(--surface-2);
  border-inline-start: 1px solid transparent;
  transition:
    width 0.25s ease,
    border-color 0.25s ease;
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  position: relative;
  min-height: calc(100vh - 56px - 60px - 24px);
}
.ac-secondary-panel.open {
  width: 300px;
  border-inline-start-color: var(--border);
}
.ac-panel-toggle {
  position: absolute;
  left: -6px;
  top: 50%;
  transform: translateY(-50%);
  width: 18px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  border: 1px solid var(--border);
  border-radius: 0 5px 5px 0;
  background: var(--surface);
  color: var(--dim);
  font-size: var(--text-2xs);
  z-index: 5;
  transition:
    color 0.15s ease,
    background 0.15s ease;
}
.ac-panel-toggle:hover {
  color: var(--text);
  background: var(--surface-2);
}
.ac-panel-toggle .chevron-icon {
  display: inline-block;
  transition: transform 0.25s ease;
}
.ac-panel-toggle.open .chevron-icon {
  transform: rotate(180deg);
}
.ac-panel-inner {
  padding: 20px 14px;
  overflow-y: auto;
  flex: 1;
  opacity: 0;
  transition: opacity 0.15s ease 0.05s;
}
.ac-secondary-panel.open .ac-panel-inner {
  opacity: 1;
}
.ac-panel-section {
  margin-bottom: 20px;
}
.ac-panel-section:last-child {
  margin-bottom: 0;
}
.ac-panel-label {
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--dim);
  font-weight: 700;
  margin-bottom: 8px;
}
.ac-sparkline-wrap {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  height: 36px;
  margin-bottom: 4px;
}
.ac-sparkline-bar {
  flex: 1;
  border-radius: 2px 2px 0 0;
  background: var(--primary);
  opacity: 0.45;
  min-width: 4px;
  transition: height 0.35s ease;
}
.ac-sparkline-bar.current {
  opacity: 1;
}

/* Touchpoints */
.ac-touchpoint-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 0;
  border-bottom: 1px solid rgba(0, 0, 0, 0.04);
  font-size: 0.76rem;
  color: var(--text-secondary);
  cursor: default;
  position: relative;
}
.ac-touchpoint-item:last-child {
  border-bottom: none;
}
.ac-touchpoint-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--dim);
  flex-shrink: 0;
}
.ac-touchpoint-dot.call {
  background: var(--blue);
}
.ac-touchpoint-dot.message {
  background: var(--primary);
}
.ac-touchpoint-dot.email {
  background: var(--primary);
}
.ac-touchpoint-time {
  margin-inline-start: auto;
  font-size: var(--text-2xs);
  color: var(--dim);
  white-space: nowrap;
}
.ac-touchpoint-tooltip {
  display: none;
  position: absolute;
  bottom: calc(100% + 6px);
  left: 0;
  right: 0;
  background: var(--surface-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 8px 10px;
  font-size: var(--text-xs);
  color: var(--text);
  z-index: 10;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
  word-break: break-word;
}
.ac-touchpoint-item:hover .ac-touchpoint-tooltip {
  display: block;
}

/* Value Artifact (panel) */
.ac-value-artifact {
  padding: 10px 12px;
  background: rgba(124, 58, 237, 0.06);
  border-inline-start: 3px solid var(--primary);
  border-radius: 0 6px 6px 0;
  font-size: var(--text-sm);
  color: #c4b5fd;
  line-height: 1.5;
}

/* Snooze */
.ac-snooze-row {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.ac-snooze-btn {
  padding: 5px 12px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text-secondary);
  font-size: var(--text-xs);
  font-weight: 500;
  cursor: pointer;
  transition:
    background 0.15s,
    border-color 0.15s;
}
.ac-snooze-btn:hover {
  background: var(--primary-glow);
  border-color: color-mix(in srgb, var(--primary) 30%, transparent);
  color: var(--primary);
}
.ac-pin-btn {
  background: none;
  border: none;
  color: var(--dim);
  cursor: pointer;
  font-size: 0.62rem;
  padding: 3px 0;
  margin-top: 4px;
  transition: color 0.15s;
}
.ac-pin-btn:hover {
  color: var(--text-secondary);
}
.ac-pin-btn.pinned {
  color: var(--primary);
}

/* Later / Snooze Column */
.later-column {
  width: 0;
  overflow: hidden;
  background: var(--surface-2);
  border-inline-start: 1px solid transparent;
  transition:
    width 0.25s ease,
    border-color 0.25s ease;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  min-height: calc(100vh - 56px - 60px - 24px);
}
.later-column.open {
  width: 260px;
  border-inline-start-color: var(--border);
}
.later-column-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 14px 8px;
  font-size: var(--text-sm);
  font-weight: 700;
  color: var(--text);
  border-bottom: 1px solid var(--border);
}
.later-column-list {
  flex: 1;
  overflow-y: auto;
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.later-item {
  padding: 10px 12px;
  background: rgba(0, 0, 0, 0.02);
  border: 1px solid rgba(0, 0, 0, 0.06);
  border-radius: var(--radius);
  font-size: var(--text-xs);
  color: var(--text-secondary);
  transition:
    border-color 0.15s,
    background 0.15s;
}
.later-item:hover {
  border-color: var(--border);
  background: rgba(0, 0, 0, 0.04);
}
.later-item-due {
  font-size: var(--text-2xs);
  color: var(--dim);
  margin-bottom: 4px;
}
.later-item-title {
  font-weight: 600;
  color: var(--text);
  margin-bottom: 6px;
}
.later-item-actions {
  display: flex;
  gap: 6px;
}
.later-item-actions .btn {
  padding: 3px 10px;
  font-size: var(--text-2xs);
}
.later-toggle-btn {
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 18px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  border: 1px solid var(--border);
  border-radius: 5px 0 0 5px;
  background: var(--surface);
  color: var(--dim);
  font-size: var(--text-2xs);
  z-index: 5;
  transition:
    color 0.15s,
    background 0.15s;
}
.later-toggle-btn:hover {
  color: var(--amber);
  background: var(--surface-2);
}

/* Mini-Composer Modal */
.composer-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.75);
  backdrop-filter: blur(4px);
  z-index: 300;
  display: none;
  align-items: center;
  justify-content: center;
}
.composer-modal-overlay.active {
  display: flex;
}
.composer-modal {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 24px 28px 20px;
  max-width: 500px;
  width: 90%;
  animation: modal-in 0.2s ease;
}
.composer-modal-title {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 700;
  margin-bottom: 2px;
}
.composer-modal-contact {
  font-size: var(--text-sm);
  color: var(--dim);
  margin-bottom: 14px;
}
.composer-textarea {
  width: 100%;
  min-height: 100px;
  max-height: 220px;
  padding: 12px 14px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  color: var(--text);
  font-family: var(--font-body);
  font-size: 0.9rem;
  line-height: 1.5;
  outline: none;
  resize: vertical;
  transition: border-color 0.15s;
}
.composer-textarea:focus {
  border-color: var(--primary);
}
.composer-meta {
  margin-top: 8px;
  font-size: var(--text-xs);
  color: var(--dim);
  display: flex;
  align-items: center;
  gap: 6px;
}
.composer-meta.dry-run {
  color: var(--amber);
}
.composer-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-top: 14px;
}

/* Workflow Overview Modal */
.workflow-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.7);
  backdrop-filter: blur(4px);
  z-index: 300;
  display: none;
  align-items: center;
  justify-content: center;
}
.workflow-overlay.active {
  display: flex;
}
.workflow-modal {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 24px 28px;
  max-width: 440px;
  width: 90%;
  animation: modal-in 0.2s ease;
}
.workflow-modal-title {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 700;
  margin-bottom: 16px;
}
.workflow-step {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid rgba(0, 0, 0, 0.04);
}
.workflow-step:last-child {
  border-bottom: none;
}
.workflow-step-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
  background: var(--dim);
}
.workflow-step-dot.done {
  background: var(--primary);
}
.workflow-step-dot.active {
  background: var(--primary);
  box-shadow: 0 0 8px var(--primary-glow);
}
.workflow-step-label {
  font-size: var(--text-base);
  color: var(--dim);
}
.workflow-step-label.done {
  color: var(--primary);
  text-decoration: line-through;
}
.workflow-step-label.active {
  color: var(--text);
  font-weight: 600;
}
.workflow-step-badge {
  margin-inline-start: auto;
  font-size: var(--text-2xs);
  padding: 2px 8px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--primary) 10%, transparent);
  color: var(--primary);
}

/* Toast */
.ac-toast {
  position: fixed;
  bottom: 80px;
  left: 50%;
  transform: translateX(-50%);
  padding: 10px 20px;
  border-radius: 999px;
  background: var(--surface-3);
  border: 1px solid var(--border);
  color: var(--text);
  font-size: var(--text-sm);
  font-weight: 600;
  z-index: 500;
  animation:
    toast-in 0.25s ease,
    toast-out 0.3s ease 2.5s forwards;
  pointer-events: none;
}
.ac-toast.success {
  border-color: color-mix(in srgb, var(--primary) 40%, transparent);
  color: var(--primary);
}
.ac-toast.info {
  border-color: rgba(59, 130, 246, 0.4);
  color: #8ec5ff;
}
@keyframes toast-in {
  from {
    opacity: 0;
    transform: translateX(-50%) translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
  }
}
@keyframes toast-out {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}

/* Card transition animations */
.hero-card.slide-out-up {
  animation: slide-out-up 0.18s ease forwards;
}
@keyframes slide-out-up {
  to {
    opacity: 0;
    transform: translateY(-24px);
  }
}
.hero-card.slide-in-up {
  animation: slide-in-up 0.22s ease forwards;
}
@keyframes slide-in-up {
  from {
    opacity: 0;
    transform: translateY(24px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
.hero-card.slide-out-right {
  animation: slide-out-right 0.2s ease forwards;
}
@keyframes slide-out-right {
  to {
    opacity: 0;
    transform: translateX(60px);
  }
}

/* ——— Conversational Team Inbox (two-pane) ——— */
.inbox2 {
  display: flex;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  height: calc(100vh - 56px - 48px);
  background: var(--surface);
}
/* On mobile browsers 100vh is the address-bar-hidden height, so the composer lands below the
   fold whenever the bar is showing. dvh tracks the actually-visible viewport. */
@supports (height: 100dvh) {
  .inbox2 {
    height: calc(100dvh - 56px - 48px);
  }
}
.inbox2-list {
  width: 320px;
  border-inline-end: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  min-width: 0;
}
/* The attention-queue row (Priority) needs its own flex row now that it's not nested inside a
   shared filter wrapper — .inbox2-filters elsewhere relies on display:contents and a parent that
   already provides the row. */
#inbox-queues {
  display: flex;
  flex-direction: column;
  padding: 0 0 4px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--border);
}
#inbox-queues:empty {
  display: none;
}
/* The queues live in the list's ⋯ menu now; the button carries one dot, in the colour of the most
   urgent queue with something in it. Menu items carry their own colour dot. */
.inbox-more-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-inline-start: 4px;
  border-radius: 50%;
  vertical-align: middle;
}
.inbox-more-dot[hidden] {
  display: none;
}
#inbox-queues .inbox-queue-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-inline-end: 8px;
  border-radius: 50%;
}
/* Search + the Mine toggle + the filter-overflow button, one row. Everything rarer than "is this
   mine" lives behind the overflow button instead of its own permanent row. The row itself carries
   the padding/border that .inbox2-search used to own outright — .inbox2-search now only ever
   appears nested here, so it stays bare (no self-padding to fight the row's). */
.inbox2-toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-bottom: 1px solid var(--border);
}
.inbox2-search {
  flex: 1;
  min-width: 0;
}
.inbox2-search input {
  width: 100%;
}
/* Status/Line/Entity render inside the filter-overflow dropdown as a vertical menu, reusing its
   existing item styling rather than the horizontal pill-row layout those chips use elsewhere. */
.inbox-more-dropdown .inbox2-lines,
.inbox-more-dropdown .inbox2-filters {
  display: flex;
  flex-direction: column;
}
.inbox-more-dropdown .inbox2-line-tab,
.inbox-more-dropdown .inbox2-filter-chip {
  display: block;
  width: 100%;
  text-align: start;
  margin: 0;
  border-radius: 0;
  border: none;
  background: none;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text);
  padding: 8px 14px;
  cursor: pointer;
}
.inbox-more-dropdown .inbox2-line-tab:hover,
.inbox-more-dropdown .inbox2-filter-chip:hover {
  background: var(--surface-2);
}
.inbox-more-dropdown .inbox2-line-tab.active,
.inbox-more-dropdown .inbox2-filter-chip.active {
  color: var(--primary);
  font-weight: 700;
}
.inbox2-convos {
  flex: 1;
  overflow-y: auto;
}
.inbox-convo {
  display: block;
  width: 100%;
  text-align: start;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--border);
  padding: 10px 12px;
  cursor: pointer;
}
.inbox-convo:hover {
  background: var(--surface-2);
}
.inbox-convo.active {
  background: var(--primary-glow);
}
.inbox-convo-top {
  display: flex;
  justify-content: space-between;
  gap: 8px;
}
.inbox-convo-name {
  font-weight: 600;
  font-size: var(--text-base);
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.inbox-convo-time {
  font-size: var(--text-xs);
  color: var(--dim);
  white-space: nowrap;
}
.inbox-convo-preview {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  align-items: center;
  margin-top: 2px;
}
.inbox-convo-preview span:first-child {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.inbox-convo-unread {
  background: var(--primary);
  color: var(--on-primary);
  border-radius: 999px;
  font-size: var(--text-2xs);
  min-width: 18px;
  height: 18px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 5px;
}
.inbox-convo-unnamed {
  color: var(--amber);
  font-size: 0.6rem;
  vertical-align: middle;
}
/* Identity sub-line: the contact's number under a named row (name AND number, always both
   when known), plus the business line the thread lives on when there's more than one. */
.inbox-convo-sub {
  display: flex;
  align-items: center;
  gap: 5px;
  margin-top: 1px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.inbox-convo-num {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  color: var(--dim);
}
.inbox-convo-dot {
  color: var(--dim);
  font-size: var(--text-2xs);
}
.inbox-convo-linechip {
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--primary);
  opacity: 0.85;
}
.inbox-convo-entity {
  font-size: 0.62rem;
  font-weight: 600;
  padding: 1px 5px;
  border-radius: 3px;
  background: var(--ok-bg);
  color: var(--ok-fg);
}
/* Assignee initials — context on a row, not a filter. Skipped in Inbound, which already
   sub-groups by assignee (see groupOf() in inbox.js). */
.inbox-convo-assignee {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--dim);
  font-size: 0.6rem;
  font-weight: 700;
}
/* Inbound's "waiting 6h+" signal, once assignee grouping has taken the section header's place. */
.inbox-convo-aging {
  font-size: 0.9em;
}
/* "Klaros spoke last" — an automated send can never bump a thread (the list ranks by inbound
   recency, by design), so this makes the operator's own automation legible without hijacking the
   "who needs me" order it exists to answer. */
.inbox-convo-system {
  margin-top: 3px;
  font-size: var(--text-2xs);
  color: var(--primary);
  opacity: 0.85;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* The tappable options we offered. Meta renders these on the contact's phone and keeps no copy for
   us, so showing them is the only way the operator can see what was actually asked on their behalf
   — and what a one-word reply was answering. Rendered flat (not as buttons) because they are a
   record of what the CONTACT can tap, not a control for the operator. */
.msg-choices {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-top: 6px;
}
.msg-choice {
  font-size: var(--text-2xs);
  padding: 3px 9px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: rgba(255, 255, 255, 0.04);
  color: var(--text-secondary);
}
.inbox2-thread {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.inbox2-empty {
  margin: auto;
  text-align: center;
  color: var(--dim);
  padding: 24px;
}
.inbox2-thread-inner {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.inbox2-thread-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
}
/* Back affordance exists only in the single-pane (mobile) layout; desktop shows both panes at
   once and has no use for it. */
.inbox2-thread-back {
  display: none;
}
/* flex:1 + min-width:0 — identity text is what should give way when the row is tight (three panes
   can genuinely be narrow at once), never the action buttons or indicator pills beside it. */
.inbox2-thread-title {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex: 1;
  min-width: 0;
}
.inbox2-thread-name {
  font-weight: 700;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* The contact's number beside their name — identity is name AND number, whenever both exist. */
.inbox2-thread-num {
  font-family: var(--font-mono);
  font-size: 0.76rem;
  color: var(--dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 140px;
}
.inbox2-thread-num:empty {
  display: none;
}
/* Real-time presence: shows "● Agent X is viewing" or "Agent X is typing…" */
.inbox2-thread-presence {
  font-size: var(--text-xs);
  color: var(--dim);
  white-space: nowrap;
  transition: opacity 0.2s;
}
.inbox2-thread-presence:empty {
  display: none;
}
.inbox2-thread-presence .presence-dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--green);
  margin-inline-end: 4px;
  vertical-align: middle;
}
.inbox2-thread-presence .presence-typing {
  color: var(--primary);
  font-style: italic;
}
.inbox2-thread-head-right {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: none;
  justify-content: flex-end;
}
/* Compact indicators (assignee/reply-line/window state): icon or a word or two, full context in
   the tooltip. Replaces three sentence-length text spans that used to fight the action buttons for
   the same row — "Assigned: Priya Sharma" / "Replying via +91 98765…" / "24h window closed — reply
   with an approved template" — which is exactly the "too much of a stretch" the header used to be. */
.inbox2-indicators {
  display: flex;
  align-items: center;
  gap: 6px;
}
.inbox2-indicator {
  font-size: var(--text-2xs);
  font-weight: 700;
  border: 1px solid var(--border-light);
  border-radius: 999px;
  padding: 2px 8px;
  white-space: nowrap;
}
.inbox2-indicator:empty {
  display: none;
}
button.inbox2-indicator {
  cursor: pointer;
  background: none;
  color: inherit;
}
button.inbox2-indicator:hover {
  background: var(--surface-2);
}
.inbox2-assignee {
  color: var(--dim);
  border-color: currentColor;
}
.inbox2-assignee.is-assigned {
  color: var(--primary);
}
.inbox2-reply-line {
  color: var(--dim);
}
.win-open {
  color: var(--primary);
}
.win-closed {
  color: var(--amber);
}
.inbox-more-wrap {
  position: relative;
}
.inbox-more-dropdown {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  min-width: 160px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
  padding: 4px 0;
  z-index: 50;
}
.inbox-more-item {
  display: block;
  width: 100%;
  text-align: start;
  font-size: var(--text-sm);
  padding: 8px 14px;
  color: var(--text);
  background: none;
  border: none;
  cursor: pointer;
}
.inbox-more-item:hover {
  background: var(--surface-2);
}

/* One flowing strip above the thread — labels, linked entity, and the "who is this?" context
   (known/new, consent, shared groups, attribution) all as pills in a single row. The three source
   containers (.inbox2-thread-labels ×2, .inbox2-context) go display:contents so their chips join
   this row directly; the wrapper alone carries the border/background/padding. */
.inbox2-meta-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  padding: 6px 16px;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}
/* Hidden whenever every source is empty — :has() checks each DIRECT child (the three containers),
   not their chips, so this still works with them collapsed to display:contents. */
.inbox2-meta-strip:not(:has(> *:not(:empty))) {
  display: none;
}
.inbox2-context {
  display: contents;
}
.ctx-chip {
  font-size: var(--text-2xs);
  font-weight: 600;
  color: var(--dim);
  border: 1px solid var(--border-light);
  border-radius: 999px;
  padding: 1px 8px;
  white-space: nowrap;
}
.ctx-chip.ctx-known,
.ctx-chip.ctx-ok {
  color: var(--primary);
  border-color: currentColor;
}
.ctx-chip.ctx-new {
  color: var(--blue);
  border-color: currentColor;
}
.ctx-chip.ctx-warn {
  color: var(--amber);
  border-color: currentColor;
}
.ctx-chip.ctx-bad {
  color: var(--red);
  border-color: currentColor;
}
.ctx-chip.ctx-attr {
  color: var(--primary);
  border-color: currentColor;
}
.ctx-chip.ctx-qual {
  color: var(--green);
  border-color: currentColor;
  background: color-mix(in srgb, currentColor 8%, transparent);
}
/* An open support case, shown wherever its conversation already lands by turn/category — a
   flavor of the row, not a rival list (see caseBadgeHtml() in inbox.js). */
.ctx-chip.ctx-case {
  color: var(--accent);
  border-color: currentColor;
  text-transform: capitalize;
}
.ctx-chip.ctx-ai {
  color: #818cf8;
  border-color: currentColor;
}
.ctx-chip.ctx-ai[data-ai-draft] {
  cursor: pointer;
}
.ctx-chip.ctx-ai[data-ai-draft]:hover {
  background: color-mix(in srgb, currentColor 10%, transparent);
}
.ctx-chip.ctx-invite {
  color: var(--amber);
  border-color: currentColor;
  cursor: pointer;
  font-weight: 700;
}
.ctx-chip.ctx-invite:hover {
  background: color-mix(in srgb, currentColor 10%, transparent);
}

/* Line switcher (multi-number): All + a tab per connected number, with per-line unread badges. */
.inbox2-lines {
  display: contents;
}
.inbox2-line-tab {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--dim);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 4px 10px;
  cursor: pointer;
}
.inbox2-line-tab:hover {
  color: var(--text);
}
.inbox2-line-tab.active {
  color: var(--on-primary);
  background: var(--primary);
  border-color: var(--primary);
}
.inbox2-line-tab .tab-badge {
  background: rgba(0, 0, 0, 0.18);
  border-radius: 999px;
  font-size: var(--text-2xs);
  min-width: 16px;
  height: 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 4px;
}
.inbox2-line-tab:not(.active) .tab-badge {
  background: var(--primary);
  color: var(--on-primary);
}

/* Category tabs (Interactive · Inbound · Outbound) — the top-level partition of the list.
   Segmented control, one segment per category; Interactive badges its "waiting on you" count. */
.inbox2-cats {
  display: flex;
  gap: 0;
  padding: 10px 10px 0;
}
.inbox2-cat-tab {
  flex: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  font-size: 0.76rem;
  font-weight: 600;
  color: var(--dim);
  background: var(--surface-2);
  border: 1px solid var(--border);
  padding: 6px 4px;
  cursor: pointer;
}
.inbox2-cat-tab:first-child {
  border-radius: var(--radius) 0 0 var(--radius);
}
.inbox2-cat-tab:last-child {
  border-radius: 0 var(--radius) var(--radius) 0;
}
.inbox2-cat-tab + .inbox2-cat-tab {
  border-inline-start: 0;
}
.inbox2-cat-tab:hover {
  color: var(--text);
}
.inbox2-cat-tab.active {
  color: var(--on-primary);
  background: var(--primary);
  border-color: var(--primary);
}
.inbox2-cat-tab .tab-badge {
  background: rgba(0, 0, 0, 0.18);
  border-radius: 999px;
  font-size: 0.64rem;
  min-width: 16px;
  height: 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 4px;
}
.inbox2-cat-tab:not(.active) .tab-badge {
  background: var(--amber);
  color: var(--on-primary);
}

/* Sticky sub-section headers inside the endless-scrolling list (Your turn · Their turn ·
   Aging · per-broadcast groups), plus the sentinel row that triggers the next page. */
.inbox2-section-head {
  position: sticky;
  top: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-size: var(--text-2xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--dim);
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
  padding: 5px 12px;
}
.inbox2-section-count {
  font-weight: 700;
  color: var(--text-secondary);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 0.62rem;
  min-width: 18px;
  height: 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 5px;
}
.inbox2-section-head.is-toggle {
  cursor: pointer;
  user-select: none;
}
.inbox2-section-head.is-toggle:hover {
  background: var(--surface-3);
}
.inbox2-section-title {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.inbox2-section-chev {
  font-size: 0.6rem;
  color: var(--dim);
  width: 10px;
}
.inbox2-section-badges {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.inbox2-section-unread {
  font-weight: 700;
  color: var(--on-primary);
  background: var(--primary);
  border-radius: 999px;
  font-size: 0.62rem;
  min-width: 18px;
  height: 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 5px;
}
.inbox-convo-window {
  font-size: 0.64rem;
  font-weight: 700;
  color: var(--primary);
  border: 1px solid currentColor;
  border-radius: 999px;
  padding: 0 6px;
  margin-inline-end: 6px;
}
.inbox-convo-window.is-closing {
  color: var(--amber);
}
.inbox2-scroll-sentinel {
  padding: 10px 12px;
}
.inbox2-scroll-sentinel .skel-block {
  height: 34px;
}

/* ——— Contact detail panel (third pane) ——— */
.inbox2-detail {
  width: 280px;
  min-width: 280px;
  border-inline-start: 1px solid var(--border);
  display: none;
  flex-direction: column;
  overflow: hidden;
  background: var(--surface);
}
.inbox2.show-detail .inbox2-detail {
  display: flex;
}
.detail-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
  flex: none;
}
.detail-title {
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--dim);
}
.detail-close {
  background: none;
  border: none;
  color: var(--dim);
  cursor: pointer;
  font-size: 16px;
  padding: 2px 6px;
  line-height: 1;
}
.detail-close:hover {
  color: var(--text);
}
.detail-body {
  padding: 0;
  overflow-y: auto;
  flex: 1;
}
.detail-empty {
  padding: 32px 14px;
  text-align: center;
  color: var(--dim);
  font-size: var(--text-sm);
}

/* Detail panel: avatar + identity header */
.detail-identity {
  text-align: center;
  padding: 20px 14px 14px;
  border-bottom: 1px solid var(--border);
}
.detail-avatar {
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: var(--primary);
  color: var(--on-primary);
  font-weight: 700;
  font-size: var(--text-lg);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 8px;
}
.detail-name {
  font-weight: 700;
  font-size: var(--text-md);
  color: var(--text);
  word-break: break-word;
}
.detail-phone {
  font-family: var(--font-mono);
  font-size: 0.76rem;
  color: var(--dim);
  margin-top: 2px;
}
.detail-badges {
  display: flex;
  justify-content: center;
  gap: 6px;
  margin-top: 8px;
  flex-wrap: wrap;
}
.detail-badges .ctx-chip {
  font-size: var(--text-2xs);
}

/* Detail panel: sections */
.detail-section {
  border-bottom: 1px solid var(--border);
  padding: 12px 14px;
}
.detail-section:last-child {
  border-bottom: 0;
}
.detail-label {
  font-size: var(--text-2xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--dim);
  margin-bottom: 8px;
}

/* Detail panel: tags */
.detail-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.detail-tag {
  font-size: var(--text-2xs);
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--text-secondary);
  border: 1px solid var(--border);
}
.detail-tag-add {
  font-size: var(--text-2xs);
  padding: 2px 8px;
  border-radius: 999px;
  background: none;
  border: 1px dashed var(--border);
  color: var(--dim);
  cursor: pointer;
}
.detail-tag-add:hover {
  border-color: var(--primary);
  color: var(--primary);
}

/* Detail panel: key-value fields */
.detail-fields {
  display: grid;
  gap: 6px;
}
.detail-field {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
}
.detail-fk {
  font-size: var(--text-xs);
  color: var(--dim);
  white-space: nowrap;
}
.detail-fv {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--text);
  text-align: end;
  word-break: break-word;
}
.detail-fv select {
  font-size: var(--text-xs);
  padding: 1px 4px;
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  background: var(--surface);
  color: var(--text);
}
.detail-ltv {
  color: var(--primary-dark);
}
.detail-ltv-warn {
  color: var(--amber);
}
.detail-orders {
  display: grid;
  gap: 5px;
  margin-top: 8px;
}
.detail-order {
  display: grid;
  grid-template-columns: 1fr auto auto;
  gap: 8px;
  align-items: center;
  font-size: var(--text-xs);
  padding: 5px 7px;
  background: var(--surface-2);
  border-radius: var(--radius-sm);
}
.detail-order-status {
  font-weight: 600;
  color: var(--text-secondary);
}
.detail-order-paid,
.detail-order-fulfilled {
  color: var(--primary-dark);
}
.detail-order-payment_requested {
  color: var(--amber);
}
.detail-order-expired {
  color: var(--dim);
}
.detail-order-amt {
  font-weight: 700;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.detail-order-when {
  color: var(--dim);
}

/* Detail panel: the events this person is part of (EventsHub) */
.detail-events {
  display: grid;
  gap: 5px;
}
.detail-event {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 8px;
  align-items: center;
  width: 100%;
  padding: 6px 8px;
  border: 0;
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--text);
  font: inherit;
  font-size: var(--text-xs);
  text-align: left;
}
button.detail-event {
  cursor: pointer;
}
button.detail-event:hover,
button.detail-event:focus-visible {
  background: var(--surface-3);
  outline: 1px solid var(--border);
}
.detail-event-main {
  display: grid;
  min-width: 0;
}
.detail-event-name {
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.detail-event-sub {
  color: var(--dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.detail-event-standing {
  font-weight: 600;
  color: var(--text-secondary);
  white-space: nowrap;
}
.detail-event-standing[data-standing='came'],
.detail-event-standing[data-standing='registered'] {
  color: var(--primary-dark);
}
.detail-event-standing[data-standing='waiting'] {
  color: var(--amber);
}
.detail-event-standing[data-standing='declined'],
.detail-event-standing[data-standing='missed'] {
  color: var(--dim);
}

/* Detail panel: notes */
.detail-notes-list {
  display: grid;
  gap: 6px;
  margin-bottom: 8px;
  max-height: 180px;
  overflow-y: auto;
}
.detail-note {
  background: var(--surface-2);
  border-radius: var(--radius-sm);
  padding: 6px 8px;
}
.detail-note-text {
  font-size: 0.76rem;
  color: var(--text);
  word-break: break-word;
}
.detail-note-meta {
  font-size: 0.64rem;
  color: var(--dim);
  margin-top: 2px;
}
.detail-note-form {
  display: flex;
  gap: 4px;
}
.detail-note-form textarea {
  flex: 1;
  font-size: var(--text-xs);
  padding: 4px 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  background: var(--surface);
  color: var(--text);
  resize: none;
  min-height: 28px;
  font-family: inherit;
}
.detail-note-form button {
  flex: none;
  font-size: var(--text-2xs);
}
.btn-link-remove {
  background: none;
  border: none;
  color: var(--dim);
  cursor: pointer;
  font-size: 1rem;
  line-height: 1;
  padding: 0 2px;
  opacity: 0.6;
}
.btn-link-remove:hover {
  opacity: 1;
  color: var(--danger);
}

/* Detail panel: toggle button in thread header */
#inbox-detail-toggle {
  font-size: var(--text-sm);
  padding: 2px 8px;
  min-width: 28px;
}
#inbox-detail-toggle.active {
  background: var(--primary);
  color: var(--on-primary);
  border-color: var(--primary);
}

/* Responsive: hide detail panel on narrow screens */
@media (max-width: 900px) {
  .inbox2-detail {
    position: absolute;
    right: 0;
    top: 0;
    bottom: 0;
    z-index: 20;
    box-shadow: -4px 0 16px rgba(0, 0, 0, 0.12);
  }
  .inbox2 {
    position: relative;
  }
}
/* Below 760px a 280px panel would cover 82% of the screen while reading as a partial
   overlay, with its own close button underneath it. Commit: it becomes a full-screen
   sheet stacked above the thread, dismissed by its own (44px) close button. */
@media (max-width: 760px) {
  .inbox2-detail {
    width: auto;
    min-width: 0;
    inset: 0;
    z-index: 30;
    border-inline-start: 0;
  }
  .detail-head {
    padding: 8px 10px 8px 14px;
  }
  .detail-close {
    min-width: 44px;
    min-height: 44px;
    font-size: 22px;
  }
}

/* Outbound broadcast accordion: a collapsible block per campaign, so many broadcasts stay
   scannable. Header = name + recency; stats line = send outcomes with the Retry-failed verb
   (amber = action). */
.inbox2-group-head {
  position: sticky;
  top: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  text-align: start;
  background: var(--surface-2);
  border: 0;
  border-bottom: 1px solid var(--border);
  padding: 7px 12px;
  cursor: pointer;
  font-size: var(--text-sm);
  font-weight: 700;
  color: var(--text);
}
.inbox2-group-head:hover {
  background: var(--surface-3, var(--surface-2));
}
.inbox2-group-chev {
  color: var(--dim);
  font-size: var(--text-2xs);
  flex: none;
}
.inbox2-group-name {
  flex: 1;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.inbox2-group-time {
  font-size: var(--text-2xs);
  color: var(--dim);
  font-weight: 600;
  flex: none;
}
.inbox2-group-stats {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 4px 12px 6px;
  font-size: var(--text-2xs);
  color: var(--text-secondary);
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
}
.inbox2-group-stats > span {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.inbox2-group-failed {
  color: var(--red);
  font-weight: 700;
}
.inbox2-group-why {
  color: var(--amber);
  font-weight: 600;
}
.inbox2-group-retry {
  font-size: var(--text-2xs);
  font-weight: 700;
  color: var(--amber);
  background: none;
  border: 1px solid currentColor;
  border-radius: var(--radius-sm);
  padding: 2px 8px;
  cursor: pointer;
  flex: none;
}
.inbox2-group-retry:hover {
  background: color-mix(in srgb, currentColor 10%, transparent);
}
.inbox2-group-retry:disabled {
  opacity: 0.5;
  cursor: default;
}
.inbox2-group-retry-force {
  color: var(--red);
}
.inbox2-group-recovered {
  color: var(--primary);
  font-weight: 600;
}
.ctx-chip.ctx-linked {
  color: var(--accent);
  border-color: currentColor;
  cursor: pointer;
}
.ctx-chip.ctx-linked:hover {
  background: color-mix(in srgb, currentColor 8%, transparent);
}

/* Keyboard cursor on the conversation list (↑/↓, Enter opens). */
.inbox-convo.kbd-focus {
  outline: 2px solid var(--primary);
  outline-offset: -2px;
}

/* Anchored popover — the in-app replacement for window.prompt (assign, rename). */
.inbox2-pop {
  position: absolute;
  z-index: 60;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.16);
  padding: 10px;
  min-width: 210px;
  max-width: 280px;
}
.inbox2-pop-title {
  font-size: var(--text-2xs);
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--dim);
  margin-bottom: 6px;
}
.inbox2-pop-item {
  display: block;
  width: 100%;
  text-align: start;
  font-size: var(--text-sm);
  color: var(--text);
  background: none;
  border: 0;
  border-radius: var(--radius-sm);
  padding: 6px 8px;
  cursor: pointer;
}
.inbox2-pop-item:hover {
  background: var(--surface-2);
}
.inbox2-pop-item.current {
  color: var(--primary);
  font-weight: 700;
}
.inbox2-pop-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-top: 8px;
}

/* Thread furniture: day separators, the unread divider, and history paging. */
.msg-day-sep {
  align-self: center;
  font-size: 0.64rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--dim);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 2px 10px;
  margin: 6px 0 2px;
}
.msg-unread-sep {
  align-self: stretch;
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--red);
  font-size: 0.64rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin: 4px 0;
}
.msg-unread-sep::before,
.msg-unread-sep::after {
  content: '';
  flex: 1;
  border-top: 1px solid color-mix(in srgb, var(--red) 40%, transparent);
}
.thread-load-earlier {
  align-self: center;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--primary);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 4px 12px;
  cursor: pointer;
  margin-bottom: 4px;
}
.thread-load-earlier:hover {
  background: var(--surface-2);
}

/* Per-message line badge (shown in the integrated view). The header's own reply-line/window
   indicators are styled with .inbox2-thread-head-right, above. */
.msg-line {
  display: inline-block;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--dim);
  opacity: 0.8;
  margin-bottom: 2px;
}
.inbox2-messages {
  flex: 1;
  overflow-y: auto;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: var(--bg);
}
.msg {
  max-width: 72%;
  padding: 8px 12px;
  border-radius: 12px;
  font-size: var(--text-base);
}
.msg.in {
  align-self: flex-start;
  background: var(--surface);
  border: 1px solid var(--border);
  border-bottom-left-radius: 3px;
}
.msg.out {
  align-self: flex-end;
  background: var(--primary-glow);
  border: 1px solid color-mix(in srgb, var(--primary) 30%, var(--border));
  border-bottom-right-radius: 3px;
}
.msg.failed.out {
  background: color-mix(in srgb, var(--red) 10%, var(--surface));
  border-color: color-mix(in srgb, var(--red) 35%, var(--border));
}
.msg-body {
  color: var(--text);
  white-space: pre-wrap;
  word-break: break-word;
}
/* A file deleted from Media: said quietly, so the gap in the thread explains itself. */
.msg-media-deleted {
  color: var(--dim);
  font-style: italic;
  font-size: var(--text-sm);
}
.msg-meta {
  font-size: var(--text-2xs);
  color: var(--dim);
  margin-top: 3px;
  text-align: end;
}
.msg-tick.read {
  color: var(--blue);
}
.msg-tick.failed {
  color: var(--red);
}
.msg-error {
  font-size: var(--text-2xs);
  color: var(--red);
  margin-top: 2px;
}
.inbox2-compose {
  display: flex;
  gap: 8px;
  padding: 12px;
  border-top: 1px solid var(--border);
  align-items: flex-end;
}
/* The composer is a writing surface, not a search box: start roomy (~3 lines) and grow
   with the draft up to 240px (auto-grow in inbox.js), so buttons/lists/multi-line replies
   are composed in full view. */
.inbox2-compose textarea {
  flex: 1;
  resize: none;
  max-height: 240px;
  min-height: 68px;
}

/* Inbox media bubbles */
.msg-media {
  max-width: 240px;
  max-height: 260px;
  border-radius: 10px;
  display: block;
  margin-bottom: 4px;
  cursor: pointer;
}
.msg-doc {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-base);
  font-weight: 600;
  color: var(--primary);
  text-decoration: none;
}
.msg-doc:hover {
  text-decoration: underline;
}
#inbox-plus-btn {
  padding: 6px 10px;
  font-size: 1.05rem;
  line-height: 1;
}

/* Agent (non-admin seat) view: hide admin/management nav so teammates get a clean inbox view. */
body.role-agent [data-agent-hide] {
  display: none !important;
}

/* ——— Card mode (rung two: owns one page, asked for nothing else) ———
   Same shape as the agent seat above: hide the surfaces a card owner has no account for, so the
   one thing they do own is not competing with forty tabs they cannot use. */
body.mode-card [data-agent-hide],
body.mode-card #dash-search,
body.mode-card .status-rail {
  display: none !important;
}

/* Hidden, not locked — unlike the nav.
   A padlock on a nav item advertises a capability worth upgrading for. A padlock on "+ Create Page"
   advertises the ability to own a SECOND card, which is not the product being sold and not
   something this person wants. Same for bulk creation and search: one card needs no search, and
   offering to make more of them is noise rather than an upsell. The nav already carries the
   upgrade story; this surface should just be their card. */
body.mode-card #tab-pages .search-bar,
body.mode-card #btn-create-page,
body.mode-card #btn-bulk-provision,
body.mode-card #pages-search,
body.mode-card #btn-create-first-page,
body.mode-card #pages-action-banner {
  display: none !important;
}
/* Visible, legible, and plainly not available yet. Dimmed rather than removed so the nav shows what
   the product can do; the padlock is what says "not yet" without a tooltip having to. */
body.mode-card .nav-item.nav-locked {
  opacity: 0.45;
  cursor: not-allowed;
  position: relative;
}
body.mode-card .nav-item.nav-locked:hover {
  background: none;
  color: inherit;
}
body.mode-card .nav-item.nav-locked::after {
  content: '🔒';
  margin-inline-start: auto;
  font-size: 0.72rem;
  opacity: 0.8;
}
.kcm-cta {
  margin: 22px 0 0;
  padding: 20px 22px;
  border-radius: 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-inline-start: 3px solid var(--amber);
}
.kcm-eyebrow {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 700;
  color: var(--amber);
}
.kcm-title {
  font-size: 1.05rem;
  font-weight: 700;
  margin: 6px 0 4px;
  color: var(--text);
}
.kcm-sub {
  font-size: 0.86rem;
  color: var(--dim);
  line-height: 1.55;
  max-width: 60ch;
}
.kcm-btn {
  display: inline-block;
  margin-top: 14px;
  text-decoration: none;
}
/* The public card's launcher, on the inside. Same shape and same corner, because a card owner has
   already learned what the green circle does on their own page. */
.kcm-fab {
  position: fixed;
  right: 18px;
  bottom: 18px;
  z-index: 60;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: #25d366;
  color: #06281a;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 6px 20px rgba(37, 211, 102, 0.35);
  text-decoration: none;
  transition: transform 0.15s ease;
}
.kcm-fab:hover {
  transform: translateY(-2px);
}
@media (max-width: 480px) {
  .kcm-fab {
    right: 12px;
    bottom: 12px;
  }
}

/* ——— Guided card edit: one question at a time ———
   The progress bar is the honest part: it tells someone how much is left before they commit to
   starting, which is what makes a seven-step flow feel finite instead of open-ended. */
.ep-guide-progress {
  height: 4px;
  border-radius: 2px;
  background: var(--surface-3);
  overflow: hidden;
  margin: 0 0 16px;
}
.ep-guide-bar {
  height: 100%;
  width: 0;
  background: var(--primary);
  transition: width 0.25s ease;
}
.ep-guide-step {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 4px;
}
.ep-guide-hint {
  font-size: 0.85rem;
  color: var(--dim);
  line-height: 1.5;
  margin-bottom: 16px;
  max-width: 52ch;
}

/* Team inbox: the Mine toggle, the filter-overflow menu's chips, and the per-message "sent by"
   attribution. display:contents keeps these invisible to whichever flex row already contains
   them (.inbox2-toolbar, or the .inbox-more-dropdown override above). */
.inbox2-filters {
  display: contents;
}
.inbox2-filters:empty {
  display: none;
}
.inbox2-filter-chip {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--dim);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 3px 10px;
  cursor: pointer;
}
.inbox2-filter-chip:hover {
  color: var(--text);
}
.inbox2-filter-chip.active {
  color: var(--on-primary);
  background: var(--primary);
  border-color: var(--primary);
}
.inbox2-filter-chip .chip-count {
  font-weight: 700;
  margin-inline-start: 2px;
}

/* Attention-queue rows (Needs reply · Priority) rendered in the conversation-list pane. */
.inbox-queue-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-inline-end: 6px;
  flex: none;
}
.inbox-queue-actions {
  display: flex;
  gap: 6px;
  margin-top: 6px;
}
.inbox-queue-act {
  font-size: var(--text-2xs);
  font-weight: 600;
  color: var(--dim);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 2px 8px;
  cursor: pointer;
}
.inbox-queue-act:hover {
  color: var(--text);
}
.inbox-queue-act.danger:hover {
  color: var(--red);
  border-color: var(--red);
}
.inbox-queue-act:disabled {
  opacity: 0.5;
  cursor: default;
}

.msg-sentby {
  font-size: 0.62rem;
  color: var(--dim);
  opacity: 0.85;
  margin-inline-start: 6px;
}

/* Structured message extras (meta_json → UI): quotes, choice chips, cards, flow data. */
.msg-quote {
  font-size: var(--text-xs);
  color: var(--dim);
  border-inline-start: 3px solid var(--primary);
  padding: 2px 8px;
  margin-bottom: 4px;
  background: var(--surface-2);
  border-radius: 0 6px 6px 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 280px;
}
.msg-quote-who {
  font-weight: 700;
  color: var(--primary);
}
.msg-quote-who::after {
  content: ': ';
  font-weight: 400;
  color: var(--dim);
}
.msg-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 5px;
}
.msg-chip {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--primary);
  border: 1px solid var(--primary);
  border-radius: 999px;
  padding: 2px 10px;
  background: transparent;
  white-space: nowrap;
}
/* Costs > "Which ads are actually working": link an ad to a product, and the Meta reporting line. */
.ctwa-link {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  font-weight: 600;
  color: var(--primary);
  cursor: pointer;
  text-align: left;
}
.ctwa-link:hover {
  text-decoration: underline;
}
.ctwa-picker {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 6px;
  max-width: 360px;
}
.ctwa-picker[hidden] {
  display: none;
}
.ctwa-results {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
/* Which kind of source a row is: an ad (Meta) or a Klaros link (a post, a poster, a table code). */
.source-kind {
  display: inline-block;
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 1px 6px;
  margin-right: 4px;
  border-radius: var(--radius-xs);
  border: 1px solid var(--border-light);
  color: var(--dim);
  vertical-align: 1px;
}
.source-kind-ad {
  color: var(--primary);
  border-color: var(--primary);
}
/* A source's line carries reach, sales and assists; it wraps rather than hiding the end of it. */
#cost-ctwa-rollup .overview-list-meta {
  white-space: normal;
}
.ctwa-capi-status {
  margin-top: 10px;
}
.ctwa-capi-error {
  color: var(--danger);
  margin-top: 4px;
}
/* Inbox order form: "Already paid at the counter?" sits under Send as its own choice. */
.ordpop-paid {
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid var(--border-light);
}
/* The Click-to-WhatsApp ad's own picture, beside its "From ad" chip. */
.msg-ad-thumb {
  width: 40px;
  height: 40px;
  border-radius: var(--radius-sm);
  object-fit: cover;
  border: 1px solid var(--border-light);
}
/* Quick-reply buttons rendered as WhatsApp renders them: full-width rows under the bubble. */
.msg-buttons {
  display: flex;
  flex-direction: column;
  gap: 1px;
  margin-top: 6px;
  border-top: 1px solid var(--border-light);
}
.msg-btn {
  text-align: center;
  padding: 7px 8px;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--primary);
  background: var(--surface);
}
/* The slot the contact picked on a time proposal — brand green, so the booked row reads at a glance. */
.msg-btn-booked {
  color: var(--green);
  background: color-mix(in srgb, var(--green) 8%, transparent);
}
/* The rows of a list message, as the customer sees them after tapping its button: what was offered
   and, for products, at what price. */
.msg-list-row {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 6px 8px;
  background: var(--surface);
}
.msg-list-title {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-primary);
}
.msg-list-desc {
  font-size: var(--text-xs);
  color: var(--text-secondary);
}
.msg-card {
  font-size: var(--text-sm);
  margin-top: 4px;
  padding: 5px 8px;
  border: 1px solid var(--border-light);
  border-radius: var(--radius);
  background: var(--surface-2);
}
.msg-kv {
  margin-top: 5px;
  border: 1px solid var(--border-light);
  border-radius: var(--radius);
  padding: 5px 8px;
  background: var(--surface-2);
}
.msg-kv-row {
  display: flex;
  gap: 8px;
  font-size: var(--text-xs);
}
.msg-kv-row span {
  color: var(--dim);
  min-width: 70px;
  font-weight: 600;
}
.msg-body.msg-reaction {
  font-size: var(--text-xl);
  line-height: 1.2;
}
.msg-translation {
  font-size: var(--text-sm);
  font-style: italic;
  color: var(--dim);
  margin-top: 2px;
}
/* Always faintly visible — touch devices have no hover — brighter under a pointer. */
.msg-reply-btn,
.msg-react-btn,
.msg-meeting-btn {
  border: none;
  background: none;
  cursor: pointer;
  font-size: var(--text-sm);
  color: var(--dim);
  opacity: 0.45;
  margin-inline-start: 8px;
  padding: 0 4px;
}
.msg:hover .msg-reply-btn,
.msg:hover .msg-react-btn,
.msg:hover .msg-meeting-btn {
  opacity: 1;
}
.msg-reply-btn:hover,
.msg-react-btn:hover,
.msg-meeting-btn:hover {
  color: var(--primary);
}
/* Touch has no hover to reveal them and no precision to hit a ~20x14px glyph. Give them a
   real 44px target and full opacity, since on touch this resting state is the only state. */
@media (hover: none) {
  .msg-reply-btn,
  .msg-react-btn,
  .msg-meeting-btn {
    opacity: 0.9;
    min-width: 44px;
    min-height: 44px;
    padding: 0 8px;
    font-size: var(--text-md);
  }
}

/* Reaction emoji picker — floating strip on a message bubble. */
.msg-react-picker {
  position: absolute;
  bottom: 100%;
  right: 0;
  display: flex;
  gap: 2px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 4px 6px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
  z-index: 20;
}
.msg-react-picker .react-emoji {
  border: none;
  background: none;
  cursor: pointer;
  font-size: 1.2rem;
  padding: 2px 4px;
  border-radius: var(--radius-sm);
  transition: background 0.1s;
}
.msg-react-picker .react-emoji:hover {
  background: var(--surface-2);
}

/* Attachment "+" menu */
.inbox-attach-wrap {
  position: relative;
}
#inbox-plus-btn {
  font-size: var(--text-lg);
  font-weight: 700;
  min-width: 38px;
  padding: 6px 0;
}
.inbox-attach-dropdown {
  position: absolute;
  bottom: calc(100% + 6px);
  right: 0;
  min-width: 200px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
  padding: 6px 0;
  z-index: 30;
}
.attach-item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  border: none;
  background: none;
  padding: 8px 14px;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text);
  cursor: pointer;
  text-align: start;
  white-space: nowrap;
}
.attach-item:hover {
  background: var(--surface-2);
}
.attach-item:disabled {
  opacity: 0.4;
  cursor: default;
}
.attach-item span {
  font-size: 1rem;
  width: 20px;
  text-align: center;
  flex: none;
}
/* Composer actions that only relocate into this menu on mobile. Must sit AFTER .attach-item,
   which is equally specific and would otherwise re-show them on desktop. */
.attach-mobile-only {
  display: none;
}
.attach-sep {
  border: none;
  border-top: 1px solid var(--border);
  margin: 4px 10px;
}
.attach-group-label {
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--dim);
  padding: 6px 14px 2px;
}

/* Inline popovers (above composer) — shared base. */
.inbox-pop {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px;
  margin: 0 16px 10px;
  background: var(--surface);
}
.inbox-pop-title {
  font-size: var(--text-sm);
  font-weight: 700;
  color: var(--dim);
  margin-bottom: 8px;
}
.inbox-pop-hint {
  font-size: var(--text-xs);
  color: var(--dim);
  margin-bottom: 6px;
}
/* Antisocial-hours / double-booking caution in the "Propose times" preview. */
.inbox-pop-hint.warn {
  color: var(--warn-fg);
  font-weight: 600;
}

/* Contextual "how did the call go?" prompt above the composer (meeting outcome loop). */
.inbox-followup {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  padding: 8px 16px;
  margin: 0 16px 8px;
  border: 1px solid var(--warn-border);
  background: var(--warn-bg);
  border-radius: 10px;
}
.inbox-followup-q {
  font-size: var(--text-sm);
  color: var(--warn-fg);
  font-weight: 600;
}
.inbox-followup-hint {
  font-weight: 500;
  opacity: 0.85;
}
.inbox-followup-actions {
  display: flex;
  gap: 6px;
  margin-inline-start: auto;
}

/* Composer quote strip ("replying to …") */
.inbox2-reply-quote {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px 0;
}
.reply-quote-text {
  flex: 1;
  font-size: var(--text-xs);
  color: var(--dim);
  border-inline-start: 3px solid var(--primary);
  padding: 2px 8px;
  background: var(--surface-2);
  border-radius: 0 6px 6px 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.reply-quote-cancel {
  border: none;
  background: none;
  cursor: pointer;
  color: var(--dim);
  font-size: var(--text-sm);
}
.reply-quote-cancel:hover {
  color: var(--red);
}

/* ─────────────────────────────────────────────────────────────────────────────────
   Inbox: mobile (single-pane navigation)

   The desktop layout puts the conversation list beside the thread. Below 760px there is
   no width to split: shrinking the list instead of collapsing it produced a 100px list
   (a 28px-wide truncated name, no preview, no number) next to a 241px thread, so both
   panes failed at once. Mobile shows ONE pane at a time — the list fills the screen, and
   opening a conversation slides the thread over it. `.thread-open` on .inbox2 is the
   switch; inbox.js sets it and the back button in the thread header clears it.
   ───────────────────────────────────────────────────────────────────────────────── */
@media (max-width: 760px) {
  /* Full-bleed: cancel .dash-main's 16px mobile padding so the inbox owns the whole width
     below the 56px header. An inbox with page gutters wastes width it cannot spare.
     Deliberately in-flow rather than position:fixed — .dash-tab carries a translateY entry
     animation, and a transformed ancestor becomes the containing block for fixed children,
     which would silently un-pin this from the viewport for the first 300ms of every visit. */
  .inbox2 {
    position: relative;
    margin: -16px;
    border-radius: 0;
    border: 0;
    height: calc(100vh - 56px);
  }
  .inbox2-list {
    width: 100%;
    border-inline-end: 0;
  }

  .inbox2-thread {
    position: absolute;
    inset: 0;
    z-index: 10;
    background: var(--surface);
    transform: translateX(100%);
    visibility: hidden;
    transition:
      transform 0.22s ease,
      visibility 0.22s;
  }
  .inbox2.thread-open .inbox2-thread {
    transform: none;
    visibility: visible;
  }
  /* "Select a conversation" is a two-pane idea. Single-pane, the list IS that screen. */
  .inbox2-empty {
    display: none;
  }

  .inbox2-thread-back {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 44px;
    height: 44px;
    margin-inline-start: -10px;
    font-size: 1.6rem;
    line-height: 1;
    color: var(--text);
    background: none;
    border: 0;
    cursor: pointer;
  }
  .inbox2-thread-title {
    flex: 1;
    min-width: 0;
  }
  .inbox2-thread-head {
    padding: 4px 10px;
    gap: 8px;
  }
  .inbox2-thread-head-right {
    flex: none;
    gap: 6px;
    flex-wrap: wrap;
    justify-content: flex-end;
  }
  .inbox2-thread-head-right .btn {
    min-height: 44px;
  }
  #inbox-detail-toggle {
    min-width: 44px;
    min-height: 44px;
    justify-content: center;
  }
  #inbox-more-btn {
    min-width: 44px;
    min-height: 44px;
    justify-content: center;
  }
  .inbox-more-dropdown .inbox-more-item {
    min-height: 44px;
    display: flex;
    align-items: center;
  }
  /* The indicator pills are informational text, not primary controls — 32px keeps them tappable
     without competing with the 44px action buttons for the row's width. */
  button.inbox2-indicator {
    min-height: 32px;
    padding: 2px 10px;
  }
  .inbox2-meta-strip {
    padding: 6px 10px;
  }

  /* ── List-pane chrome ──
     Categories, the Priority chip, and the search+Mine+overflow toolbar are the only rows now
     (previously six, stacked 348px deep, folded behind a "Filters" disclosure — that toggle is
     gone along with the rows it existed to hide). What's left fits without folding; the only
     thing that still scrolls sideways is the category row, on the narrowest phones. */
  .inbox2-cats {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    padding: 6px 10px 0;
  }
  .inbox2-cats::-webkit-scrollbar {
    display: none;
  }
  .inbox2-cat-tab {
    flex: 1 0 auto;
    min-height: 44px;
    padding: 6px 12px;
  }
  .inbox2-filter-chip,
  .inbox2-line-tab {
    min-height: 44px;
  }
  #inbox-list-more-btn {
    min-width: 44px;
    min-height: 44px;
    justify-content: center;
  }
  .filter-toggle-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 16px;
    height: 16px;
    padding: 0 5px;
    font-size: 0.62rem;
    font-weight: 700;
    color: var(--on-primary);
    background: var(--primary);
    border-radius: 999px;
  }
  /* An author display: rule always beats the UA [hidden]{display:none} default (origin order
     trumps specificity), so the JS's badge.hidden = (n === 0) would silently do nothing without
     this — the "0" badge would show permanently instead of only appearing when it means something. */
  .filter-toggle-count[hidden] {
    display: none;
  }

  .inbox2-toolbar {
    padding: 8px 10px;
    flex-wrap: wrap;
  }
  /* 16px is the threshold below which iOS Safari zooms the page on focus and never zooms
     back out. Every text field the agent taps has to clear it. */
  .inbox2-search input {
    font-size: 16px;
    min-height: 44px;
  }

  /* ── Conversation rows ──
     The preview and the number are what make a row identifiable; the old 480px rule hid
     both. Full width has room for all of it, at a 44px-tall tap target. */
  .inbox-convo {
    min-height: 44px;
    padding: 9px 12px;
  }

  .inbox2-messages {
    padding: 10px;
    gap: 6px;
  }
  .msg {
    max-width: 85%;
  }
  /* Belt and braces with the (hover: none) rule further up: width is the reliable signal on
     phones that report hover support (some Android browsers do), and these were ~20x14px. */
  .msg-reply-btn,
  .msg-react-btn,
  .msg-meeting-btn {
    opacity: 0.9;
    min-width: 44px;
    min-height: 44px;
    padding: 0 8px;
    font-size: var(--text-md);
  }

  /* ── Composer ──
     Six controls in one row squeezed the textarea to 96px. Note / Suggest / Template move
     into the "+" menu (see .attach-mobile-only), leaving textarea + "+" + Send. */
  .inbox2-compose {
    gap: 6px;
    padding: 8px 10px;
  }
  .inbox2-compose textarea {
    min-height: 44px;
    font-size: 16px;
  }
  #inbox-note-toggle,
  #inbox-suggest-btn,
  #inbox-template-btn {
    display: none !important;
  }
  #inbox-plus-btn,
  #inbox-send {
    min-height: 44px;
    min-width: 44px;
    justify-content: center;
  }
  .attach-mobile-only {
    display: block;
  }
  .inbox-attach-dropdown {
    right: -8px;
    min-width: 200px;
    max-height: 60vh;
    overflow-y: auto;
  }
  .attach-item {
    min-height: 44px;
  }

  .inbox-pop {
    margin: 0 8px 8px;
    padding: 10px;
    max-height: 60vh;
    overflow-y: auto;
  }
  .msg-react-picker {
    gap: 1px;
    padding: 3px 4px;
  }
  .msg-react-picker .react-emoji {
    font-size: 1.35rem;
    padding: 6px 8px;
  }
}
/* dvh tracks the visible viewport, so the composer stays above the address bar rather than
   under it. Kept separate from the block above so the vh value remains the fallback. */
@supports (height: 100dvh) {
  @media (max-width: 760px) {
    .inbox2 {
      height: calc(100dvh - 56px);
    }
  }
}

@media (max-width: 380px) {
  /* Narrowest phones: trim padding, never information. The preview and number stay. */
  .inbox2-thread-head-right {
    gap: 4px;
  }
  .inbox2-thread-num {
    display: none;
  }
  .inbox-convo {
    padding: 9px 10px;
  }
  .inbox2-messages {
    padding: 8px;
  }
  .msg {
    max-width: 90%;
  }
  .msg.in .msg-react-picker {
    right: auto;
    left: 0;
  }
}

/* Settings → WhatsApp Tools rows (QR links, flows) */
.wa-tool-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 0;
  border-bottom: 1px solid var(--border-light);
  flex-wrap: wrap;
}
.wa-tool-row:last-of-type {
  border-bottom: none;
}

/* Flow category badges — same visual mechanic as .tpl-bp-cat, Meta's flow categories instead */
.tpl-bp-cat.LEAD_GENERATION,
.tpl-bp-cat.SALES {
  background: var(--warn-bg);
  color: var(--warn-fg);
}
.tpl-bp-cat.APPOINTMENT_BOOKING {
  background: var(--ok-bg);
  color: var(--primary-dark);
}
.tpl-bp-cat.SIGN_UP,
.tpl-bp-cat.SIGN_IN {
  background: var(--info-bg);
  color: var(--info-fg);
}
.tpl-bp-cat.CONTACT_US,
.tpl-bp-cat.CUSTOMER_SUPPORT {
  background: #fee2e2;
  color: var(--danger-fg-strong);
}
.tpl-bp-cat.SURVEY,
.tpl-bp-cat.OTHER {
  background: #f1f5f9;
  color: #475569;
}

/* Flow library "customize before deploying" mini-panel (one per selected blueprint with option lists) */
.flow-customize-card {
  padding: 10px 12px;
  margin-bottom: 8px;
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}
.flow-customize-card .form-group {
  margin-bottom: 8px;
}
.flow-customize-card:last-child {
  margin-bottom: 0;
}

/* Local flow-form mock-up — the "how your customer sees it" phone preview, rendered client-side
   from the flow's own JSON (no Meta call; works before anything is deployed). Sits inside the
   same .tpl-phone gradient frame Templates uses, for visual consistency. */
.flow-mock-screen {
  background: var(--surface);
  border-radius: var(--radius-xs) 12px 12px 12px;
  padding: 12px 12px 14px;
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.08);
}
.flow-mock-heading {
  font-size: var(--text-base);
  font-weight: 700;
  color: #111b21;
  margin-bottom: 10px;
  line-height: 1.35;
}
.flow-mock-field {
  margin-bottom: 9px;
}
.flow-mock-label {
  font-size: var(--text-2xs);
  color: #667781;
  margin-bottom: 3px;
}
.flow-mock-input {
  border: 1px solid #e2e8f0;
  border-radius: var(--radius);
  padding: 7px 9px;
  font-size: 0.76rem;
  color: #111b21;
  background: #fbfbfb;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 6px;
}
.flow-mock-input-hint {
  color: #94a3b8;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.flow-mock-radio-row {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 0.76rem;
  color: #111b21;
  padding: 3px 0;
}
.flow-mock-radio-dot {
  width: 14px;
  height: 14px;
  border-radius: 999px;
  border: 1.5px solid #94a3b8;
  flex: none;
}
.flow-mock-footer {
  margin-top: 12px;
  background: var(--whatsapp-green);
  color: var(--on-whatsapp);
  text-align: center;
  border-radius: var(--radius);
  padding: 9px 8px;
  font-size: var(--text-sm);
  font-weight: 700;
}

/* Media library grid */
.media-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 14px;
}
.media-card {
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
  background: var(--surface);
  display: flex;
  flex-direction: column;
}
.media-thumb {
  width: 100%;
  height: 120px;
  object-fit: cover;
  display: block;
  background: var(--surface-2);
}
.media-thumb-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2.4rem;
  color: var(--dim);
}
.media-card-name {
  font-size: var(--text-sm);
  font-weight: 600;
  padding: 8px 10px 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.media-card-meta {
  font-size: var(--text-xs);
  color: var(--dim);
  padding: 2px 10px 8px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Products list: one shelf per category, each holding its designs of several pieces and its single
   products (ui/product-arrangement.js arrange). */
.product-shelf {
  margin-bottom: 22px;
}
.product-shelf-title {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin: 0 0 10px;
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 600;
}
.product-shelf-count {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 400;
  color: var(--dim);
}
.variant-group {
  padding: 10px;
  margin-bottom: 10px;
}
.variant-group-summary {
  margin-bottom: 8px;
}
/* Square photographs. Jewellery is shot square or portrait, and the 120px landscape strip every
   grid shared cut the piece and any caption under it. The tile is as tall as it is wide. */
.product-card .media-thumb,
.design-tile .media-thumb {
  height: auto;
  aspect-ratio: 1 / 1;
}
/* Two lines for a name before the ellipsis: "Mothiram Emerald Filigr…" told the shop nothing. */
.product-card .media-card-name,
.design-tile .media-card-name {
  white-space: normal;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  line-height: 1.3;
}
/* One grid per shelf: a design's opened pieces span the row under it, and the cards after the
   tile fill the gap beside it rather than leaving it empty. */
.product-shelf-grid {
  grid-auto-flow: row dense;
}
.product-shelf {
  scroll-margin-top: 72px;
}
/* A design of several pieces: one tile, drawn as a small stack so it reads as more than one. */
.design-tile {
  position: relative;
  cursor: pointer;
  overflow: visible;
  box-shadow:
    3px 3px 0 -1px var(--surface),
    3px 3px 0 0 var(--border),
    6px 6px 0 -1px var(--surface),
    6px 6px 0 0 var(--border);
}
.design-tile.is-open {
  border-color: var(--primary);
}
.design-tile:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 3px;
}
.design-tile-count,
.product-card-count {
  position: absolute;
  inset-block-end: 8px;
  font-size: var(--text-xs);
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.66);
  color: #fff;
}
.design-tile-count {
  inset-inline-start: 8px;
}
.product-card-count {
  inset-inline-end: 8px;
}
.design-pieces {
  grid-column: 1 / -1;
  padding: 10px;
  margin: 0;
}
.design-pieces[hidden] {
  display: none;
}
/* Ticking products shows every piece, so nothing ticked is ever out of sight. */
#product-library-list.is-selecting .design-pieces[hidden] {
  display: block;
}
.design-pieces-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}
/* The one status line a card carries, and the full list on the product's own view. */
.pl-status {
  font-weight: 600;
}
/* A reason is a sentence; two lines of it before the ellipsis, the whole of it on hover and in
   the product's own view. */
.media-card-meta.pl-status {
  white-space: normal;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  line-height: 1.35;
}
.pl-status.is-red {
  color: var(--red);
}
.pl-status.is-amber {
  color: var(--amber);
}
.pl-status.is-dim {
  color: var(--dim);
  font-weight: 500;
}
.pl-status.is-ok {
  color: var(--primary);
}
/* One chip per shelf, to jump to it. */
.pl-shelf-chips {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  margin: 0 0 14px;
  padding-bottom: 2px;
  scrollbar-width: thin;
}
.pl-shelf-chip {
  flex: 0 0 auto;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  border-radius: 999px;
  padding: 4px 12px;
  font: 500 var(--text-sm) / 1.4 var(--font-body);
  white-space: nowrap;
  cursor: pointer;
}
.pl-shelf-chip:hover {
  border-color: var(--primary);
}
.pl-shelf-chip span {
  margin-inline-start: 6px;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--dim);
}
/* The product's own view, in the sheet (openView). The form below it hides while it shows. */
#product-library-form.is-viewing > :not(.pl-sheet-head):not(#product-view) {
  display: none !important;
}
.pv-photos {
  margin-bottom: 14px;
}
.pv-main {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  max-height: 420px;
  object-fit: contain;
  background: var(--surface-2);
  border-radius: 10px;
}
.pv-main-empty {
  display: grid;
  place-items: center;
  font-size: 3rem;
  color: var(--dim);
}
/* The empty picture is the way to add one, not a placeholder that looks finished. */
.pv-add-photo {
  align-content: center;
  gap: 6px;
  border: 2px dashed var(--border);
  cursor: pointer;
  font: inherit;
}
.pv-add-photo span:last-child {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--primary);
}
.pv-add-photo:hover,
.pv-add-photo:focus-visible {
  border-color: var(--primary);
}
/* Delete sits apart from the everyday actions, in the danger colour, never beside Edit's weight. */
.pv-actions .pv-delete {
  margin-inline-start: auto;
  color: var(--red);
}
.pv-strip {
  display: flex;
  gap: 8px;
  margin-top: 8px;
  overflow-x: auto;
}
.pv-thumb {
  flex: 0 0 64px;
  width: 64px;
  height: 64px;
  padding: 0;
  border: 2px solid transparent;
  border-radius: 8px;
  overflow: hidden;
  background: var(--surface-2);
  cursor: pointer;
}
.pv-thumb img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.pv-thumb.is-current {
  border-color: var(--primary);
}
.pv-sub {
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.pv-price {
  margin-top: 2px;
  font-size: 1.4rem;
  font-weight: 700;
  color: var(--text);
}
.pv-price span {
  margin-inline-start: 4px;
  font-size: var(--text-sm);
  font-weight: 400;
  color: var(--dim);
}
.pv-head .pv-badge {
  position: static;
  display: inline-block;
  margin-top: 6px;
}
.pv-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 14px 0;
}
.pv-status {
  display: grid;
  gap: 4px;
  margin: 0 0 14px;
  padding: 0;
  list-style: none;
  font-size: var(--text-sm);
}
.pv-label {
  margin: 14px 0 6px;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--dim);
}
.pv-line {
  font-size: var(--text-sm);
  color: var(--text);
}
.pv-facts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px 16px;
  margin: 0;
}
.pv-facts div {
  min-width: 0;
}
.pv-facts dt {
  font-size: var(--text-xs);
  color: var(--dim);
}
.pv-facts dd {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--text);
  overflow-wrap: anywhere;
}
/* wrap: the row was sized for two buttons, so adding Edit and Sold out pushed Delete off the edge
   of the card where it was still clickable but half-invisible. Wrapping costs a row of height and
   removes the whole class of "one more action clips the last one". */
.media-card-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 0 10px 10px;
  margin-top: auto;
}
.media-act {
  font-size: var(--text-xs);
  font-weight: 600;
  text-decoration: none;
  padding: 4px 8px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  color: var(--text);
  cursor: pointer;
  background: none;
}
.media-act:hover {
  background: var(--bg, #f8f9fa);
}
.media-act-del {
  color: var(--red, #dc2626);
  border-color: transparent;
}
.media-act-del:hover {
  background: var(--danger-bg);
}
.media-act-dim {
  color: var(--dim);
  border-color: transparent;
  cursor: default;
}

/* Shared visual media picker (Templates + Broadcast header media + Catalog Picker) */
.media-picker-card {
  position: relative;
  cursor: pointer;
  border-radius: 12px;
  border: 1.5px solid var(--border);
  background: var(--surface);
  transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
  padding-bottom: 8px;
  user-select: none;
  overflow: hidden;
}
.media-picker-card:hover {
  border-color: var(--primary, #0f766e);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.08);
  transform: translateY(-2px);
}
.media-picker-card:active {
  transform: scale(0.98);
}
.media-picker-card:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

/* Active / Selected state ring & glow */
.media-picker-card.is-active {
  border-color: var(--whatsapp-green, var(--primary, #25d366));
  background: var(--surface);
  box-shadow:
    0 0 0 2px var(--whatsapp-green, var(--primary, #25d366)),
    0 6px 20px rgba(37, 211, 102, 0.15);
}

/* Selection Badge showing order index or checkmark */
.media-picker-badge {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(4px);
  border: 1.5px solid var(--border);
  color: var(--dim);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.72rem;
  font-weight: 700;
  transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
  z-index: 2;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);
  pointer-events: none;
}
.media-picker-card.is-active .media-picker-badge {
  background: var(--whatsapp-green, var(--primary, #25d366));
  border-color: var(--whatsapp-green, var(--primary, #25d366));
  color: #ffffff;
  transform: scale(1.1);
  box-shadow: 0 3px 10px rgba(37, 211, 102, 0.4);
}

.media-picker-card .media-thumb {
  width: 100%;
  height: 125px;
  object-fit: cover;
  display: block;
  background: var(--surface-2, #f1f5f9);
  border-bottom: 1px solid var(--border);
}

/* Skeleton loader cards for smooth loading without flicker */
.media-card-skeleton {
  border-radius: 12px;
  height: 175px;
  background: linear-gradient(
    90deg,
    var(--surface-2, #e2e8f0) 25%,
    var(--surface, #f8fafc) 50%,
    var(--surface-2, #e2e8f0) 75%
  );
  background-size: 200% 100%;
  animation: media-skeleton-pulse 1.4s infinite ease-in-out;
  border: 1px solid var(--border);
}
@keyframes media-skeleton-pulse {
  0% {
    background-position: 200% 0;
  }
  100% {
    background-position: -200% 0;
  }
}

.media-picker-filters {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.media-picker-tab {
  font-size: var(--text-sm);
  font-weight: 600;
  padding: 5px 12px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--dim);
  cursor: pointer;
}
.media-picker-tab.is-active {
  background: var(--primary);
  color: var(--on-primary);
  border-color: var(--primary);
}
.media-picker-preview {
  display: flex;
  align-items: center;
  gap: 10px;
}
.media-picker-preview-thumb {
  width: 48px;
  height: 48px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  background: var(--surface-2);
}
.media-picker-preview-thumb-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--text-xl);
}

/* ================================================================
   UME Media Picker — Split-panel premium layout (mpc-*)
   All values via tokens.css — no raw hex or raw px outside structural grid dimensions.
   ================================================================ */
.mpc-modal {
  display: flex;
  flex-direction: column;
  height: 92vh;
}
.mpc-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-3) var(--space-5);
  border-bottom: 1px solid var(--border);
  flex: none;
  background: var(--surface);
}
.mpc-header-meta {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
  overflow: hidden;
}
.mpc-header-title {
  font-weight: 700;
  color: var(--text);
  font-size: var(--text-base);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 260px;
}
.mpc-header-mime {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--dim);
  white-space: nowrap;
}
.mpc-header-dims {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--dim);
  white-space: nowrap;
}
.mpc-sep {
  color: var(--border-light);
  font-size: var(--text-sm);
  user-select: none;
  flex: none;
}
.mpc-header-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex: none;
}
.mpc-shell {
  display: grid;
  grid-template-columns: 1fr 400px;
  flex: 1;
  min-height: 0;
  overflow: hidden;
}
.mpc-preview {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--bg);
  border-right: 1px solid var(--border);
}
.mpc-preview-media {
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  padding: var(--space-6);
  position: relative;
}
.mpc-preview-img,
.mpc-preview-video {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
  display: block;
}
.mpc-preview-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  color: var(--dim);
  font-size: var(--text-sm);
  text-align: center;
}
.mpc-preview-empty-icon {
  font-size: 2.8rem;
  line-height: 1;
  opacity: 0.45;
}
.mpc-audio-bar {
  flex: none;
  border-top: 1px solid var(--border);
  background: var(--surface);
  padding: var(--space-3) var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.mpc-audio-title {
  font-size: var(--text-base);
  font-weight: 700;
  color: var(--text);
}
.mpc-audio-time {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--dim);
}
.mpc-waveform {
  width: 100%;
  height: 40px;
  border-radius: var(--radius-xs);
  background: var(--surface-2);
}
.mpc-audio-controls {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.mpc-audio-btn {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--text-secondary);
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
  font-size: var(--text-lg);
  transition: var(--transition);
  flex: none;
}
.mpc-audio-btn:hover {
  color: var(--primary);
  background: var(--primary-glow);
}
.mpc-audio-btn.mpc-play {
  width: 36px;
  height: 36px;
  background: var(--primary);
  color: var(--on-primary);
  border-radius: 50%;
  font-size: var(--text-base);
  box-shadow: 0 4px 12px var(--primary-glow);
}
.mpc-audio-btn.mpc-play:hover {
  background: var(--primary-dark);
}
.mpc-filmstrip-wrap {
  flex: none;
  border-top: 1px solid var(--border);
  background: var(--surface);
  padding: var(--space-2) 30px;
  position: relative;
  overflow: hidden;
}
.mpc-filmstrip {
  display: flex;
  gap: var(--space-2);
  overflow-x: auto;
  scroll-behavior: smooth;
  scrollbar-width: none;
  padding: var(--space-1) 0;
}
.mpc-filmstrip::-webkit-scrollbar {
  display: none;
}
.mpc-film-thumb {
  flex: none;
  width: 96px;
  height: 60px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  border: 2px solid transparent;
  cursor: pointer;
  transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
  opacity: 0.6;
  background: var(--surface-2);
}
.mpc-film-thumb:hover {
  opacity: 1;
  border-color: var(--border-light);
}
.mpc-film-thumb.is-active {
  opacity: 1;
  border-color: var(--primary);
  box-shadow: 0 0 0 2px var(--primary-glow);
}
.mpc-film-icon {
  flex: none;
  width: 96px;
  height: 60px;
  border-radius: var(--radius-sm);
  border: 2px solid transparent;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.4rem;
  background: var(--surface-2);
  opacity: 0.6;
  transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
  color: var(--dim);
}
.mpc-film-icon:hover {
  opacity: 1;
  border-color: var(--border-light);
}
.mpc-film-icon.is-active {
  opacity: 1;
  border-color: var(--primary);
  box-shadow: 0 0 0 2px var(--primary-glow);
}
.mpc-film-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  width: 24px;
  height: 34px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-secondary);
  font-size: var(--text-lg);
  transition: var(--transition);
  z-index: 2;
  padding: 0;
  line-height: 1;
}
.mpc-film-nav:hover {
  background: var(--surface-2);
  border-color: var(--primary);
  color: var(--primary);
}
.mpc-film-nav:disabled {
  opacity: 0.3;
  cursor: default;
}
.mpc-film-prev {
  left: 2px;
}
.mpc-film-next {
  right: 2px;
}
.mpc-picker {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--surface);
}
.mpc-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-4) var(--space-4) var(--space-3);
  flex: none;
  border-bottom: 1px solid var(--border);
}
.mpc-toolbar-count {
  font-size: var(--text-sm);
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--dim);
}
.mpc-toolbar-actions {
  display: flex;
  gap: var(--space-2);
  align-items: center;
}
.mpc-icon-btn {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--dim);
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
  transition: var(--transition);
  padding: 0;
}
.mpc-icon-btn:hover {
  color: var(--text);
  background: var(--surface-2);
}
.mpc-icon-btn.is-active {
  color: var(--primary);
  background: var(--primary-glow);
}
.mpc-icon-btn svg {
  display: block;
}
.mpc-album-label {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 700;
  color: var(--text);
  padding: var(--space-3) var(--space-4) var(--space-2);
  flex: none;
}
.mpc-search-wrap {
  padding: var(--space-1) var(--space-4) var(--space-2);
  flex: none;
}
.mpc-search-wrap-inner {
  position: relative;
}
.mpc-search-input {
  width: 100%;
  padding: 7px var(--space-3) 7px 30px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font-size: var(--text-sm);
  background: var(--surface-2);
  color: var(--text);
  font-family: var(--font-body);
  transition: var(--transition);
}
.mpc-search-input:focus {
  border-color: var(--primary);
  outline: none;
  background: var(--surface);
}
.mpc-search-icon {
  position: absolute;
  left: 9px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--dim);
  pointer-events: none;
}
.mpc-filter-row {
  padding: 0 var(--space-4) var(--space-2);
  flex: none;
}
.mpc-grid-wrap {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: var(--space-3);
}
.mpc-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
  gap: var(--space-2);
}
.mpc-card {
  position: relative;
  cursor: pointer;
  border-radius: 10px;
  border: 1.5px solid var(--border);
  background: var(--surface);
  transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
  overflow: hidden;
  user-select: none;
}
.mpc-card:hover {
  border-color: var(--primary);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
  transform: translateY(-1px);
}
.mpc-card:active {
  transform: scale(0.98);
}
.mpc-card:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}
.mpc-card.is-active {
  border-color: var(--amber);
  box-shadow:
    0 0 0 2px var(--amber-glow),
    0 4px 16px rgba(0, 0, 0, 0.06);
}
.mpc-card.is-previewing {
  border-color: var(--primary);
  box-shadow: 0 0 0 2px var(--primary-glow);
}
.mpc-card-thumb {
  width: 100%;
  height: 110px;
  object-fit: cover;
  display: block;
  background: var(--surface-2);
}
.mpc-card-icon {
  width: 100%;
  height: 110px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2rem;
  color: var(--dim);
  background: var(--surface-2);
}
.mpc-type-badge {
  position: absolute;
  top: 6px;
  left: 6px;
  z-index: 3;
  background: var(--amber);
  color: #fff;
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  font-weight: 700;
  padding: 2px 5px;
  border-radius: var(--radius-xs);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  pointer-events: none;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
}
.mpc-duration-badge {
  position: absolute;
  bottom: 34px;
  left: 6px;
  z-index: 3;
  background: rgba(0, 0, 0, 0.62);
  color: #fff;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  padding: 2px 5px;
  border-radius: var(--radius-xs);
  pointer-events: none;
  backdrop-filter: blur(4px);
}
.mpc-sel-ring {
  position: absolute;
  top: 7px;
  right: 7px;
  z-index: 2;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.75);
  background: rgba(0, 0, 0, 0.22);
  backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--text-xs);
  font-weight: 700;
  color: #fff;
  transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
  pointer-events: none;
}
.mpc-card.is-active .mpc-sel-ring {
  background: var(--amber);
  border-color: var(--amber);
  box-shadow: 0 2px 8px var(--amber-glow);
  transform: scale(1.1);
}
.mpc-card-name {
  font-size: var(--text-sm);
  font-weight: 600;
  padding: 5px var(--space-2) 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--text);
}
/* What a file is part of, seen before anyone deletes it. */
.mpc-card-uses {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  padding: 2px var(--space-2) 0;
}
.mpc-use-chip {
  font-size: var(--text-xs);
  font-weight: 600;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--primary-glow);
  color: var(--primary);
}
.mpc-use-chip.is-chat {
  background: var(--amber-glow);
  color: var(--amber);
}
/* The next page sits under the grid, across its full width. */
.mpc-load-more {
  grid-column: 1 / -1;
  justify-self: center;
  margin: var(--space-2) 0;
}
.mpc-source {
  width: auto;
  margin-inline-start: auto;
  padding: 4px 8px;
  font-size: var(--text-sm);
}
.mpc-card-dims {
  font-size: var(--text-xs);
  font-family: var(--font-mono);
  color: var(--dim);
  padding: 0 var(--space-2) var(--space-2);
}
.mpc-nav-btn {
  background: none;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  width: 30px;
  height: 30px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-secondary);
  font-size: var(--text-lg);
  transition: var(--transition);
  flex: none;
  padding: 0;
  line-height: 1;
}
.mpc-nav-btn:hover {
  background: var(--surface-2);
  border-color: var(--primary);
  color: var(--primary);
}
.mpc-nav-btn:disabled {
  opacity: 0.3;
  cursor: default;
}
.mpc-close-btn {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--dim);
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
  font-size: var(--text-lg);
  transition: var(--transition);
  flex: none;
  padding: 0;
  line-height: 1;
}
.mpc-close-btn:hover {
  color: var(--text);
  background: var(--surface-2);
}
.mpc-footer {
  flex: none;
  border-top: 1px solid var(--border);
  padding: var(--space-3) var(--space-4);
  background: var(--surface);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.mpc-count-label {
  font-size: var(--text-sm);
  color: var(--dim);
  text-align: center;
  transition: color 0.2s;
}
.mpc-count-label.is-warn {
  color: var(--warning);
}
.mpc-confirm-btn {
  width: 100%;
  padding: 12px;
  border: none;
  border-radius: var(--radius);
  cursor: pointer;
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 600;
  background: var(--amber);
  color: #fff;
  transition: var(--transition);
  box-shadow: 0 4px 14px var(--amber-glow);
}
.mpc-confirm-btn:hover {
  background: var(--amber2);
  box-shadow: 0 6px 20px var(--amber-glow);
}
.mpc-confirm-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
  box-shadow: none;
}
.mpc-empty {
  grid-column: 1 / -1;
  padding: var(--space-10) var(--space-4);
  text-align: center;
  color: var(--dim);
  font-size: var(--text-sm);
}
/* Upload-in-picker: uploading state feedback */
.mpc-upload-btn.is-uploading {
  opacity: 0.5;
  pointer-events: none;
}
.mpc-upload-btn.is-uploading svg {
  animation: mpc-spin 0.9s linear infinite;
}
@keyframes mpc-spin {
  to {
    transform: rotate(360deg);
  }
}
/* Optimistic insert card — shimmer while server processes */
.mpc-card.is-uploading .mpc-card-thumb,
.mpc-card.is-uploading .mpc-card-icon {
  animation: media-skeleton-pulse 1.2s infinite ease-in-out;
  background-size: 200% 100%;
}
/* Filmstrip skeleton slots shown during initial load */
.mpc-film-skeleton {
  flex: none;
  width: 96px;
  height: 60px;
  border-radius: var(--radius-sm);
  background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface) 50%, var(--surface-2) 75%);
  background-size: 200% 100%;
  animation: media-skeleton-pulse 1.4s infinite ease-in-out;
}
@media (max-width: 480px) {
  .mpc-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* Operator-facing URL destination preview (Templates + Broadcast) — not shown to recipients */
.link-preview-card {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px 12px;
  margin-top: 8px;
  max-width: 320px;
  background: var(--surface);
}
.link-preview-label {
  font-size: var(--text-2xs);
  color: var(--dim);
  margin-bottom: 6px;
  line-height: 1.3;
}
.link-preview-loading {
  font-size: var(--text-sm);
  color: var(--dim);
}
.link-preview-body {
  display: flex;
  gap: 8px;
  align-items: flex-start;
}
.link-preview-image {
  width: 64px;
  height: 64px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  flex: none;
}
.link-preview-text {
  min-width: 0;
}
.link-preview-title {
  font-size: var(--text-sm);
  font-weight: 700;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.link-preview-desc {
  font-size: var(--text-xs);
  color: var(--dim);
  margin-top: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.link-preview-domain {
  font-size: var(--text-xs);
  color: var(--primary);
  margin-top: 6px;
  font-weight: 600;
}

/* Grouped sidebar (Miller's Law) */
.nav-group-label {
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--dim);
  font-weight: 700;
  padding: 12px 12px 4px;
  opacity: 0.75;
}
.dash-sidebar .nav-section + .nav-section {
  margin-top: 4px;
}

/* ── Costs tab — Meta-authoritative spend, zero-markup ───────────────────────── */
.cost-hero {
  padding: 18px 20px;
}
.cost-hero-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
}
.cost-hero-main {
  min-width: 0;
}
.cost-hero-amount {
  font-family: var(--font-display);
  font-size: 2.4rem;
  font-weight: 700;
  line-height: 1.05;
  color: var(--text);
  margin-top: 4px;
  letter-spacing: -0.02em;
}
.cost-hero-sub {
  margin-top: 5px;
  color: var(--text-secondary);
  font-size: var(--text-base);
}
.cost-hero-blended {
  margin-top: 10px;
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  flex-wrap: wrap;
  padding: 7px 12px;
  border-radius: 10px;
  background: var(--primary-glow);
  border: 1px solid color-mix(in srgb, var(--primary) 30%, var(--border));
}
.cost-hero-blended strong {
  color: var(--primary-dark);
  font-size: 1rem;
  font-weight: 800;
}
.cost-hero-blended span {
  color: var(--text-secondary);
  font-size: var(--text-sm);
}
.cost-markup-badge {
  flex: none;
  text-align: center;
  padding: 14px 22px;
  border-radius: var(--radius);
  border: 1px solid var(--primary);
  background: var(--primary-glow);
}
.cost-markup-label {
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 700;
  color: var(--primary-dark);
}
.cost-markup-value {
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--primary);
  line-height: 1.15;
  margin: 3px 0 2px;
}
.cost-markup-note {
  font-size: var(--text-2xs);
  color: var(--dim);
}
.cost-range-tabs {
  display: inline-flex;
  gap: 6px;
  margin-top: 16px;
}
.cost-range-btn {
  font-size: var(--text-sm);
  font-weight: 600;
  padding: 6px 15px;
  border-radius: 999px;
  cursor: pointer;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--dim);
  transition: var(--transition);
}
.cost-range-btn:hover {
  border-color: var(--border-light);
  color: var(--text);
}
.cost-range-btn.is-active {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--on-primary);
}
.cost-footnote {
  margin-top: 14px;
  font-size: var(--text-xs);
  color: var(--dim);
  line-height: 1.5;
  max-width: 640px;
}

/* Markup avoided — the zero-markup promise expressed as money saved */
.cost-savings-panel {
  border-color: var(--primary);
  background: var(--primary-glow);
}
.cost-savings-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
  margin-top: 10px;
}
.cost-savings-main {
  min-width: 0;
}
.cost-savings-amount {
  font-family: var(--font-display);
  font-size: 2.1rem;
  font-weight: 800;
  line-height: 1.05;
  color: var(--primary);
  letter-spacing: -0.02em;
}
.cost-savings-sub {
  margin-top: 5px;
  color: var(--text-secondary);
  font-size: var(--text-base);
  max-width: 420px;
}
.cost-savings-compare {
  flex: none;
  min-width: 220px;
}
.cost-savings-line {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 7px 0;
  font-size: var(--text-base);
  color: var(--text-secondary);
  border-bottom: 1px solid var(--border);
}
.cost-savings-line:last-child {
  border-bottom: 0;
}
.cost-savings-line strong {
  color: var(--text);
  font-weight: 700;
}
.cost-savings-line--alt strong {
  color: var(--primary-dark);
}
@media (max-width: 640px) {
  .cost-savings-row {
    flex-direction: column;
    align-items: stretch;
  }
  .cost-savings-compare {
    min-width: 0;
  }
}

/* Unit economics — cost per outcome + send funnel */
.cost-eff-stats {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  margin: 12px 0 6px;
}
.cost-eff-stat {
  flex: 1;
  min-width: 130px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface);
}
.cost-eff-stat-val {
  font-size: 1.35rem;
  font-weight: 800;
  color: var(--text);
  line-height: 1.15;
}
.cost-eff-stat-label {
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--dim);
  font-weight: 700;
  margin-top: 2px;
}
.cost-funnel {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 8px;
}
.cost-funnel-stage {
  text-align: center;
  min-width: 72px;
}
.cost-funnel-n {
  font-size: var(--text-lg);
  font-weight: 800;
  color: var(--text);
}
.cost-funnel-label {
  font-size: var(--text-xs);
  color: var(--dim);
  font-weight: 600;
}
.cost-funnel-rate {
  color: var(--primary);
  font-weight: 700;
}
.cost-funnel-arrow {
  color: var(--dim);
  opacity: 0.6;
  font-size: 1rem;
}

.cost-trend-chart-wrap {
  position: relative;
  margin-top: 10px;
}
.cost-trend-svg {
  display: block;
  width: 100%;
  height: 160px;
  overflow: visible;
  cursor: crosshair;
}
.cost-trend-svg .ct-grid {
  stroke: var(--border);
  stroke-width: 1;
}
.cost-trend-svg .ct-area {
  fill: var(--primary);
  opacity: 0.1;
}
.cost-trend-svg .ct-line {
  fill: none;
  stroke: var(--primary);
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
}
.cost-trend-svg .ct-line--forecast {
  stroke: var(--dim);
  stroke-width: 2;
  stroke-dasharray: 4 4;
  fill: none;
  stroke-linecap: round;
}
.cost-trend-svg .ct-dot {
  fill: var(--primary);
  stroke: var(--surface);
  stroke-width: 2;
}
.cost-trend-svg .ct-dot--forecast {
  fill: var(--dim);
  stroke: var(--surface);
  stroke-width: 2;
}
.cost-trend-svg .ct-crosshair {
  stroke: var(--border-light);
  stroke-width: 1;
}
.cost-trend-svg .ct-hit {
  fill: transparent;
}
.cost-trend-svg .ct-axis-label {
  fill: var(--dim);
  font-size: 9px;
}
.cost-trend-svg .ct-end-label {
  fill: var(--text);
  font-size: 10px;
  font-weight: 700;
}
.cost-trend-tooltip {
  position: absolute;
  top: 0;
  pointer-events: none;
  transform: translate(-50%, -100%);
  background: var(--text);
  color: var(--surface);
  font-size: var(--text-xs);
  font-weight: 600;
  padding: 5px 9px;
  border-radius: var(--radius);
  white-space: nowrap;
  z-index: 5;
}
.cost-trend-tooltip strong {
  font-weight: 800;
}
.cost-trend-caption {
  font-size: var(--text-xs);
  color: var(--dim);
  margin-top: 8px;
}
.cost-trend-cta {
  display: block;
  margin-top: 10px;
  padding: 8px 12px;
  border-radius: 10px;
  font-size: var(--text-sm);
  font-weight: 700;
  text-decoration: none;
  background: color-mix(in srgb, var(--amber) 12%, var(--surface));
  color: var(--amber);
  border: 1px solid color-mix(in srgb, var(--amber) 35%, var(--border));
}
.cost-trend-cta:hover {
  border-color: var(--amber);
}

@media (max-width: 640px) {
  .cost-hero-row {
    flex-direction: column;
    align-items: stretch;
  }
  .cost-markup-badge {
    align-self: flex-start;
  }
  .cost-hero-amount {
    font-size: 2rem;
  }
  .cost-funnel-arrow {
    display: none;
  }
}

/* ── Audience builder (Broadcast composer) ──────────────────────────────────── */
.bcast-audience-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 8px;
}
.bcast-audience-empty {
  font-size: var(--text-sm);
  color: var(--dim);
  padding: 8px 0;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.bcast-aud-quick-alt {
  color: var(--dim);
}
/* Reach breakdown: four facts, four lines. Replaces a single 180-character sentence that carried
   the only answer to "who is being left out, and why". */
.bcast-reach {
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.bcast-reach-row {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
/* Qualified by .bcast-reach on purpose. `.bcast-audience-summary strong { color: var(--primary) }`
   below is the same specificity and comes later, so an unqualified rule loses the cascade and every
   figure renders green — including "300 removed by your exclusions", where green reads as reach. */
.bcast-reach .bcast-reach-row strong {
  font-family: var(--font-mono);
  font-weight: 700;
  color: var(--text);
  min-width: 3.5em;
  text-align: end;
}
.bcast-reach .bcast-reach-row em {
  font-style: normal;
  color: var(--dim);
  font-size: var(--text-xs);
}
.bcast-reach .bcast-reach-row.is-in strong {
  color: var(--primary);
}
.bcast-reach .bcast-reach-row.is-warn strong {
  color: var(--amber);
}
.bcast-picker-note {
  width: 100%;
  font-size: var(--text-xs);
  color: var(--dim);
  padding: 6px 2px 0;
}
.bcast-source-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.bcast-source-label {
  font-size: var(--text-base);
  font-weight: 600;
  flex: 1;
}
.bcast-source-count {
  font-size: var(--text-xs);
  color: var(--dim);
  white-space: nowrap;
}
.bcast-source-mode {
  max-width: 110px;
  font-size: var(--text-sm);
  padding: 4px 6px;
}
.bcast-source-remove {
  background: none;
  border: none;
  color: var(--dim);
  font-size: var(--text-lg);
  cursor: pointer;
  line-height: 1;
  padding: 0 4px;
}
.bcast-source-remove:hover {
  color: var(--red);
}
.bcast-audience-add {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-bottom: 8px;
}
.bcast-audience-summary {
  font-size: var(--text-sm);
  color: var(--dim);
  min-height: 1.1em;
}
.bcast-audience-summary strong {
  color: var(--primary);
}
.bcast-picker {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 10px;
  margin-bottom: 10px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}
.bcast-picker-empty {
  font-size: var(--text-sm);
  color: var(--dim);
}
.bcast-contact-q {
  width: 100%;
}
.bcast-contact-results {
  width: 100%;
  max-height: 180px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.bcast-contact-opt {
  padding: 6px 8px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-size: var(--text-sm);
}
.bcast-contact-opt:hover {
  background: var(--surface-2);
}
.bcast-contact-meta {
  color: var(--dim);
  font-size: var(--text-xs);
}
.bcast-contact-chosen {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.bcast-chip {
  background: var(--primary);
  color: var(--on-primary);
  border-radius: 999px;
  padding: 3px 10px;
  font-size: var(--text-xs);
  cursor: pointer;
}
.bcast-when-row {
  display: flex;
  gap: 14px;
  align-items: center;
  flex-wrap: wrap;
}
.bcast-when-opt {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-base);
  cursor: pointer;
}

/* ── Broadcast delivery funnel (expandable row) ─────────────────────────────── */
.bcast-row {
  border-bottom: 1px solid var(--border);
}
.bcast-row-detail {
  padding: 12px 10px 16px;
}
.bcast-funnel-loading {
  font-size: var(--text-sm);
  color: var(--dim);
  padding: 6px 0;
}
.bcast-funnel {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 12px;
}
.bcast-funnel-stage {
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.bcast-funnel-bar {
  height: 8px;
  background: var(--surface-2);
  border-radius: var(--radius-xs);
  overflow: hidden;
}
.bcast-funnel-fill {
  height: 100%;
  background: var(--primary);
  border-radius: var(--radius-xs);
  transition: width 0.3s;
}
.bcast-funnel-meta {
  display: flex;
  gap: 8px;
  align-items: baseline;
  font-size: var(--text-sm);
  color: var(--dim);
}
.bcast-funnel-meta strong {
  color: var(--text);
}
.bcast-funnel-pct {
  margin-inline-start: auto;
}
.bcast-funnel-footer {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  align-items: center;
  margin-bottom: 8px;
}
.bcast-funnel-ok {
  font-size: var(--text-sm);
  color: var(--dim);
}
.bcast-heatmap {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}
.bcast-heatmap-title {
  font-size: var(--text-sm);
  color: var(--dim);
  margin-bottom: 8px;
}
.bcast-recip-link {
  background: none;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 4px 10px;
  font-size: var(--text-xs);
  color: var(--primary);
  cursor: pointer;
}
.bcast-recip-link:hover {
  background: var(--surface-2);
}
.bcast-recip-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-height: 220px;
  overflow-y: auto;
}
.bcast-recip-row {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  font-size: var(--text-sm);
  padding: 5px 8px;
  border-radius: var(--radius-sm);
}
.bcast-recip-row:nth-child(odd) {
  background: var(--surface-2);
}
.bcast-recip-status {
  color: var(--dim);
  white-space: nowrap;
}

/* ── Broadcast composer: two-column form + sticky preview/summary rail ───────────
   The layout shell is .tpl-lib-layout / .tpl-lib-side (shared with the Templates and
   Flows libraries), so the 940px single-column collapse comes for free. Only the
   composer-specific pieces live here. */
.bcast-group + .bcast-group {
  margin-top: var(--space-5);
  padding-top: var(--space-5);
  border-top: 1px solid var(--border);
}
.bcast-group-title {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 700;
  color: var(--primary);
  margin-bottom: var(--space-4);
  padding-inline-start: 10px;
  border-inline-start: 3px solid var(--primary);
  line-height: 1.3;
}
.bcast-compose-actions {
  margin-top: var(--space-6);
  padding-top: var(--space-4);
  border-top: 1px solid var(--border);
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}
.bcast-draft-status {
  font-size: var(--text-xs);
  color: var(--dim);
  margin-inline-start: auto;
}
/* Summary rail rows reuse .overview-status-row; these are the composer-only extras. */
#bcast-summary .bcast-summary-value-mono {
  font-family: var(--font-mono);
}
.bcast-summary-note {
  font-size: var(--text-xs);
  color: var(--primary);
  margin: var(--space-1) 0 0;
  padding: 0 2px;
}
.bcast-summary-status {
  margin-top: var(--space-2);
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.bcast-summary-status.is-ready {
  color: var(--primary);
  font-weight: 600;
}
.bcast-summary-status ul {
  margin: var(--space-1) 0 0;
  padding-inline-start: 16px;
  list-style: disc;
}
.bcast-summary-status li {
  color: var(--amber);
  margin-bottom: 2px;
}
.bcast-test-send {
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--border);
}
.bcast-test-row {
  display: flex;
  gap: var(--space-2);
  align-items: center;
}
.bcast-test-row .form-input {
  flex: 1;
  min-width: 0;
}
.bcast-test-row .btn {
  white-space: nowrap;
}
.bcast-field-note {
  font-size: var(--text-xs);
  color: var(--dim);
  margin-top: var(--space-1);
  line-height: 1.5;
}
.bcast-quiet-row {
  display: flex;
  gap: var(--space-2);
  align-items: center;
  flex-wrap: wrap;
}
/* Condensed summary pinned to the top of the form on mobile, where the rail has dropped off the
   bottom of the page. A button: tapping it jumps to the full rail. Desktop keeps it hidden. */
.bcast-mobile-summary {
  display: none;
}
@media (max-width: 940px) {
  .bcast-mobile-summary {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    width: 100%;
    /* 56px is .dash-header's fixed height (same constant the layout, sidebar and inbox use):
       sticking at 0 pins the bar behind the header, where nobody can read it. */
    position: sticky;
    top: 56px;
    z-index: 5;
    margin: 0 0 var(--space-4);
    padding: var(--space-2) var(--space-3);
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    font: inherit;
    font-size: var(--text-sm);
    color: var(--text);
    text-align: start;
    cursor: pointer;
  }
  .bcast-mobile-summary[hidden] {
    display: none;
  }
  .bcast-mobile-summary .bcast-ms-state {
    margin-inline-start: auto;
    font-weight: 700;
    white-space: nowrap;
  }
  .bcast-mobile-summary .bcast-ms-state.is-ready {
    color: var(--primary);
  }
  .bcast-mobile-summary .bcast-ms-state.is-blocked {
    color: var(--amber);
  }
  .bcast-mobile-summary .bcast-ms-nums {
    font-family: var(--font-mono);
    color: var(--text-secondary);
  }
}
/* Template picker: the .tpl-bp-* card family (shared with the libraries), rendered as buttons. */
#bcast-template-picker {
  margin-top: 6px;
  max-height: 280px;
  overflow-y: auto;
  padding: 2px;
}
#bcast-template-picker .tpl-bp-card {
  display: block;
  width: 100%;
  text-align: start;
  font-family: inherit;
  color: var(--text);
}
#bcast-template-picker .tpl-bp-card:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 1px;
}

/* ── Team management (master) ───────────────────────────────────────────────── */
.team-add-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 8px;
  align-items: center;
}
.team-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.team-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  background: var(--surface-2, rgba(255, 255, 255, 0.03));
  border: 1px solid var(--border);
  border-radius: var(--radius);
  flex-wrap: wrap;
}
.team-row-main {
  flex: 1;
  min-width: 180px;
}
.team-row-title {
  font-size: 0.9rem;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
.team-row-meta {
  font-size: 0.76rem;
  color: var(--dim);
  margin-top: 2px;
}
.team-chip {
  font-size: var(--text-2xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  padding: 1px 7px;
  border: 1px solid var(--border);
  border-radius: 999px;
}
.team-row-actions {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.team-key-box {
  border: 1px solid var(--primary);
  border-radius: var(--radius);
  padding: 12px;
  background: var(--surface-2, rgba(255, 255, 255, 0.04));
}
.team-key-label {
  font-size: var(--text-sm);
  color: var(--dim);
  margin-bottom: 8px;
}
.team-key-row {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
}
.team-key-value {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  background: var(--bg);
  padding: 6px 10px;
  border-radius: var(--radius-sm);
  word-break: break-all;
  flex: 1;
  min-width: 240px;
}

/* ── Sub-tab navigation (Templates: My Templates/Library/Create; Flows: My Flows/Library/Create;
   Broadcast: Compose/Broadcasts). Shared visual language via combined selectors — kept as separate
   class names per feature (.tpl-* vs .flow-* vs .bcast-*) since each feature's JS queries its own
   classes unscoped; sharing class names would make tabs' tab-switching wiring toggle each other's
   panels. ── */
.tpl-subtabs,
.flow-subtabs,
.bcast-subtabs {
  display: flex;
  gap: 8px;
  margin: 16px 0 18px;
  border-bottom: 1px solid var(--border);
}
.tpl-subtab,
.flow-subtab,
.bcast-subtab {
  font-size: var(--text-base);
  font-weight: 700;
  padding: 8px 4px;
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  color: var(--dim);
  cursor: pointer;
}
.tpl-subtab.is-active,
.flow-subtab.is-active,
.bcast-subtab.is-active {
  color: var(--primary);
  border-bottom-color: var(--primary);
}
.tpl-subtab-panel,
.flow-subtab-panel,
.bcast-subtab-panel {
  display: none;
}
.tpl-subtab-panel.is-active,
.flow-subtab-panel.is-active,
.bcast-subtab-panel.is-active {
  display: block;
}
.tpl-status-pills,
.tpl-cat-pills,
.flow-status-pills,
.flow-cat-pills,
.bcast-status-pills {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
.tpl-status-pill,
.tpl-cat-pill,
.flow-status-pill,
.flow-cat-pill,
.bcast-status-pill {
  font-size: var(--text-sm);
  font-weight: 600;
  padding: 5px 12px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--dim);
  cursor: pointer;
}
.tpl-status-pill.is-active,
.tpl-cat-pill.is-active,
.flow-status-pill.is-active,
.flow-cat-pill.is-active,
.bcast-status-pill.is-active {
  background: var(--primary);
  color: var(--on-primary);
  border-color: var(--primary);
}

/* ── Template blueprint library (experiential picker + live WhatsApp preview) ── */
.tpl-lib-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: 18px;
  align-items: start;
}
@media (max-width: 940px) {
  .tpl-lib-layout {
    grid-template-columns: 1fr;
  }
  .tpl-lib-side {
    position: static;
  }
}
/* 56px is .dash-header's fixed height, +12px breathing room. At the old `top: 12px` the pinned
   rail slid 42px UNDER the fixed header once the page scrolled — measured on the Broadcast
   composer, and true of the Templates and Flows libraries that share this class. */
.tpl-lib-side {
  position: sticky;
  top: 68px;
}
.tpl-pack-title {
  font-size: var(--text-sm);
  font-weight: 700;
  margin: 14px 0 2px;
}
.tpl-pack-desc {
  font-size: var(--text-xs);
  color: var(--dim);
  margin-bottom: 8px;
}
/* Collapsible sets: library packs (.tpl-pack) and "Your templates" groups (.mtpl-group). */
details.tpl-pack,
details.mtpl-group {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  padding: 0 12px;
  margin-bottom: 8px;
}
.tpl-pack-summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 0;
  user-select: none;
}
.tpl-pack-summary::-webkit-details-marker {
  display: none;
}
.tpl-pack-summary::before {
  content: '▸';
  font-size: var(--text-2xs);
  color: var(--dim);
  transition: transform 0.15s;
}
details[open] > .tpl-pack-summary::before {
  transform: rotate(90deg);
}
.tpl-pack-summary .tpl-pack-title {
  margin: 0;
}
.tpl-pack-count {
  font-size: var(--text-xs);
  color: var(--dim);
  margin-inline-start: auto;
}
details.tpl-pack > .tpl-bp-grid,
details.mtpl-group > .overview-list-item {
  margin-bottom: 10px;
}
details.mtpl-group > .overview-list-item {
  border-top: 1px solid var(--border);
  padding-top: 10px;
  margin-bottom: 0;
  padding-bottom: 10px;
}
.tpl-bp-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(215px, 1fr));
  gap: 8px;
}
.tpl-bp-card {
  position: relative;
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 10px 12px;
  cursor: pointer;
  font-size: var(--text-sm);
  background: var(--surface);
  transition:
    border-color 0.15s,
    box-shadow 0.15s,
    transform 0.1s;
}
.tpl-bp-card:hover {
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.07);
  transform: translateY(-1px);
}
.tpl-bp-card.is-active {
  box-shadow: 0 0 0 2px var(--primary) inset;
}
.tpl-bp-card.is-selected {
  border-color: var(--primary);
  background: #f0fdf4;
}
.tpl-bp-head {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-bottom: 4px;
}
.tpl-bp-name {
  flex: 1;
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tpl-bp-cat {
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.03em;
  padding: 2px 7px;
  border-radius: 999px;
}
.tpl-bp-cat.MARKETING {
  background: var(--warn-bg);
  color: var(--warn-fg);
}
.tpl-bp-cat.UTILITY {
  background: var(--ok-bg);
  color: var(--primary-dark);
}
.tpl-bp-cat.AUTHENTICATION {
  background: var(--info-bg);
  color: var(--info-fg);
}
.tpl-bp-check {
  width: 18px;
  height: 18px;
  border-radius: 999px;
  border: 2px solid var(--border);
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  color: var(--on-primary);
  transition: all 0.12s;
}
.is-selected .tpl-bp-check {
  background: var(--primary);
  border-color: var(--primary);
}
.tpl-bp-snippet {
  color: var(--dim);
  font-size: var(--text-xs);
  line-height: 1.45;
  max-height: 42px;
  overflow: hidden;
}
.tpl-bp-caps {
  margin-top: 6px;
  display: flex;
  gap: 5px;
  flex-wrap: wrap;
}
.tpl-bp-cap {
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0 7px;
  font-size: 0.64rem;
  color: var(--dim);
}
/* Phone preview — the template rendered as the customer will see it */
.tpl-phone {
  background: linear-gradient(160deg, #e7f0e4 0%, #dbe7d6 100%);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 14px 12px 16px;
  min-height: 180px;
}
.tpl-phone-label {
  font-size: 0.64rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #64748b;
  margin-bottom: 10px;
  text-align: center;
}
/* The phone frame (.tpl-phone) is a fixed-appearance WhatsApp mock — its gradient never inverts,
   so the bubble and button pills on it stay light with dark text in both themes, same reasoning as
   --whatsapp-green in tokens.css. Using var(--surface) here left the bubble near-black on dark. */
.tpl-bubble {
  background: #ffffff;
  border-radius: var(--radius-xs) 12px 12px 12px;
  padding: 9px 11px 6px;
  font-size: var(--text-sm);
  color: #111b21;
  line-height: 1.5;
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.08);
  word-wrap: break-word;
}
.tpl-bubble-footer {
  color: #8696a0;
  font-size: var(--text-2xs);
  margin-top: 5px;
}
.tpl-bubble-time {
  text-align: end;
  color: #8696a0;
  font-size: 0.62rem;
  margin-top: 3px;
}
.tpl-btns {
  margin-top: 6px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.tpl-btn-pill {
  background: #ffffff;
  border-radius: var(--radius);
  text-align: center;
  padding: 7px 8px;
  font-size: var(--text-xs);
  font-weight: 600;
  color: #0a7cff;
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.08);
}
.tpl-slot-live {
  font-weight: 700;
}
.tpl-slot-missing {
  background: var(--warn-bg);
  color: var(--warn-fg);
  border-radius: var(--radius-xs);
  padding: 0 4px;
  font-size: var(--text-xs);
}
.tpl-var-sample {
  color: var(--primary-dark);
  font-style: italic;
}
.tpl-preview-why {
  font-size: var(--text-xs);
  color: var(--dim);
  margin-top: 10px;
  line-height: 1.5;
}
.tpl-preview-why strong {
  color: var(--text, #111827);
}

/* Library cards carrying live WABA status (already submitted → previewable, not re-submittable) */
.tpl-bp-card.is-submitted {
  opacity: 0.82;
  cursor: default;
}
.tpl-bp-card.is-submitted:hover {
  transform: none;
  box-shadow: none;
}
.tpl-bp-status {
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.03em;
  padding: 2px 7px;
  border-radius: 999px;
  white-space: nowrap;
}
.tpl-bp-status.st-approved {
  background: var(--ok-bg);
  color: var(--primary-dark);
}
.tpl-bp-status.st-pending {
  background: var(--warn-bg);
  color: var(--warn-fg);
}
.tpl-bp-status.st-rejected,
.tpl-bp-status.st-paused,
.tpl-bp-status.st-disabled {
  background: #fee2e2;
  color: var(--danger-fg-strong);
}
.tpl-brand-warn {
  background: var(--warn-bg);
  color: var(--warn-fg);
  border: 1px solid var(--warn-border);
  border-radius: 10px;
  padding: 10px 14px;
  font-size: var(--text-sm);
  line-height: 1.5;
  margin-bottom: 12px;
}

/* ════════════════════════════════════════════════════════════════════════════════
   Inbox Productivity — canned replies, labels, notes, resolve
   ════════════════════════════════════════════════════════════════════════════════ */

.canned-dropdown {
  position: absolute;
  bottom: 100%;
  left: 0;
  right: 0;
  max-height: 260px;
  overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.08);
  z-index: 100;
  padding: 4px;
}
.canned-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-size: var(--text-sm);
}
.canned-item.active {
  background: var(--surface-2);
}
.canned-item .canned-shortcut {
  font-weight: 700;
  color: var(--amber);
  white-space: nowrap;
  min-width: 50px;
}
.canned-item .canned-title {
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
}
.canned-item .canned-preview {
  color: var(--dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
}
.canned-cat {
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--dim);
  padding: 6px 10px 2px;
}

.canned-manager,
.labels-manager {
  padding: 12px 0;
}
.canned-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
}
.canned-header h3 {
  font-size: 1rem;
  font-weight: 700;
  margin: 0;
}
.canned-list,
.labels-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.canned-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 12px;
  background: var(--surface-2);
  border-radius: var(--radius);
}
.canned-row-info {
  display: flex;
  align-items: center;
  gap: 8px;
  overflow: hidden;
  flex: 1;
}
.canned-row-info .canned-shortcut {
  font-weight: 700;
  font-size: var(--text-xs);
  color: var(--accent);
}
.canned-row-info .canned-title {
  font-weight: 600;
  font-size: var(--text-sm);
}
.canned-row-info .canned-body {
  font-size: var(--text-xs);
  color: var(--dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.canned-row-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-2xs);
  color: var(--dim);
  flex: none;
}
.canned-form {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px;
  margin-bottom: 12px;
}
.canned-form h4 {
  margin: 0 0 10px;
  font-size: 0.9rem;
}
.canned-form label {
  display: block;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--dim);
  margin-bottom: 8px;
}
.canned-form input,
.canned-form textarea {
  width: 100%;
  margin-top: 4px;
}
.canned-form-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-top: 10px;
}

/* Its chips join .inbox2-meta-strip's row directly — the wrapper alone carries the layout now. */
.inbox2-thread-labels {
  display: contents;
}
.label-chip {
  display: inline-flex;
  align-items: center;
  font-size: var(--text-2xs);
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--label-color, var(--blue)) 15%, transparent);
  color: var(--label-color, var(--blue));
  border: 1px solid color-mix(in srgb, var(--label-color, var(--blue)) 30%, transparent);
}
.label-add-btn {
  font-size: var(--text-xs);
  font-weight: 700;
  color: var(--dim);
  background: none;
  border: 1px dashed var(--border);
  border-radius: 999px;
  padding: 1px 8px;
  cursor: pointer;
}
.label-add-btn:hover {
  color: var(--text);
  border-color: var(--text);
}
.label-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex: none;
}
.label-picker {
  position: absolute;
  bottom: 100%;
  right: 0;
  min-width: 200px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.08);
  z-index: 120;
  padding: 8px;
  font-size: var(--text-sm);
}
.label-picker-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-height: 180px;
  overflow-y: auto;
  margin-bottom: 8px;
}
.label-picker-item {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 6px;
  border-radius: var(--radius-xs);
  cursor: pointer;
}
.label-picker-item:hover {
  background: var(--surface-2);
}
.label-picker-item input[type='checkbox'] {
  width: 14px;
  height: 14px;
}
.label-picker-create {
  display: flex;
  gap: 6px;
}
.label-picker-create input {
  flex: 1;
  font-size: var(--text-sm);
}
.label-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  background: var(--surface-2);
  border-radius: var(--radius-sm);
}
.label-row .label-name {
  flex: 1;
  font-size: var(--text-sm);
  font-weight: 600;
}

.inbox2-compose.note-mode {
  background: color-mix(in srgb, var(--amber2) 8%, var(--surface));
  border-color: var(--amber2);
}
.inbox2-compose.note-mode #inbox-reply {
  background: transparent;
}
#inbox-note-toggle.active {
  background: var(--amber2);
  color: var(--on-primary);
  border-color: var(--amber2);
}

.msg.note {
  align-self: center;
  max-width: 80%;
  background: color-mix(in srgb, var(--amber2) 10%, var(--surface-2));
  border: 1px solid color-mix(in srgb, var(--amber2) 25%, transparent);
  border-radius: 10px;
  padding: 8px 12px;
  margin: 6px auto;
  text-align: center;
}
.msg.note .msg-note-badge {
  font-size: var(--text-2xs);
  font-weight: 700;
  color: var(--warn-fg);
  margin-bottom: 4px;
}
.msg.note .msg-body {
  font-size: var(--text-sm);
  color: var(--text);
  text-align: start;
}
.msg.note .msg-meta {
  font-size: var(--text-2xs);
  color: var(--dim);
  text-align: end;
}
.msg-mention {
  font-weight: 700;
  color: var(--primary);
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  border-radius: 4px;
  padding: 0 3px;
}

/* Pre-send advisories in the template picker (cap risk, open window, consent state). */
.tpl-advice {
  margin-bottom: 8px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.tpl-advice-row {
  font-size: var(--text-xs);
  border-radius: 6px;
  padding: 6px 8px;
}
.tpl-advice-row[data-tone='warn'] {
  background: color-mix(in srgb, var(--warn, var(--amber)) 12%, transparent);
  color: var(--warn-fg, #92400e);
}
.tpl-advice-row[data-tone='info'] {
  background: color-mix(in srgb, var(--primary) 10%, transparent);
  color: var(--text);
}

.tpl-ai-variants {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.tpl-ai-variant {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 14px;
  cursor: pointer;
  transition:
    border-color 0.15s,
    box-shadow 0.15s;
}
.tpl-ai-variant:hover {
  border-color: var(--primary);
  box-shadow: 0 0 0 1px var(--primary);
}
.tpl-ai-variant-body {
  font-size: var(--text-sm);
  line-height: 1.5;
  margin-bottom: 8px;
  white-space: pre-wrap;
}
.tpl-ai-variant-pick {
  font-size: var(--text-xs);
  font-weight: 700;
  color: var(--primary);
}
.tpl-ai-loading {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--text-sm);
  color: var(--dim);
  padding: 12px 0;
}
.tpl-ai-error {
  font-size: var(--text-sm);
  color: var(--danger-fg-strong, #b91c1c);
  padding: 8px 0;
}
@keyframes tpl-ai-flash {
  0% {
    box-shadow: 0 0 0 3px rgba(5, 150, 105, 0.3);
  }
  100% {
    box-shadow: none;
  }
}
.tpl-ai-picked {
  animation: tpl-ai-flash 0.6s ease-out;
}

/* @mention autocomplete above the composer. Anchored to the composer rather than the caret:
   the textarea is only three rows tall, so a list above it is never far from what you typed. */
.inbox-mention-pop {
  border: 1px solid var(--border);
  border-radius: 10px;
  margin: 0 16px 6px;
  background: var(--surface);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.08);
  overflow: hidden;
  max-height: 200px;
  overflow-y: auto;
}
.inbox-mention-pop .mention-item {
  display: flex;
  align-items: baseline;
  gap: 8px;
  width: 100%;
}
.inbox-mention-pop .mention-item-name {
  font-size: var(--text-xs);
  color: var(--dim);
}

.btn-success {
  background: var(--primary);
  color: var(--on-primary);
  border: 1px solid var(--primary);
}
.btn-success:hover {
  background: var(--primary);
}

.inbox-all-caught-up {
  text-align: center;
  padding: 40px 20px;
  color: var(--dim);
}
.inbox-all-caught-up .caught-up-icon {
  font-size: 2rem;
  margin-bottom: 8px;
}
.inbox-all-caught-up .caught-up-text {
  font-size: var(--text-base);
  font-weight: 600;
}

/* ── Optimistic send bubble ── */
.msg.pending {
  opacity: 0.7;
}
.msg.pending .msg-tick {
  font-size: var(--text-xs);
}

/* ── Reusable skeleton shimmer ── */
@keyframes skel-shimmer {
  0% {
    background-position: -400px 0;
  }
  100% {
    background-position: 400px 0;
  }
}
.skel-line {
  height: 14px;
  border-radius: var(--radius-xs);
  margin-bottom: 8px;
  background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface-3) 50%, var(--surface-2) 75%);
  background-size: 800px 100%;
  animation: skel-shimmer 1.5s infinite linear;
}
.skel-line.w60 {
  width: 60%;
}
.skel-line.w80 {
  width: 80%;
}
.skel-line.w40 {
  width: 40%;
}
.skel-block {
  height: 48px;
  border-radius: var(--radius-sm);
  margin-bottom: 10px;
  background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface-3) 50%, var(--surface-2) 75%);
  background-size: 800px 100%;
  animation: skel-shimmer 1.5s infinite linear;
}

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ─── WhatsApp connect: per-field guidance + verification verdicts ───────────────────────────
   Three opaque Meta ids failing as one blob is why the connect form goes uncompleted. Each field
   states where its value lives and reports its own result after verification. */
.wa-field-hint {
  display: block;
  font-size: var(--text-xs);
  color: var(--dim);
  margin-top: 5px;
  line-height: 1.5;
}
.wa-field-hint code {
  font-size: var(--text-xs);
  background: var(--surface-2);
  padding: 1px 4px;
  border-radius: 3px;
}
.wa-field-hint.is-ok {
  color: var(--primary);
  font-weight: 600;
}
.wa-field-hint.is-error {
  color: var(--danger-fg);
  font-weight: 600;
}
.form-input.is-ok {
  border-color: var(--primary);
}
/* Error state mirrors the :focus ring (0 0 0 3px glow) so a flagged field reads as a state, not a
   stray brown border. Both themes via the tokens. */
.form-input.is-error,
.form-input.is-error:focus {
  border-color: var(--red);
  box-shadow: 0 0 0 3px var(--red-glow);
}
#wa-connect-summary {
  font-size: var(--text-sm);
  padding: 10px 12px;
  border-radius: var(--radius);
  margin: 10px 0;
  line-height: 1.5;
}
#wa-connect-summary.is-ok {
  background: var(--ok-bg);
  color: #065f46;
}
#wa-connect-summary.is-error {
  background: #fffbeb;
  color: var(--warn-fg);
}

/* Guided connect wizard */
.wa-wizard {
  display: flex;
  flex-direction: column;
  gap: 0;
}
.wa-wizard-step {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin-bottom: -1px;
  overflow: hidden;
}
.wa-wizard-step:first-child {
  border-radius: var(--radius) 8px 0 0;
}
.wa-wizard-step:last-of-type {
  border-radius: 0 0 8px 8px;
}
.wa-wizard-step-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  cursor: pointer;
  background: var(--surface-2);
}
.wa-wizard-step-head:hover {
  background: var(--bg-alt);
}
.wa-wizard-step-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--dim);
  color: var(--bg);
  font-size: var(--text-xs);
  font-weight: 700;
  flex-shrink: 0;
}
.wa-wizard-step[data-wizard-active='true'] .wa-wizard-step-num {
  background: var(--primary);
}
.wa-wizard-step-title {
  font-weight: 600;
  font-size: var(--text-base);
  flex: 1;
}
.wa-wizard-step-status {
  font-size: var(--text-xs);
  font-weight: 600;
}
.wa-wizard-step-body {
  display: none;
  padding: 10px 14px 14px;
  border-top: 1px solid var(--border);
}
.wa-wizard-step[data-wizard-active='true'] .wa-wizard-step-body {
  display: block;
}
.wa-wizard-guide {
  background: var(--surface-2);
  border-radius: var(--radius-sm);
  padding: 10px 12px;
  font-size: var(--text-sm);
  line-height: 1.6;
}
.wa-wizard-guide-title {
  font-weight: 700;
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--dim);
  margin-bottom: 4px;
}
.wa-wizard-steps-list {
  margin: 0;
  padding-inline-start: 1.3em;
}
.wa-wizard-steps-list li {
  margin-bottom: 2px;
}
.wa-wizard-steps-list code {
  font-size: var(--text-xs);
  background: var(--bg);
  padding: 1px 4px;
  border-radius: 3px;
}
.wa-wizard-gotcha {
  margin-top: 8px;
  padding: 8px 10px;
  border-radius: 5px;
  background: #fffbeb;
  color: var(--warn-fg);
  font-size: var(--text-sm);
  line-height: 1.5;
  border-inline-start: 3px solid var(--amber);
}

/* ══════════════════════════════════════════════════════════════════════════════
   Portfolio / Extensions — entity engine UI
   Uses the same tokens, type scale, and component patterns as the rest of the
   dashboard: .overview-panel for sections, .stat-card sizing for metrics,
   .form-* for inputs, .uidlg-* for dialogs.
   ══════════════════════════════════════════════════════════════════════════════ */

/* ── Banner alerts (WABA gate, flow provisioning) ── */
.pf-banner {
  padding: 12px 16px;
  border-radius: var(--radius);
  margin-bottom: 16px;
  font-size: var(--text-base);
  display: flex;
  align-items: center;
  gap: 10px;
}
.pf-banner-icon {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  stroke: currentColor;
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.pf-banner-body {
  flex: 1;
  min-width: 0;
}
.pf-banner-title {
  font-weight: 600;
  font-size: var(--text-base);
  margin-bottom: 2px;
}
.pf-banner-desc {
  font-size: var(--text-sm);
  line-height: 1.45;
}
.pf-banner-action {
  flex-shrink: 0;
}
.pf-banner.is-error {
  background: color-mix(in srgb, var(--red) 8%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--red) 20%, var(--border));
  color: var(--red);
}
.pf-banner.is-warn {
  background: color-mix(in srgb, var(--amber) 8%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--amber) 20%, var(--border));
  color: var(--amber);
}
.pf-banner.is-info {
  background: color-mix(in srgb, var(--primary) 6%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--primary) 15%, var(--border));
  color: var(--primary);
}

/* ── Entity grid cards ── */
.pf-card {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  padding: 16px;
  cursor: pointer;
  transition: var(--transition);
}
.pf-card:hover {
  border-color: var(--border-light);
  background: var(--surface-2);
  transform: translateY(-1px);
}
.pf-card-head {
  display: flex;
  justify-content: space-between;
  align-items: start;
  gap: 8px;
}
.pf-card-title {
  font-family: var(--font-display);
  font-size: var(--text-md);
  font-weight: 700;
  color: var(--text);
  display: flex;
  align-items: center;
  gap: 6px;
}
.pf-card-meta {
  font-size: var(--text-xs);
  color: var(--dim);
  margin-top: 2px;
}
.pf-card-stat {
  font-size: var(--text-xs);
  color: var(--dim);
  white-space: nowrap;
}
.pf-card-chips {
  margin-top: 8px;
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
}

/* ── Reusable chip / tag ── */
.pf-chip {
  display: inline-block;
  padding: 2px 8px;
  font-size: var(--text-xs);
  font-weight: 500;
  border-radius: var(--radius-xs);
  background: var(--surface-2);
  color: var(--dim);
}
.pf-chip.is-green {
  background: color-mix(in srgb, var(--primary) 12%, var(--surface));
  color: var(--primary);
}
.pf-chip.is-amber {
  background: color-mix(in srgb, var(--amber) 12%, var(--surface));
  color: var(--amber);
}
.pf-chip.is-red {
  background: color-mix(in srgb, var(--red) 12%, var(--surface));
  color: var(--red);
}
.pf-chip.is-blue {
  background: color-mix(in srgb, var(--blue) 12%, var(--surface));
  color: var(--blue);
}

/* ── Detail view: sections as overview-panels ── */
.pf-detail-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  margin-top: 16px;
}
.pf-detail-grid .pf-section.is-full {
  grid-column: 1 / -1;
}
.pf-section {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  padding: 14px;
}
.pf-section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}
.pf-section-title {
  font-family: var(--font-display);
  font-size: var(--text-md);
  font-weight: 700;
  color: var(--text);
}
.pf-section-empty {
  font-size: var(--text-sm);
  color: var(--dim);
  padding: 8px 0;
}

/* ── Entity detail header ── */
.pf-entity-header {
  display: flex;
  justify-content: space-between;
  align-items: start;
  flex-wrap: wrap;
  gap: 12px;
}
.pf-entity-name {
  font-family: var(--font-display);
  font-size: 1.3rem;
  font-weight: 700;
  margin: 0;
}
.pf-entity-meta {
  font-size: var(--text-sm);
  color: var(--dim);
  margin-top: 2px;
}

/* ── Scorecard stats row ── */
.pf-scorecard {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
  gap: 10px;
}
.pf-stat {
  text-align: center;
  padding: 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
}
.pf-stat-value {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: 700;
  color: var(--text);
}
.pf-stat-label {
  font-size: var(--text-2xs);
  color: var(--dim);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-top: 2px;
}

/* ── List rows (contacts, records, interventions, captures) ── */
.pf-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 0;
  border-bottom: 1px solid var(--border);
  gap: 8px;
}
.pf-row:last-child {
  border-bottom: none;
}
.pf-row-main {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1;
  min-width: 0;
}
.pf-row-name {
  font-size: var(--text-base);
  font-weight: 500;
  color: var(--text);
}
.pf-row-sub {
  font-size: var(--text-xs);
  color: var(--dim);
}
.pf-row-actions {
  display: flex;
  gap: 4px;
  flex-shrink: 0;
}
.pf-row-actions .btn {
  font-size: var(--text-xs);
  padding: 3px 8px;
}
.pf-row-time {
  font-size: var(--text-xs);
  color: var(--dim);
  white-space: nowrap;
}

/* ── Narrative block ── */
.pf-narrative {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 12px;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  white-space: pre-wrap;
  line-height: 1.55;
}

/* ── Dialog (uses <dialog> but styled to match .uidlg pattern) ── */
dialog.pf-dialog {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  padding: 22px;
  max-width: 460px;
  width: 92%;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.25);
}
dialog.pf-dialog::backdrop {
  background: rgba(17, 24, 39, 0.45);
}
.pf-dialog-title {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 700;
  color: var(--text);
  margin-bottom: 16px;
}
.pf-dialog-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 20px;
}

/* ── Contact search results ── */
.pf-search-results {
  max-height: 200px;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.pf-search-row {
  padding: 8px 12px;
  cursor: pointer;
  border-bottom: 1px solid var(--border);
  font-size: var(--text-base);
  display: flex;
  justify-content: space-between;
  align-items: center;
  transition: background 0.1s;
}
.pf-search-row:last-child {
  border-bottom: none;
}
.pf-search-row:hover {
  background: var(--surface-2);
}
.pf-search-row-name {
  font-weight: 500;
}
.pf-search-row-phone {
  font-size: var(--text-xs);
  color: var(--dim);
}
.pf-selected {
  padding: 8px 12px;
  background: color-mix(in srgb, var(--primary) 8%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--primary) 20%, var(--border));
  border-radius: var(--radius-sm);
  font-size: var(--text-base);
}

/* ── Extensions catalog ── */
.ext-card {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  padding: 16px;
  transition: var(--transition);
}
.ext-card:hover {
  border-color: var(--border-light);
}
.ext-card.is-active {
  border-color: var(--primary);
}
.ext-card.is-coming {
  opacity: 0.55;
}
.ext-card-head {
  display: flex;
  justify-content: space-between;
  align-items: start;
  gap: 8px;
}
.ext-card-icon {
  font-size: 1.5rem;
  flex-shrink: 0;
}
.ext-card-name {
  font-family: var(--font-display);
  font-size: var(--text-md);
  font-weight: 700;
}
.ext-card-desc {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin: 6px 0;
  line-height: 1.45;
}
.ext-card-roles {
  font-size: var(--text-xs);
  color: var(--dim);
}
.ext-catalog-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 12px;
}
.ext-includes-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 10px;
  padding: 4px 0;
}
.ext-includes-item {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 12px;
  background: var(--surface);
}
.ext-includes-item strong {
  font-size: var(--text-base);
}
.ext-includes-item p {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin: 4px 0 0;
  line-height: 1.4;
}

/* ── Portfolio responsive ── */
@media (max-width: 768px) {
  .pf-detail-grid {
    grid-template-columns: 1fr;
  }
  .pf-detail-grid .pf-section.is-full {
    grid-column: 1;
  }
  .ext-catalog-grid {
    grid-template-columns: 1fr;
  }
  .ext-includes-grid {
    grid-template-columns: 1fr 1fr;
  }
}

/* ── PWA Install Banner ── */
.pwa-install-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  background: color-mix(in srgb, var(--primary) 12%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--primary) 35%, var(--border));
  border-radius: var(--radius-lg);
  padding: 12px 18px;
  margin-bottom: 20px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
  backdrop-filter: blur(8px);
  animation: pwaSlideDown 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}

@keyframes pwaSlideDown {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.pwa-banner-content {
  display: flex;
  align-items: center;
  gap: 14px;
  min-width: 0;
}

.pwa-banner-icon {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border-radius: 10px;
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
  overflow: hidden;
}

.pwa-banner-icon img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.pwa-banner-text {
  min-width: 0;
}

.pwa-banner-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--text-md);
  color: var(--text);
  line-height: 1.2;
}

.pwa-banner-sub {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.pwa-banner-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.pwa-close-btn {
  font-size: 1.3rem;
  line-height: 1;
  padding: 4px 8px;
  color: var(--dim);
  background: transparent;
  border: none;
  cursor: pointer;
  border-radius: var(--radius-sm);
  transition:
    color 0.15s,
    background 0.15s;
}

.pwa-close-btn:hover {
  color: var(--text);
  background: var(--surface-2);
}

@media (max-width: 640px) {
  .pwa-install-banner {
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
    padding: 12px 14px;
  }
  .pwa-banner-sub {
    white-space: normal;
  }
  .pwa-banner-actions {
    justify-content: flex-end;
    width: 100%;
  }
  .pwa-banner-actions #pwa-install-btn {
    flex: 1;
  }
}

/* ── Health alerts (Settings → Alerts) — surfaces health_events the backend already tracked but
   nothing read: webhook auto-disabled, sequence step-limit exceeded, etc. Tone follows severity. ─── */
.ov-alert-row[data-tone='danger'] {
  background: var(--danger-bg);
  border-color: var(--danger-border);
}
.ov-alert-row[data-tone='danger'] .overview-list-title {
  color: var(--danger-fg-strong);
}
.ov-alert-row[data-tone='warn'] {
  background: var(--warn-bg);
  border-color: var(--warn-border);
}
.ov-alert-row[data-tone='warn'] .overview-list-title {
  color: var(--warn-fg);
}
/* .overview-list-meta is shared with short fixed-format lines ("3 unread · 2h ago") and is
   nowrap+ellipsis on purpose there. An alert's `reasons` is a full, variable-length sentence —
   ellipsis would hide part of why it fired, and combined with this row's default min-width:auto
   as a flex/grid item, an unbroken nowrap sentence floors the row's own box at its full text
   width, blowing it out past the panel on narrow screens regardless of the container being
   correctly constrained (min-content floor inflating a flex item past its track — see
   project_responsive_defect_shapes shape #3). Wrap instead of truncating, and let the row shrink. */
.ov-alert-row {
  min-width: 0;
}
.ov-alert-row .overview-list-meta {
  white-space: normal;
  overflow-wrap: break-word;
}

/* ═════════════════════════════════════════════════════════════════════════════════
   Dashboard: mobile (global)

   Deliberately the LAST block in this file. dashboard.css has grown by appending, so a
   component's base rules are scattered throughout it; a media query placed next to the
   component it modifies loses to any equally-specific rule further down. Anchoring the
   responsive layer at the end makes "does this win?" answerable without reading 3000
   lines. Add new mobile rules HERE, not beside the component.

   Scope: below 760px only. Nothing in this block affects desktop.
   ═════════════════════════════════════════════════════════════════════════════════ */

/* ── Sequence graph view (docs/VISUAL_FLOW_BUILDER_TODO_2026-08-04.md Phase 4) ──────────────────
   Drawflow's own CSS (css/vendor/drawflow.min.css) supplies layout mechanics only — absolute node
   positioning, connection-path drawing; everything visible here overrides its cosmetic defaults
   (cyan nodes, red selection) so nodes read as this design system, not the library's demo theme.
   Read-only: editor_mode='view' in sequence-graph.js already blocks drag/delete/rewire, so nothing
   here needs a disabled/pointer-events treatment on top of that. */
.seq-graph-container {
  height: 560px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-2);
  overflow: hidden;
}
.seq-graph-container .drawflow-node {
  background: transparent;
  border: none;
  padding: 0;
  width: 220px;
  min-height: 0;
}
.seq-graph-container .drawflow-node:hover {
  cursor: default;
}
.seq-graph-container .drawflow-node .input,
.seq-graph-container .drawflow-node .output {
  background: var(--surface-2);
  border-color: var(--border-light);
  cursor: default;
}
.seq-graph-container .connection .main-path {
  stroke: var(--border-light);
  stroke-width: 2px;
}
.seq-graph-node-wrap {
  display: flex;
}
.seq-graph-node {
  width: 100%;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface);
  box-shadow: var(--shadow-card);
  padding: 10px 12px;
  font-family: var(--font-body);
}
.seq-graph-node-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 4px;
}
.seq-graph-node-num {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  color: var(--dim);
  min-width: 16px;
}
.seq-graph-node-kind {
  font-size: var(--text-2xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  padding: 1px 6px;
  border-radius: 3px;
  border: 1px solid var(--border);
}
.seq-graph-node-body {
  font-size: var(--text-sm);
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.seq-graph-node-delay {
  font-size: var(--text-2xs);
  color: var(--dim);
  margin-top: 4px;
}
.seq-graph-node-routes {
  margin-top: 6px;
  border-top: 1px dashed var(--border);
  padding-top: 6px;
}
.seq-graph-node-route {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  color: var(--text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.seq-node-template .seq-graph-node-kind {
  color: var(--primary);
  border-color: var(--primary);
  background: var(--primary-glow);
}
.seq-node-flow .seq-graph-node-kind {
  color: var(--blue);
  border-color: var(--blue);
  background: var(--info-bg);
}
.seq-node-payment .seq-graph-node-kind {
  color: var(--amber);
  border-color: var(--amber);
  background: var(--warn-bg);
}
.seq-node-wait .seq-graph-node-kind {
  color: var(--dim);
  border-color: var(--border-light);
  background: var(--surface-2);
}
.seq-node-branch .seq-graph-node-kind {
  color: var(--accent);
  border-color: var(--accent);
  background: var(--accent-glow);
}

@media (max-width: 760px) {
  /* ── Text entry: 16px or iOS zooms ──
     Safari zooms the page whenever a focused text field computes under 16px, and does not
     zoom back out. Every text-entry surface in the dashboard was 12.3-13.5px, so tapping
     any field left the user zoomed in with no way back. Checkboxes and radios are exempt:
     they take no text and never trigger the zoom. */
  .form-input,
  .form-select,
  .form-textarea,
  .search-input {
    font-size: 16px;
  }

  /* ── Touch targets ──
     44px is the smallest reliably-hittable target. .btn covers most of the dashboard;
     the components below own their own sizing and need naming explicitly. */
  .btn {
    min-height: 44px;
  }
  /* .btn-sm is a DESKTOP density affordance. On a phone there is no such thing as a button
     too unimportant to hit, so it gets the same target as any other. */
  .btn-sm {
    min-height: 44px;
  }
  .nav-item {
    min-height: 44px;
  }
  .ov-vital-pill {
    min-height: 44px;
  }

  /* ── Segmented sub-navigation, unified ──
     The same control existed five times under five class names, all 27-33px tall:
     tpl-subtab / flow-subtab / bcast-subtab / connect-subtab (underline family) and
     trust-tab-btn / cost-range-btn (pill family). They stay visually distinct because
     they read differently, but sizing and overflow behaviour are now one decision.
     Scrolling sideways beats wrapping: a wrapped row silently eats vertical space that
     the content below needs. */
  .tpl-subtabs,
  .flow-subtabs,
  .bcast-subtabs,
  .connect-subtabs,
  .trust-tabs,
  .cost-range-tabs,
  .settings-cat-tabs {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .tpl-subtabs::-webkit-scrollbar,
  .flow-subtabs::-webkit-scrollbar,
  .bcast-subtabs::-webkit-scrollbar,
  .connect-subtabs::-webkit-scrollbar,
  .trust-tabs::-webkit-scrollbar,
  .cost-range-tabs::-webkit-scrollbar,
  .settings-cat-tabs::-webkit-scrollbar {
    display: none;
  }

  .tpl-subtab,
  .flow-subtab,
  .bcast-subtab,
  .connect-subtab,
  .trust-tab-btn,
  .cost-range-btn,
  .settings-cat-btn,
  .knw-cat-btn {
    flex: 0 0 auto;
    min-height: 44px;
    white-space: nowrap;
  }

  /* ── Nav drawer scrim ──
     Dims the content behind the open drawer and gives it a tap-anywhere dismiss. Sits
     under the sidebar (60) and under the header (100), above everything else. */
  .sidebar-scrim {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 55;
    background: rgba(17, 24, 39, 0.45);
    opacity: 0;
    visibility: hidden;
    transition:
      opacity 0.3s ease,
      visibility 0.3s ease;
  }
  .dash-sidebar.open ~ .sidebar-scrim {
    opacity: 1;
    visibility: visible;
  }

  /* ── Action center: secondary panel ──
     .ac-layout had no responsive rules at all. The panel was width:300px flex-shrink:0
     next to a flex:1 main column with 48px of padding, inside a 343px content area, so
     opening it left the main column ~43px wide. Same fixed-side-panel mistake the inbox
     had; same fix, an overlay sheet rather than a column. */
  .ac-layout {
    position: relative;
  }
  .ac-secondary-panel {
    position: absolute;
    inset: 0;
    width: auto;
    z-index: 30;
    border-inline-start: 0;
    min-height: 0;
    transition:
      transform 0.25s ease,
      visibility 0.25s;
    transform: translateX(100%);
    visibility: hidden;
    overflow: visible;
  }
  .ac-secondary-panel.open {
    width: auto;
    transform: none;
    visibility: visible;
  }
  .ac-main {
    padding: 16px 16px 0;
  }
  .ac-snooze-row {
    flex-wrap: wrap;
  }
  .ac-snooze-btn,
  .ac-pin-btn {
    min-height: 44px;
  }

  /* ── Status pills ──
     These are tappable filters in the template/flow lists, not read-only badges, so they
     get a full target like everything else. Their rows scroll sideways (above), so the
     extra width costs nothing. */
  .tpl-status-pill,
  .flow-status-pill {
    min-height: 44px;
  }

  /* ── Settings: rail becomes a scrolling pill row ──
     A 208px fixed rail beside content has no room at 375px, so the two-column grid
     collapses and the same buttons re-render as the horizontal pill strip (same markup,
     same data-cat contract, so the switcher in ui/settings.js is unaffected). Sticky is
     dropped too: a sticky nav on a short viewport eats the content it navigates to. */
  /* minmax(0,…) not 1fr: a bare `1fr` track is `minmax(auto, 1fr)`, and `auto` floors the track at
     its content's min-content width. The rail's buttons are white-space:nowrap, so that floor is
     the sum of all six — which blew the whole grid (and the page) out to 500px at a 375px
     viewport. The zero minimum lets the track actually shrink and the row scroll instead. */
  .set-layout {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
  }
  .set-nav {
    position: static;
    flex-direction: row;
    gap: 6px;
    margin-bottom: 20px;
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .set-nav::-webkit-scrollbar {
    display: none;
  }
  .set-nav .settings-cat-btn,
  .set-nav .knw-cat-btn,
  .set-nav .eh-cat-btn {
    width: auto;
    flex: 0 0 auto;
    min-height: 44px;
    white-space: nowrap;
    border: 1px solid var(--border);
    border-radius: 99px;
    padding: 7px 14px;
  }
  .set-nav .settings-cat-btn.active,
  .set-nav .knw-cat-btn.active,
  .set-nav .eh-cat-btn.active {
    border-color: var(--primary);
  }

  /* A label + its control cannot sit side by side at this width without the control
     collapsing to a sliver — every row stacks, matching .set-row.is-stacked. */
  .set-row {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
  }
  .set-row-control {
    width: 100%;
  }
  /* ...except a switch, which is small enough to stay on the label's line. Pulling it
     back up beside the label keeps toggle-heavy cards from doubling in height. */
  .set-row:has(> .set-row-control > .switch) {
    flex-direction: row;
    align-items: center;
  }
  .set-row:has(> .set-row-control > .switch) .set-row-control {
    width: auto;
  }
}

/* ── Knowledge sources (Settings → "What the assistant reads") ───────────────────────────────
   Appended at the end deliberately: this file grew by appending, so a rule placed beside its
   component loses to any equally-specific rule further down. */
.knw-lede {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  line-height: 1.6;
  margin: 0 0 10px;
}
.knw-total {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--dim);
  margin-bottom: 10px;
}
/* A flat amber wash reads as one alarm. Three of them stacked (unanswered terms, capability gaps,
   review queue) read as the same alarm three times, which is noise rather than a signal — the
   amber stopped meaning anything by the second box. A left-border accent on the ordinary card
   background says "this needs a look" without drowning whatever sits inside it in yellow. */
.knw-warn {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  background: var(--surface);
  border: 1px solid var(--border);
  border-inline-start: 3px solid var(--amber);
  border-radius: 8px;
  padding: 10px 12px 10px 14px;
  margin: 0 0 12px;
  line-height: 1.5;
}
/* The coverage cross-reference: topics the assistant can send but cannot explain. Lives inside a
   .knw-warn, so it inherits the warning colours rather than defining its own. */
/* The review queue itself is not a warning — it is the day-to-day workspace this whole panel
   exists for, and dressing it in the same amber as an actual gap buried the one section somebody
   is meant to open every day under the two they open rarely. Title + description only; the rows
   below carry their own card chrome via .knw-rows. */
.knw-review-head {
  margin: 0 0 10px;
}
.knw-review-head + .knw-rows {
  margin-bottom: 12px;
}
/* AI commands: a command switched off stays visible but reads as inactive, because hiding it would
   make "why can it not do that" unanswerable from this screen. */
.knw-row-off {
  opacity: 0.55;
}
.knw-aud {
  width: auto;
  padding: 4px 8px;
  font-size: var(--text-xs);
}
.knw-toggle {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: var(--text-xs);
  color: var(--text-secondary);
}
.knw-gaps {
  margin: 6px 0 4px;
  padding-inline-start: 18px;
}
.knw-gaps li {
  margin-bottom: 4px;
  line-height: 1.5;
}
.knw-rows {
  display: flex;
  flex-direction: column;
  gap: 1px;
  background: var(--border);
  border-radius: 8px;
  overflow: hidden;
}
.knw-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  background: var(--surface);
}
/* An empty source is the actionable thing on this screen, so it is marked rather than left to be
   inferred from a zero somebody scrolls past. */
.knw-row-empty {
  background: var(--warn-bg);
}
.knw-row-main {
  flex: 1;
  min-width: 0;
}
.knw-row-title {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text);
}
.knw-row-help {
  font-size: var(--text-xs);
  color: var(--dim);
  line-height: 1.5;
}
/* A handoff/answer entry carries a title, a paragraph or two, sometimes a textarea, always a
   verdict pair — .knw-row's default is a single horizontal line (built for the compact Sources
   list) and stacking that much into it is what produced the "card inside a card" look. This
   modifier keeps the same list chrome (.knw-rows' shared background/border-radius/divider) but
   lays its own content out top-to-bottom instead. */
.knw-row-review {
  flex-direction: column;
  align-items: stretch;
  gap: 8px;
  padding: 14px;
}
/* align-items:stretch above is for the textarea/buttons, which want the full row width — but it
   also stretches the kind badge (a plain flex-item <span>) into a full-width bar instead of the
   compact pill every other badge on this screen is. */
.knw-row-review > .knw-badge {
  align-self: flex-start;
}
/* The kind pill (Handed to a person / Answered by the model / Answered from your own words) reuses
   .knw-badge's shape with a tone, the same [data-tone] convention already used for status pills
   elsewhere (e.g. .ov-vital-pill) — so a reviewer can tell "still needs a fix" from "already
   resolved, just confirm" without reading the paragraph underneath first. */
.knw-badge[data-tone='warn'] {
  color: #b45309;
  background: var(--amber-glow);
}
.knw-badge[data-tone='good'] {
  color: var(--primary-dark);
  background: var(--primary-glow);
}
/* Verdict buttons on a reviewable decision. Two of them, on purpose: "right" and "wrong" is the
   whole judgement a reviewer can make quickly, and a third option is how a review queue becomes a
   form nobody fills in. Placed with its siblings rather than appended at the end of the file
   because it is a base rule, not a media-query override. */
.knw-verdicts {
  display: flex;
  gap: 8px;
  margin-top: 8px;
}
.knw-row-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: none;
}
/* A rule the workspace cannot change reads as a STATEMENT, not as a disabled dropdown. Sized to sit
   on the same baseline as the <select> beside it in the rows that do have a choice, so the column
   still scans as a column. Base rule, placed with its siblings — see the note above. */
.knw-row-fixed {
  font-size: var(--text-xs);
  color: var(--text-secondary);
  background: var(--bg-alt);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 6px 10px;
  white-space: nowrap;
}
.knw-badge {
  font-size: var(--text-xs);
  color: var(--text-secondary);
  background: var(--bg-alt);
  border-radius: 999px;
  padding: 2px 8px;
  white-space: nowrap;
}
.knw-count {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--dim);
  white-space: nowrap;
}
.knw-warn-title,
.knw-section-title {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text);
  margin-bottom: 4px;
}
.knw-actions {
  display: flex;
  gap: 8px;
  margin: 8px 0 6px;
}
/* The answer box had no styling at all — a bare <textarea> next to two bare <button>s, so it
   rendered in raw browser chrome beside every other, properly themed control on this screen. Same
   base as the rest of the app's inputs, plus resize since its 2-row default is rarely enough. */
.knw-answer {
  resize: vertical;
}
/* Paths read like code, not prose — the pages list is the one .form-input on this tab that wants
   the monospace treatment .form-textarea doesn't give it (it's a bare <textarea class="form-input">,
   not a .form-textarea, so it needs this explicitly). */
#knw-pages {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
}

@media (max-width: 768px) {
  .knw-row {
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
  }
  .knw-row-meta {
    width: 100%;
    justify-content: space-between;
    flex-wrap: wrap;
    row-gap: 4px;
  }
  .knw-actions {
    flex-direction: column;
  }
  .knw-actions .btn {
    width: 100%;
  }
  /* .knw-row's own mobile override (above) would otherwise win on specificity-tie and shrink the
     answer box/verdict buttons to content width instead of filling the row. */
  .knw-row-review {
    align-items: stretch;
    gap: 8px;
  }
  .knw-row-review .knw-verdicts .btn {
    flex: 1;
  }
}
.knw-found-head {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin: 12px 0 6px;
  line-height: 1.5;
}
.knw-found-list {
  display: flex;
  flex-direction: column;
  gap: 1px;
  background: var(--border);
  border-radius: 8px;
  overflow: hidden;
  max-height: 320px;
  overflow-y: auto;
}
.knw-found-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  background: var(--surface);
  cursor: pointer;
}
.knw-found-row:hover {
  background: var(--bg-alt);
}
.knw-found-path {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--text);
  flex: none;
}
.knw-found-why {
  font-size: var(--text-xs);
  color: var(--dim);
  margin-inline-start: auto;
  text-align: end;
}

@media (max-width: 768px) {
  .knw-found-row {
    flex-wrap: wrap;
  }
  .knw-found-why {
    margin-inline-start: 26px;
    text-align: start;
    width: 100%;
  }
}
.knw-used {
  font-size: var(--text-xs);
  color: var(--green2);
  white-space: nowrap;
}
.knw-updated {
  font-size: var(--text-xs);
  color: var(--dim);
  white-space: nowrap;
}
.knw-updated.knw-behind {
  color: var(--warning);
}
.knw-link {
  font-size: var(--text-xs);
  color: var(--green);
  text-decoration: underline;
  white-space: nowrap;
}

@media (max-width: 760px) {
  #knowledge-trial-hint {
    flex-wrap: wrap;
  }
}

/* ============================================================================
   RTL — right-to-left languages (Arabic, Hebrew, Urdu, …)
   ----------------------------------------------------------------------------
   The margin / padding / border / text-align rules above were converted to
   CSS logical properties, which flip automatically with `dir`. This block
   handles what stays PHYSICAL by nature: fixed-position anchors, popover
   sides, and a few directional radii. Driven by `<html dir="rtl">`, set from
   the LocaleContext in js/dashboard/locale.js.

   Icon mirroring (chevrons, back arrows) is deliberately NOT here — most SVGs
   in this file are non-directional and a blanket scaleX(-1) breaks them. That
   is Phase 13 (RTL enablement) in docs/LOCALE_FOUNDATION_TODO_2026-08-30.md.
   ========================================================================= */
/* .dash-main / .status-rail borders are already `border-inline-*` (auto-flip). .dash-main's
   margins are logical too, so it needs no rule here — only the physically-positioned things do.
   Every selector below was checked against the real markup / CSS. */
[dir='rtl'] .dash-sidebar {
  left: auto;
  right: 0;
}
[dir='rtl'] .status-rail {
  left: 0;
  right: auto;
}

/* These two are position:fixed with physical left/right pinned to the two rail widths (l.2435/2446). */
[dir='rtl'] .action-bar,
[dir='rtl'] .workflow-footer {
  left: var(--status-rail-width);
  right: var(--sidebar-width);
}

/* Popovers / dropdowns anchored to a physical edge → anchor to the other one. */
[dir='rtl'] .header-menu,
[dir='rtl'] .inbox-more-dropdown,
[dir='rtl'] .inbox-attach-dropdown,
[dir='rtl'] .label-picker,
[dir='rtl'] .msg-react-picker {
  right: auto;
  left: 0;
}

[dir='rtl'] .msg.in .msg-react-picker {
  left: auto;
  right: 0;
}

/* Contact / detail pane slides in from the leading (now right) edge on narrow screens. */
[dir='rtl'] .inbox2-detail {
  right: auto;
  left: 0;
  box-shadow: 4px 0 16px rgba(0, 0, 0, 0.12);
}

/* Directional toggles: side + which corners are rounded both mirror (l.2455/2501). */
[dir='rtl'] .ac-panel-toggle {
  left: auto;
  right: -6px;
  border-radius: 5px 0 0 5px;
}
[dir='rtl'] .later-toggle-btn {
  right: auto;
  left: 0;
  border-radius: 0 5px 5px 0;
}

/* Timeline rail + dots run down the leading edge (l.971/973). */
[dir='rtl'] .timeline::before {
  left: auto;
  right: 8px;
}
[dir='rtl'] .timeline-dot {
  left: auto;
  right: -24px;
}

/* Floating action button and toasts follow the leading edge (l.1675/2900). */
[dir='rtl'] .toast-container {
  right: auto;
  left: 20px;
}
[dir='rtl'] .kcm-fab {
  right: auto;
  left: 18px;
}
@media (max-width: 480px) {
  [dir='rtl'] .kcm-fab {
    left: 12px;
  }
}

/* Toggle switch knob travels the other way — the control is `.switch` with a `::before` knob (l.1814). */
[dir='rtl'] .switch::before {
  left: auto;
  right: 2px;
}
[dir='rtl'] .switch:checked::before {
  transform: translateX(-17px);
}

/* The account-menu chevron is the one meaningfully directional icon in the shell. */
[dir='rtl'] .dd-chevron {
  transform: scaleX(-1);
}

/* Experience Navigator slides in from the inline-end edge (l.1972, position:fixed right:14px). */
[dir='rtl'] .experience-panel {
  right: auto;
  left: 14px;
}

/* The off-canvas sidebar is pinned to the inline-end (right) edge in RTL (l.4187), so on mobile it
 * must hide by sliding OFF the right (+100%), not off the left. The switch knob's travel is already
 * mirrored at l.4224. Toast/thread slide directions are left as-is — cosmetic, and `toast-in` has a
 * pre-existing duplicate-keyframe collision that a directional fix here would only entangle with. */
@media (max-width: 768px) {
  [dir='rtl'] .dash-sidebar {
    transform: translateX(100%);
  }
  [dir='rtl'] .dash-sidebar.open {
    transform: translateX(0);
  }
}

/* ── Carousel builder + carousel broadcast composer ──────────────────────────────────────────────
 * These two surfaces shipped styled entirely by inline attributes, which meant no responsive
 * behaviour at all: the editor's media-picker row and the preview's card strip were both laid out
 * for a desktop width and never tested below it. Classes here so the mobile block underneath has
 * something to hook, per the file's own "new responsive rules go at the end" rule. */
/* Broadcast carousel card editor: a grid of the actual pictures, not a stack of filename rows.
   Deliberately built from .media-grid/.media-card/.media-thumb so it reads as the same component
   family as the media picker and the product library. */
.bcast-cards-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}
.bcast-cards-title {
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: 0.02em;
}
.bcast-cards-hint {
  font-size: var(--text-xs);
  color: var(--dim);
}
.bcast-card-grid {
  grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
  gap: 10px;
}
.bcast-card-tile {
  position: relative;
  cursor: pointer;
  transition:
    border-color 0.15s,
    box-shadow 0.15s;
}
.bcast-card-tile:hover {
  border-color: var(--primary);
}
.bcast-card-tile:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}
.bcast-card-tile.is-active {
  border-color: var(--primary);
  box-shadow: 0 0 0 2px var(--primary);
}
.bcast-card-tile .media-thumb {
  height: 96px;
}
/* An empty slot should read as "something goes here", not as a broken image. */
.bcast-card-empty {
  border-bottom: 1px dashed var(--border);
  color: var(--dim);
  font-size: 1.8rem;
}
.bcast-card-chip {
  align-self: flex-start;
  margin: 0 10px 4px;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--dim);
  font-size: var(--text-xs);
  font-weight: 600;
}
.bcast-card-actions {
  gap: 4px;
  padding: 0 6px 8px;
}
.bcast-card-actions .btn {
  padding: 2px 7px;
  font-size: var(--text-xs);
  line-height: 1.5;
}
.bcast-card-actions .btn:disabled {
  opacity: 0.35;
  cursor: default;
}
.bcast-card-detail {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px;
  margin-top: 12px;
  background: var(--surface);
}
.bcast-card-detail-head {
  font-size: var(--text-sm);
  font-weight: 600;
  margin-bottom: 8px;
}

.mtpl-carousel-card {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 10px;
  margin-bottom: 8px;
}
.mtpl-carousel-card-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
}
.mtpl-carousel-media-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
  flex-wrap: wrap;
}
/* One shared button slot: type select, label, and whichever value field that type needs. */
.mtpl-carousel-btn-row {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
/* The "how your customer sees it" strip: horizontally swipeable, exactly like the real thing. */
.tpl-carousel-strip {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding: 4px 2px 8px;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
}
.tpl-carousel-strip > .tpl-bubble {
  min-width: 180px;
  max-width: 180px;
  flex-shrink: 0;
  scroll-snap-align: start;
}

@media (max-width: 768px) {
  /* Stack the card heading above its Remove button so a long localized "Quitar tarjeta 3" label
   * cannot squeeze the heading to one character per line. */
  .mtpl-carousel-card-head {
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
  }
  /* Media buttons go full-width and stack — at 360px the two side-by-side pickers plus the
   * filename chip overflowed the card horizontally. */
  .mtpl-carousel-media-row {
    flex-direction: column;
    align-items: stretch;
  }
  .mtpl-carousel-media-row .btn {
    width: 100%;
    justify-content: center;
  }
  /* Stacked, or the type select and two value fields wrap into unreadable slivers on a phone. */
  .mtpl-carousel-btn-row {
    flex-direction: column;
    align-items: stretch;
  }
  /* Preview cards take most of the viewport so the caption is legible while still showing the
   * next card's edge — the affordance that tells a first-time operator it scrolls. */
  .tpl-carousel-strip > .tpl-bubble {
    min-width: 72vw;
    max-width: 72vw;
  }
}

/* Reserved-vocabulary warning in the template builder. Advisory tone on purpose: this never blocks
   a submission, it tells somebody that a word they chose already means something to the system. Uses
   the existing --warn-* trio, which carries its own dark-mode values in tokens.css. */
.mtpl-vocab-warning {
  margin: 12px 0;
  padding: 10px 12px;
  border: 1px solid var(--warn-border);
  border-radius: var(--radius);
  background: var(--warn-bg);
  color: var(--warn-fg);
  font-size: 13px;
  line-height: 1.5;
}
.mtpl-vocab-warning strong {
  font-weight: 600;
}
.mtpl-vocab-warning + .mtpl-vocab-warning {
  margin-top: -4px;
}

/* Fill-down control in a resolve-grid header. Quiet by default and only obvious on hover: it sits
   in a header a shop reads far more often than it clicks, and a column heading that shouts is a
   column heading nobody reads. */
.grid-fill {
  background: none;
  border: 1px solid transparent;
  border-radius: 4px;
  color: var(--dim);
  cursor: pointer;
  font: inherit;
  line-height: 1;
  padding: 0 4px;
}
.grid-fill:hover,
.grid-fill:focus-visible {
  background: var(--surface-2);
  border-color: var(--border);
  color: var(--text);
}

/* ── Resolve-grid columns ──────────────────────────────────────────────────────────────────────
   Name had no width while every other column had a fixed one, so it absorbed the remainder: 42px
   in a 918px table, rendering "Gold chain 22K" as "G". It is the field the vision pass writes and
   the shop corrects, in the screen the pricing feature exists for.

   So the short columns get a MAX rather than a fixed width, and Name takes what is left with a
   floor of its own. `table-layout: auto` lets the browser do the distributing; pinning Name to a
   px value would only move the squeeze to whichever column was pinned next. */
#product-grid {
  table-layout: auto;
}
#product-grid .col-code {
  width: 9%;
  min-width: 76px;
}
#product-grid .col-name {
  min-width: 180px;
}
#product-grid .col-price {
  width: 10%;
  min-width: 86px;
}
#product-grid .col-mode {
  width: 12%;
  min-width: 108px;
}
#product-grid .col-num {
  width: 8%;
  min-width: 72px;
}
#product-grid .col-cat {
  width: 10%;
  min-width: 92px;
}
#product-grid .col-brand {
  width: 9%;
  min-width: 88px;
}
/* A 13-digit barcode, readable without scrolling inside the cell: measured at 1280px, 118px showed
   eleven digits of thirteen. */
#product-grid .col-gtin {
  width: 12%;
  min-width: 148px;
}
#product-grid .col-status {
  width: 11%;
  min-width: 92px;
}

/* Below a laptop the eleven columns cannot all fit, and squeezing them is how Name became 42px in
   the first place. The table keeps its real width and scrolls inside its own box, so the page
   never scrolls sideways and the columns stay readable. */
@media (max-width: 1100px) {
  #product-grid-wrap .table-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  #product-grid {
    /* 940 + the brand and barcode columns (88 + 148). */
    min-width: 1176px;
  }
}

/* ── Product card: one object, one affordance ───────────────────────────────────────────────────
   Appended rather than filed beside `.media-card` at line 3143, for the reason CLAUDE.md gives:
   this stylesheet grew by appending, so a rule placed next to its component loses to any equally
   specific rule further down. These have to win.

   What they replace: four equal buttons per card, wrapped onto three lines, taking 104 of a 272px
   card. The card is the button now; everything else is behind one overflow that appears on hover
   and on focus. */
.product-card {
  position: relative;
  cursor: pointer;
  transition:
    box-shadow 0.16s ease,
    border-color 0.16s ease,
    transform 0.16s ease;
}
.product-card:hover {
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.1);
  border-color: var(--primary);
  transform: translateY(-1px);
}
.product-card:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
  border-color: var(--primary);
}
/* Dimmed, not hidden. A sold-out piece is still the shop's, and still has to be findable to restore. */
.product-card.is-hidden {
  opacity: 0.62;
}
.product-card.is-hidden:hover {
  opacity: 1;
}

/* `.media-card` clips its children so the photograph inherits the rounded corner. The overflow menu
   has to escape that box, so the clipping moves to the photograph's own wrapper AND the menu is
   rendered as a sibling of that wrapper rather than inside it — see the note in product-library.js.
   Moving the clip alone is not enough: a child of the clipping box is still clipped. */
.product-card {
  overflow: visible;
}
.product-card-media {
  position: relative;
  border-radius: 9px 9px 0 0;
  overflow: hidden;
}

.product-card-badge {
  position: absolute;
  inset-inline-start: 8px;
  inset-block-start: 8px;
  font-size: var(--text-2xs);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.66);
  color: #fff;
}

.card-menu-btn {
  position: absolute;
  inset-inline-end: 6px;
  inset-block-start: 6px;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  border: none;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  cursor: pointer;
  /* Hidden until wanted, so eleven products are eleven photographs rather than eleven controls.
     `visibility` as well as opacity, or it stays in the tab order while invisible. */
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 0.14s ease,
    visibility 0.14s ease;
}
.card-menu-btn svg {
  width: 16px;
  height: 16px;
  fill: currentColor;
}
.product-card:hover .card-menu-btn,
.product-card:focus-within .card-menu-btn,
.card-menu-btn[aria-expanded='true'] {
  opacity: 1;
  visibility: visible;
}
.card-menu-btn:hover {
  background: rgba(0, 0, 0, 0.78);
}
.card-menu-btn:focus-visible {
  outline: 2px solid #fff;
  outline-offset: -3px;
  opacity: 1;
  visibility: visible;
}
/* A touch screen has no hover to reveal it with, so it is simply always there. */
@media (hover: none) {
  .card-menu-btn {
    opacity: 1;
    visibility: visible;
  }
}

/* Borrows `.header-menu`'s surface and `.account-menu-item`'s rows: one menu language on this
   dashboard, not a second one invented for cards. */
.card-menu {
  top: 38px;
  inset-inline-end: 6px;
  min-width: 172px;
}
.account-menu-item-danger {
  color: var(--red, #dc2626);
}
.account-menu-item-danger:hover {
  background: var(--danger-bg);
  color: var(--red, #dc2626);
}

/* ── Choosing several products ──────────────────────────────────────────────────────────────────
   A tick on the photograph, shown on hover and focus and on every card once one is ticked, and a
   bar that says how many are chosen and what can be done to them. See the note on `selection` in
   product-library.js for why it is a mode and why there is no bulk price change in it. */
.card-select {
  position: absolute;
  inset-inline-start: 6px;
  inset-block-start: 6px;
  z-index: 2;
  width: 24px;
  height: 24px;
  padding: 0;
  display: grid;
  place-items: center;
  border: 2px solid #fff;
  border-radius: 6px;
  background: rgba(0, 0, 0, 0.35);
  color: transparent;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 0.14s ease,
    visibility 0.14s ease,
    background 0.14s ease;
}
.card-select svg {
  width: 14px;
  height: 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.product-card:hover .card-select,
.product-card:focus-within .card-select,
.card-select:focus-visible,
#product-library-list.is-selecting .card-select {
  opacity: 1;
  visibility: visible;
}
.card-select[aria-checked='true'] {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
}
.card-select:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 1px;
}
.product-card.is-selected {
  border-color: var(--primary);
  box-shadow: 0 0 0 2px var(--primary);
}
.product-card.is-selected.is-hidden {
  opacity: 1;
}
/* In selection mode a per-card menu is noise: the bar holds the actions. */
#product-library-list.is-selecting .card-menu-btn {
  display: none;
}
/* The tick owns the top corner, so the sold-out badge moves to the bottom one. */
.product-card-badge {
  inset-block-start: auto;
  inset-block-end: 8px;
}
/* A long press selects; the browser's own image menu must not open over it. */
.product-card img {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}

.selection-bar {
  /* 56px is .dash-header's height, plus the banner when one is on screen: the same offset the
     layout uses, or the bar would stick behind the header where nobody can read it. */
  position: sticky;
  top: calc(56px + var(--banner-h, 0px) + 8px);
  z-index: 6;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 10px;
  margin: 0 0 12px;
  padding: 8px 12px;
  background: var(--surface);
  border: 1px solid var(--primary);
  border-radius: 10px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.1);
}
/* `display: flex` above beats the `hidden` attribute, which is only a UA-stylesheet display:none.
   Without this the empty bar drew a green outline above every catalogue with nothing selected:
   shipped in 145f0792, and missed by a check that read the attribute instead of the rendering. */
.selection-bar[hidden] {
  display: none;
}
.selection-count {
  font-weight: 700;
  color: var(--text);
}
.selection-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-inline-start: auto;
}
.selection-link {
  border: none;
  background: none;
  padding: 2px 0;
  cursor: pointer;
  font: inherit;
  font-size: var(--text-sm);
  color: var(--primary);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.selection-link:hover {
  color: var(--primary-dark);
}
.selection-danger {
  color: var(--red, #dc2626);
}
.selection-danger:hover {
  border-color: var(--red, #dc2626);
}
@media (hover: none) {
  /* Touch: the bar docks to the bottom of the screen, where a thumb is. Fixed, not sticky: the bar
     sits at the TOP of the list, so a bottom-sticky one scrolls away upward and never docks. It
     is hidden with its tab, because a fixed element still vanishes with a display:none ancestor. */
  .selection-bar {
    position: fixed;
    top: auto;
    bottom: 12px;
    inset-inline: 12px;
    z-index: 60;
  }
  #product-library-list.is-selecting {
    padding-bottom: 120px;
  }
}
/* Shift-click extends a range of products, not a highlight of their names. Measured: without this
   a range tick painted every name between the two cards in the browser's text-selection blue. */
#product-library-list.is-selecting .product-card {
  -webkit-user-select: none;
  user-select: none;
}
@media (max-width: 640px) {
  /* Two rows, not four. The count, Select all and Clear share the first; the actions scroll
     sideways on the second. Wrapped, the bar measured 166px tall, a fifth of a phone screen. */
  .selection-actions {
    order: 3;
    margin-inline-start: 0;
    width: 100%;
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    padding-bottom: 2px;
  }
  .selection-actions::-webkit-scrollbar {
    display: none;
  }
  .selection-actions .btn {
    flex: 0 0 auto;
  }
}

/* ── One object, one affordance, in every list (ui/item-menu.js) ───────────────────────────────
   The item opens on click; its other actions sit behind one quiet ⋯ that shows on hover and focus,
   and always on touch. Same menu surface as the account menu: one menu language, not one per list. */
.item-row {
  cursor: pointer;
}
.item-row:hover {
  background: var(--surface-2);
}
.item-open {
  border: none;
  background: none;
  padding: 0;
  margin: 0;
  font: inherit;
  color: inherit;
  text-align: start;
  cursor: pointer;
  max-width: 100%;
}
.item-open:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}
.item-open:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
  border-radius: 4px;
}
.item-menu {
  position: relative;
  display: inline-flex;
  flex: 0 0 auto;
}
.item-menu-btn {
  width: 30px;
  height: 30px;
  padding: 0;
  display: grid;
  place-items: center;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: var(--dim);
  cursor: pointer;
  /* Hidden until wanted, as on the product cards; `visibility` too, or it stays in the tab order
     while invisible. */
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 0.14s ease,
    visibility 0.14s ease,
    background 0.14s ease;
}
.item-menu-btn svg {
  width: 16px;
  height: 16px;
  fill: currentColor;
}
/* `.eh-row` is here because the reveal keys on the ROW class, and a list that uses this menu from
   a row of its own name gets a ⋯ that is hidden at opacity 0 forever: the EventsHub attendee list
   shipped with Send pass, Assign and Log need reachable only by keyboard, and only on desktop
   (touch shows the button unconditionally below, which is why it looked fine on a phone). Adding
   a row class here is the cost of the reveal living on the parent; the alternative, giving every
   such row `.item-row`, also gives it `cursor: pointer`, which promises a row that opens. */
.item-row:hover .item-menu-btn,
.item-row:focus-within .item-menu-btn,
.eh-row:hover .item-menu-btn,
.eh-row:focus-within .item-menu-btn,
.item-menu-btn:focus-visible,
.item-menu-btn[aria-expanded='true'] {
  opacity: 1;
  visibility: visible;
}
.item-menu-btn:hover,
.item-menu-btn[aria-expanded='true'] {
  background: var(--surface-3, var(--surface-2));
  color: var(--text);
}
.item-menu-btn:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 1px;
}
.item-menu-panel {
  top: calc(100% + 4px);
  right: auto;
  inset-inline-end: 0;
  min-width: 190px;
}
@media (hover: none) {
  .item-menu-btn {
    opacity: 1;
    visibility: visible;
  }
}
.page-card-name .item-open {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: bottom;
  font-weight: inherit;
}
.overview-list-title .item-open {
  font-weight: inherit;
}

/* The rate board's trend line: yesterday's rate and the move since, under each rate. One colour
   for both directions on purpose: a rising gold rate is not bad news for a jeweller, nor a falling
   one good, so the arrow says which way and nothing says whether to worry. */
.board-trend {
  display: block;
  margin-top: 3px;
  font-size: var(--text-2xs);
  color: var(--dim);
  font-variant-numeric: tabular-nums;
}

/* A field that holds several lines, drawn as a short table: a piece's stones, one row per kind and
   quality. Cells wrap on a narrow screen rather than scrolling sideways, each keeping its own label,
   so a row on a phone reads as a small card of labelled fields. */
.lines-editor {
  display: grid;
  gap: 8px;
}
.lines-editor-rows {
  display: grid;
  gap: 8px;
}
.lines-editor-rows:empty {
  display: none;
}
.line-row {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 8px;
  align-items: flex-end;
  padding: 8px 36px 8px 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm, 6px);
  background: var(--surface-2, transparent);
}
.line-cell {
  display: grid;
  gap: 2px;
  flex: 1 1 90px;
  min-width: 0;
}
.line-cell-enum {
  flex-basis: 140px;
}
.line-cell-text {
  flex-basis: 110px;
}
.line-cell-label {
  font-size: var(--text-2xs);
  color: var(--dim);
  white-space: nowrap;
}
.line-cell .form-input {
  width: 100%;
  min-width: 0;
  font-variant-numeric: tabular-nums;
}
.line-remove {
  position: absolute;
  top: 6px;
  inset-inline-end: 6px;
  width: 26px;
  height: 26px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: var(--dim);
  cursor: pointer;
  font-size: 18px;
  line-height: 1;
}
.line-remove:hover {
  background: var(--surface-3, var(--surface-2));
  color: var(--red, var(--text));
}
.line-remove:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 1px;
}
.lines-editor [data-line-add] {
  justify-self: start;
}

/* "916 has no rate. Price it as [22K]" under the rate board, and the aliases already set, each with
   its own remove. Wraps to one per line on a phone. */
.board-aliases {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 16px;
  margin: 0 0 12px;
  font-size: var(--text-sm);
}
.board-alias {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.board-alias .form-input {
  width: auto;
  min-width: 110px;
}
.board-alias-set {
  position: relative;
  padding: 4px 34px 4px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
}
.board-alias-set .line-remove {
  top: 50%;
  transform: translateY(-50%);
  inset-inline-end: 4px;
}

/* Import column mapping on a phone: field, then the column chosen, then the example, stacked.
   Side by side at 375px the dropdown shrank to its arrow, so the one thing this screen exists to
   show (which column feeds which field) was the one thing that could not be read. The label cells
   carry an inline width for desktop, hence the !important. Contacts and products share the shape. */
@media (max-width: 640px) {
  #connect-import-map-body tr,
  #product-csv-map-body tr {
    display: grid;
    grid-template-columns: 1fr;
    gap: 4px;
    padding: 8px 0;
    border-bottom: 1px solid var(--border);
  }
  #connect-import-map-body td,
  #product-csv-map-body td {
    display: block;
    width: auto !important;
    padding: 0;
  }
}

/* Unsupported-content banner in a thread: offered only after 3 unreadable messages in a row. */
.msg-unsupported {
  font-style: italic;
  color: var(--dim);
}
.msg-spam-banner {
  align-self: stretch;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 8px 0;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius, 8px);
  background: var(--surface);
  font-size: 0.82rem;
}
.msg-spam-banner .btn {
  flex: none;
}

/* Media picker (mpc-*): kept at the end of the file so no later base rule outranks it.
   Tablet: the fixed 400px list column left the preview a sliver, so it narrows first. */
@media (max-width: 1000px) {
  .mpc-shell {
    grid-template-columns: 1fr 320px;
  }
}
@media (max-width: 740px) {
  .mpc-shell {
    grid-template-columns: 1fr;
  }
  .mpc-preview {
    display: none;
  }
  .mpc-modal {
    height: 96vh;
  }
  .modal-xl {
    max-height: 96vh;
  }
}

/* Document preview. Fills the pane so the browser's own PDF viewer has room for its page
   navigation; it is never shown below 740px because .mpc-preview itself is hidden there. */
.mpc-preview-pdf {
  width: 100%;
  height: 100%;
  min-height: 320px;
  border: none;
  border-radius: var(--radius);
  background: var(--surface);
  display: block;
}

/* ── A data table on a phone scrolls itself, not the page ──────────────────────────────────────
 *
 * `.data-table` sets `width:100%`, which on a table is a floor rather than a ceiling: once the
 * columns cannot fit, the table grows past its container and takes the document with it. Measured
 * on the EventsHub tab at 375px: a 4-column table rendered 346px inside a 313px panel, pushing
 * `document.scrollWidth` to 377px against a 375px viewport, so the whole page scrolled sideways.
 *
 * The container scrolls instead. `:has()` is used rather than a wrapper element because the markup
 * is built in JS at two call sites (ui/eventshub.js, ui/commerce.js) and a fix that needs every
 * caller to remember a wrapper is a fix that lapses at the third one. `:has()` already appears
 * four times in this file, so it is not a new dependency.
 *
 * The tighter cells come first so most tables simply fit and never show a scrollbar; the container
 * is the guarantee for the long agent name that would otherwise reintroduce the overflow. */
@media (max-width: 640px) {
  :where(div, section, td):has(> .data-table) {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  .data-table th,
  .data-table td {
    padding-inline: 8px;
  }
  .data-table th {
    letter-spacing: 0.04em;
  }
}

/* ——— EventsHub tab (ui/eventshub.js) ———————————————————————————————————————————————————————
 *
 * These exist because the tab shipped emitting seven class names that no stylesheet defined:
 * `.list-row`, `.list-row-title`, `.list-row-sub`, `.num`, `.pill`, `.pill-ok`, `.pill-warn`.
 * Nothing errored — the attendee list simply rendered as a stack of unstyled text, and the event
 * editor collapsed into overlapping labels because its inline `flex-direction:column` had no
 * `display:flex` to apply to. A missing rule fails silently and looks like a layout bug.
 *
 * Renamed to the `eh-` prefix every other feature here uses (bcast-row, canned-row, cost-row), so
 * the rules are obviously owned by this tab and go when it goes. The two badges reuse the shared
 * `.badge` component rather than the parallel `.pill` the tab had invented; `ok`/`warn` are
 * deliberately generic modifiers, since the existing set is commerce-specific (badge-paid,
 * badge-fulfilled) and the next tab that needs a green tick should not add an eighth one. */
/* A row inside `.eh-list` is a line in a list, not a card on a board. The first cut gave every row
   its own border and sat them inside a panel that also has one, so an attendee list read as a
   stack of boxes inside a box — two frames around one thing. Site visits, Orders and Products all
   use a flat divided list for the same shape, so this matches them: no border of its own, a hairline
   between rows, and the panel supplying the only frame. */
.eh-list {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.eh-list:empty {
  display: none;
}
.eh-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 14px;
  background: var(--surface);
}
.eh-list > .eh-row + .eh-row {
  border-top: 1px solid var(--border);
}
.eh-list > .eh-row:hover {
  background: var(--surface-2);
}
/* Outside a list — the editor and the QR card use `.eh-row` as a plain framed block — it keeps a
   border of its own, since there is no list to supply one. */
.eh-row:not(.eh-list > *) {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.eh-row:not(.eh-list > *) + .eh-row {
  margin-top: 8px;
}

/* "What attendees receive": each message drawn as the chat bubble it arrives as, business side. */
.eh-msg {
  margin: 0 0 14px;
}
.eh-msg.is-off {
  opacity: 0.5;
}
.eh-msg-when {
  font-size: 12px;
  color: var(--text-secondary);
  margin: 0 0 4px;
}
.eh-msg-kind {
  font-family: var(--font-mono);
  font-size: 11px;
}
.eh-bubble {
  white-space: pre-line;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 4px 14px 14px 14px;
  padding: 10px 12px;
  font-size: 14px;
  line-height: 1.45;
  max-width: 440px;
}
.eh-bubble-btn {
  margin: 10px -12px -10px;
  padding: 8px 12px;
  border-top: 1px solid var(--border);
  text-align: center;
  color: var(--primary);
  font-weight: 600;
}
.eh-msg-estimate {
  margin-top: 6px;
  padding: 12px 14px;
  border: 1px dashed var(--border);
  border-radius: var(--radius-sm);
}
.eh-msg-estimate:empty {
  display: none;
}
.eh-fb-avg {
  font-size: 15px;
}
.eh-team-form {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  margin-top: 8px;
}
.eh-team-form .form-input {
  flex: 1 1 160px;
  min-width: 0;
}
/* Doubled class: `.eh-row-sub { display: block }` further down sits on the same elements and would
   otherwise win, running each label into its number ("Poster41 registered"). */
.eh-row-sub.eh-reach-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 3px 0;
  border-bottom: 1px solid var(--border);
}
.eh-reach-row span:last-child {
  text-align: end;
  white-space: nowrap;
}
.eh-team-activity {
  max-height: 220px;
  overflow: auto;
  display: grid;
  gap: 4px;
}
.eh-fb-avg strong {
  font-family: var(--font-display);
  font-size: 34px;
}
.eh-fb-bar {
  display: grid;
  grid-template-columns: 34px 1fr 28px;
  gap: 8px;
  align-items: center;
  font-size: 13px;
  margin: 3px 0;
}
.eh-fb-track {
  height: 8px;
  border-radius: 999px;
  background: var(--surface-2);
  overflow: hidden;
}
.eh-fb-fill {
  height: 100%;
  background: var(--amber);
}

/* The event picker and its actions. A raw `<select>` beside three buttons floating above the
   panels was the loosest part of the tab; this keeps them together on the panel head and lets them
   wrap as one group rather than four independent items. */
.eh-toolbar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  flex-wrap: wrap;
  /* Allowed to take the width the head has left, or the picker's 280px basis plus three buttons
     measures wider than its content-sized share and the last button drops to a second line. */
  flex: 1 1 auto;
}
/* `.form-input` is width:100%, which in a flex toolbar makes the picker eat the row and push its
   own buttons onto a second line. Bounded instead, the way Site visits bounds its site filter. */
.eh-select {
  flex: 0 1 280px;
  width: auto;
  min-width: 200px;
}
.overview-panel-note {
  margin: 0 0 12px;
  color: var(--text-secondary);
  font-size: var(--text-sm);
  line-height: 1.55;
  max-width: 78ch;
}
/* The scope this tab is locked to. Neutral, because it is a statement of fact rather than a
   success or a warning, and `.badge`'s own modifiers are all one or the other. */
.eh-scope-badge {
  background: var(--surface-2);
  color: var(--text-secondary);
  margin-inline-start: 6px;
  vertical-align: baseline;
}
.eh-row-title {
  font-weight: 600;
  font-size: var(--text-sm);
  color: var(--text);
}
.eh-row-sub {
  display: block;
  color: var(--dim);
  font-size: var(--text-xs);
  margin-top: 2px;
  line-height: 1.45;
}
.eh-num {
  text-align: end;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

/* The event editor stacks each label over its control. `.overview-eyebrow` is an inline span by
   design (it is a kicker above a heading elsewhere), so without this the caption sits beside its
   input and a five-field form reads as one run-on line. Scoped to the editor rather than changing
   the shared eyebrow, which a dozen other panels rely on being inline. */
#eh-editor label {
  display: block;
}
#eh-editor label > .overview-eyebrow {
  display: block;
  margin-bottom: 4px;
}
#eh-editor .form-input {
  width: 100%;
}

.badge-ok {
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  color: var(--primary-dark);
}
.badge-warn {
  background: var(--warn-bg);
  color: var(--warn-fg);
}

/* An attendee row is name + detail + three actions. Side by side that is unreadable on a phone,
 * and the actions are the half you came for, so they keep the full width rather than being
 * squeezed to the right of a name that wraps. */
@media (max-width: 640px) {
  .eh-row {
    flex-direction: column;
    align-items: stretch;
  }
  .eh-row .btn {
    width: 100%;
  }

  /* `.overview-panel-head` is a one-line flex row, which is right on a desktop and wrong the
     moment the right-hand side is a picker plus three buttons: at 375px the select landed on top
     of its own "WHICH EVENT / Event" heading and ran past the card's edge. Scoped to this tab so
     the twenty other panels that put one small button there keep their single line. */
  #tab-eventshub .overview-panel-head {
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 10px;
  }
  #tab-eventshub .overview-panel-head > * {
    min-width: 0;
  }
  /* The collapse caret is `.overview-panel-head::after`, so it is a flex item like any other and
     the wrap above dropped it onto a line of its own under the buttons. Anchored to the corner it
     occupies on every other panel, which also keeps the head's collapse click working. */
  #tab-eventshub .overview-panel-head {
    position: relative;
    padding-inline-end: 18px;
  }
  #tab-eventshub .overview-panel-head::after {
    position: absolute;
    top: 0;
    inset-inline-end: 0;
    margin-inline-start: 0;
  }
  .eh-toolbar {
    width: 100%;
  }
  .eh-select {
    flex: 1 1 100%;
    min-width: 0;
  }
  .eh-toolbar .btn {
    flex: 1 1 auto;
  }
  /* The row-level menu is the only way to reach an attendee's actions, and `@media (hover: none)`
     already pins it visible on touch. Left in the flow it would sit under the name on its own
     line; this keeps it beside the badges where a thumb expects it. */
  #eh-attendees .eh-row > div:last-child {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
  }
}

/* ── EventsHub: the two views the rail added ──────────────────────────────────────────────────
 *
 * A bar chart and a funnel, both drawn with divs rather than a charting library. Two shapes do not
 * justify a dependency, and a page an attendee's organiser opens at a venue on hotel wifi should
 * not pull one. Colours come from tokens, so both follow the theme without a dark-mode branch. */
.eh-chart {
  display: flex;
  align-items: flex-end;
  gap: 4px;
  height: 120px;
  padding: 8px 0 22px;
  overflow-x: auto;
}
.eh-bar {
  position: relative;
  flex: 0 0 26px;
  height: 100%;
  display: flex;
  align-items: flex-end;
}
.eh-bar > span {
  width: 100%;
  background: var(--primary);
  border-radius: 3px 3px 0 0;
  min-height: 2px;
}
.eh-bar > em {
  position: absolute;
  bottom: -20px;
  left: 0;
  right: 0;
  text-align: center;
  font-style: normal;
  font-size: 0.62rem;
  color: var(--dim);
}
.eh-funnel {
  display: grid;
  gap: 10px;
  margin-bottom: 14px;
}
.eh-funnel-row {
  display: grid;
  grid-template-columns: 140px minmax(0, 1fr) auto;
  gap: 12px;
  align-items: center;
}
.eh-funnel-bar {
  background: var(--surface-2);
  border-radius: 999px;
  height: 10px;
  overflow: hidden;
}
.eh-funnel-bar > span {
  display: block;
  height: 100%;
  background: var(--primary);
  border-radius: 999px;
}
.eh-more {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 2px 2px;
  flex-wrap: wrap;
}

/* The interaction trail inside the log-a-call modal. Capped and scrolled rather than allowed to grow:
   an attendee chased for six weeks would otherwise push the Save button off the bottom of the sheet,
   which is the one control the form exists for. */
/* When and where, under the event picker. A line of context, not a panel: it answers a question the
   operator has once per visit and should not have to open the editor to ask. */
.eh-where {
  margin: 6px 0 0;
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
}
.eh-map-link {
  font-size: 0.8125rem;
  color: var(--primary);
  text-decoration: none;
  white-space: nowrap;
}
.eh-map-link:hover {
  text-decoration: underline;
}
/* The venue/region sub-form revealed inside the event editor. Inset so it reads as belonging to the
   field above it rather than as another section of the form. */
.eh-subform {
  margin-top: 8px;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
}
.eh-subform .form-group:last-of-type {
  margin-bottom: 12px;
}

/* ── The setup panel ────────────────────────────────────────────────────────────────────────────
   Shown only while something an event needs is unresolved. Rows are a list, not cards: the operator
   is scanning for the one that is not done, and a card grid makes seven equal-weight things. */
.eh-setup-list {
  display: flex;
  flex-direction: column;
}
.eh-setup-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 0;
  border-top: 1px solid var(--border);
  flex-wrap: wrap;
}
.eh-setup-row:first-child {
  border-top: none;
}
/* Done rows recede rather than disappear: the list has to keep showing progress, and a row that
   vanishes when completed makes the remaining work look like it grew. */
.eh-setup-row.is-done .eh-row-title {
  color: var(--dim);
}
.eh-setup-main {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  min-width: 0;
  flex: 1 1 260px;
}
.eh-setup-side {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
}
.eh-check {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 0.75rem;
  flex-shrink: 0;
  margin-top: 2px;
  background: var(--surface-2);
  color: var(--dim);
}
.eh-check-ok {
  background: var(--ok-bg);
  color: var(--ok-fg);
}
.eh-check-blocked {
  background: var(--warn-bg);
  color: var(--warn-fg);
}

.eh-touch-history {
  max-height: 180px;
  overflow-y: auto;
  border-top: 1px solid var(--border);
  margin-top: 4px;
  padding-top: 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.eh-touch-item {
  font-size: 0.875rem;
  line-height: 1.45;
}

@media (max-width: 640px) {
  /* The stage label above its bar, rather than a 140px column squeezing both. */
  .eh-funnel-row {
    grid-template-columns: 1fr auto;
  }
  .eh-funnel-bar {
    grid-column: 1 / -1;
  }
}

/* ── EventsHub's glance, on one line at phone width ───────────────────────────────────────────
 *
 * The global mobile rule puts .stats-grid into two columns, which is right for a tab with two to
 * four tiles and wrong for five: they became 2/2/1 and pushed the section rail most of a screen
 * down, so the first thing you saw on opening the tab was an orphaned tile.
 *
 * Scoped to #eh-summary rather than changed globally, because every other tab's tiles are still
 * better two-up.
 *
 * Five across 375px leaves about 63px each, which the number fits and the label does not — so the
 * label wraps, the letter-spacing comes off, and the decorative icon goes. The icon is the right
 * thing to drop: it repeats what the label already says, and it is the only part of the tile
 * nobody reads. */
@media (max-width: 640px) {
  #eh-summary {
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 6px;
    margin-bottom: 16px;
  }
  #eh-summary .stat-card {
    padding: 10px 6px;
    text-align: center;
  }
  #eh-summary .stat-card-value {
    font-size: 1.15rem;
  }
  #eh-summary .stat-card-label {
    font-size: 0.55rem;
    letter-spacing: 0;
    line-height: 1.25;
    margin-top: 2px;
    /* The labels are two words each so they wrap where a reader expects. This is the safety net
       for the locale where one of them is not: a label that silently reads "Registration" is worse
       than one broken across two lines. `hyphens: auto` is deliberately absent — it does not fire
       in this context even with lang="en" set, so relying on it would just mean clipping. */
    overflow-wrap: anywhere;
  }
  #eh-summary .stat-card-icon {
    display: none;
  }
}

/* ── Printed QR codes (ui/qr-codes.js) ────────────────────────────────────────────────────────
   The QR art itself always sits on white, in both themes: a phone camera needs dark modules on a
   light ground, so the preview shows exactly what will print rather than a themed approximation. */
.qrc-section {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 20px;
}
/* Pages & QR, QR codes tab: the panel sits directly under the tab bar, as EventsHub panels do. */
#pages-qr-codes {
  margin-top: 0;
}
.qrc-section-title {
  font-weight: 600;
  font-size: var(--text-md);
  margin: 0 0 16px;
}
/* Without the extension: one line saying where link and product codes come from. */
.qrc-locked p {
  margin: 0;
}
.qrc-locked a {
  color: var(--primary);
  font-weight: 600;
  text-decoration: none;
}
.qrc-locked a:hover {
  text-decoration: underline;
}
.qrc-summary-hint {
  font-weight: 400;
  font-size: var(--text-xs);
  margin-left: 6px;
}
.qrc-heading {
  font-weight: 600;
  font-size: var(--text-sm);
  margin: 0 0 6px;
}
.qrc-hint {
  margin: 0 0 10px;
  font-size: var(--text-xs);
}
.qrc-brand {
  display: flex;
  gap: 20px;
  align-items: flex-start;
  margin: 14px 0 20px;
  padding-bottom: 20px;
  border-bottom: 1px solid var(--border);
}
.qrc-preview {
  flex: none;
  line-height: 0;
  padding: 8px;
  background: var(--qr-ground);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.qrc-brand-controls {
  flex: 1;
  min-width: 0;
}
.qrc-field {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
.qrc-field .form-label {
  margin: 0;
  min-width: 88px;
}
.qrc-swatches {
  display: flex;
  gap: 8px;
  align-items: center;
}
.qrc-swatch {
  width: 26px;
  height: 26px;
  padding: 0;
  border-radius: 50%;
  border: 2px solid var(--surface);
  background: var(--swatch, var(--surface-2));
  box-shadow: 0 0 0 1px var(--border);
  cursor: pointer;
  position: relative;
}
.qrc-swatch[aria-pressed='true'] {
  box-shadow: 0 0 0 2px var(--primary);
}
.qrc-swatch:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}
.qrc-swatch-custom {
  display: grid;
  place-items: center;
  overflow: hidden;
  color: var(--text-secondary);
  font-size: var(--text-md);
  line-height: 1;
}
.qrc-swatch-custom.has-color {
  color: transparent;
}
.qrc-swatch-custom input {
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
}
.qrc-warn {
  margin: -4px 0 12px;
  padding: 8px 10px;
  font-size: var(--text-xs);
  color: var(--warn-fg);
  background: var(--warn-bg);
  border: 1px solid var(--warn-border);
  border-radius: var(--radius-sm);
}
.qrc-create {
  margin: 0 0 20px;
}
.qrc-create-row {
  display: flex;
  gap: 8px;
}
.qrc-create-row #qrc-new-label {
  flex: 1;
  min-width: 0;
}
.qrc-create-row #qrc-new-url {
  flex: 2;
  min-width: 0;
}
.qrc-list {
  border-top: 1px solid var(--border);
}
.qrc-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 8px;
  border-bottom: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.qrc-row.is-retired .qrc-thumb,
.qrc-row.is-retired .qrc-body {
  opacity: 0.6;
}
.qrc-thumb {
  flex: none;
  line-height: 0;
  padding: 3px;
  background: var(--qr-ground);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.qrc-body {
  flex: 1;
  min-width: 0;
}
.qrc-title {
  font-size: var(--text-base);
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.qrc-meta {
  font-size: var(--text-xs);
  color: var(--text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.qrc-mono {
  font-family: var(--font-mono);
}
/* What a code produced: the line the owner is actually looking for, so it reads as a result. */
.qrc-results {
  color: var(--primary);
  font-weight: 600;
  font-size: var(--text-sm);
  margin: 2px 0;
}
/* 30 days of scans, right of the row: rising, steady or fading at a glance. */
.qrc-spark {
  flex: none;
  color: var(--primary);
  opacity: 0.85;
}
.qrc-row.is-retired .qrc-spark {
  opacity: 0.35;
}
.qrc-badge-quiet {
  background: var(--warn-bg);
  color: var(--warn-fg);
}
/* New QR code: one place, four kinds. */
.qrc-maker {
  margin: 0 0 20px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--border);
}
.qrc-modes {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0 0 12px;
}
.qrc-mode,
.qrc-sort-btn {
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 600;
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-secondary);
  cursor: pointer;
}
.qrc-mode.is-active,
.qrc-sort-btn.is-active {
  border-color: var(--primary);
  color: var(--primary);
  background: color-mix(in srgb, var(--primary) 8%, transparent);
}
.qrc-mode-body .qrc-create {
  margin: 0;
}
.qrc-bulk-names {
  width: 100%;
  min-height: 96px;
  margin: 4px 0 8px;
  resize: vertical;
  font-family: var(--font-mono);
}
#qrc-bulk-url {
  flex: 1;
  min-width: 0;
}
.qrc-bulk-done {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 10px;
  font-weight: 600;
  color: var(--primary);
}
.qrc-pick-results {
  margin-top: 8px;
  max-height: 260px;
  overflow-y: auto;
}
.qrc-pick {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 4px;
  border-bottom: 1px solid var(--border);
}
.qrc-pick span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.qrc-list-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 8px;
}
.qrc-sort {
  display: flex;
  gap: 6px;
  margin-bottom: 12px;
}
/* ── QR codes tab, redesigned for a five-second read (ui/qr-codes.js) ── */
.qrc-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 20px;
}
.qrc-summary-head {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: 700;
  color: var(--text);
  line-height: 1.25;
}
.qrc-summary-sub {
  margin-top: 4px;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.qrc-top-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.qrc-style-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.qrc-style-dot {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--swatch);
  border: 1px solid var(--border);
}
.qrc-dest {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.qrc-quietline {
  font-size: var(--text-sm);
  color: var(--dim);
  margin: 2px 0;
}
/* Nothing yet: the whole idea in three steps. */
.qrc-empty {
  text-align: center;
  padding: 24px 8px 8px;
}
.qrc-empty h3 {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  margin: 0 0 20px;
}
.qrc-steps {
  list-style: none;
  counter-reset: qrc-step;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  margin: 0 0 24px;
  padding: 0;
  text-align: left;
}
.qrc-steps li {
  counter-increment: qrc-step;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px;
}
.qrc-steps li::before {
  content: counter(qrc-step);
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--primary);
  color: #fff;
  font-weight: 700;
  font-size: var(--text-sm);
  margin-bottom: 10px;
}
.qrc-steps b {
  display: block;
  margin-bottom: 4px;
}
.qrc-steps span {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  line-height: 1.5;
}
/* Dialogs: fixed overlays BELOW the shared confirm/prompt layer (z-index 4000), so a "Rename"
   prompt opened from a dialog appears on top of it, not behind. */
.qrc-overlay {
  position: fixed;
  inset: 0;
  z-index: 3000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(17, 24, 39, 0.45);
  opacity: 0;
  transition: opacity 0.16s ease;
}
.qrc-overlay.is-open {
  opacity: 1;
}
.qrc-dialog {
  width: 100%;
  max-width: 560px;
  max-height: calc(100vh - 40px);
  overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.25);
  padding: 20px 22px 22px;
}
.qrc-dialog.is-wide {
  max-width: 820px;
}
.qrc-dialog-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 8px;
}
.qrc-dialog-title {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 700;
  margin: 0;
}
.qrc-icon-btn {
  flex: none;
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 8px;
  background: none;
  color: var(--text-secondary);
  cursor: pointer;
}
.qrc-icon-btn:hover {
  background: var(--surface-2);
  color: var(--text);
}
.qrc-icon-btn svg,
.qrc-kind-icon svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* New QR code: where should it take people? */
.qrc-step-q {
  font-weight: 600;
  margin: 4px 0 12px;
}
.qrc-kinds {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}
.qrc-kind {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  text-align: left;
  font: inherit;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
}
.qrc-kind:hover {
  border-color: var(--primary);
}
.qrc-kind.is-active {
  border-color: var(--primary);
  box-shadow: 0 0 0 1px var(--primary);
  background: color-mix(in srgb, var(--primary) 5%, var(--surface));
}
.qrc-kind.is-locked {
  opacity: 0.6;
  cursor: default;
}
.qrc-kind.is-locked:hover {
  border-color: var(--border);
}
.qrc-kind-icon {
  flex: none;
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border-radius: 10px;
  background: color-mix(in srgb, var(--primary) 10%, transparent);
  color: var(--primary);
}
.qrc-kind-text {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}
.qrc-kind-text span {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  line-height: 1.45;
}
.qrc-kind-text .qrc-kind-note {
  color: var(--warn-fg);
  font-size: var(--text-xs);
}
.qrc-kind-badge {
  align-self: flex-start;
  font-size: var(--text-2xs) !important;
  font-weight: 700;
  color: var(--primary) !important;
  background: color-mix(in srgb, var(--primary) 10%, transparent);
  border-radius: 999px;
  padding: 1px 8px;
}
.qrc-step {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}
.qrc-step .form-label {
  margin-top: 6px;
}
.qrc-howmany {
  border: 0;
  padding: 0;
  margin: 6px 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px 20px;
}
.qrc-howmany legend {
  width: 100%;
  margin-bottom: 4px;
}
.qrc-howmany label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-sm);
}
.qrc-step-actions {
  display: flex;
  justify-content: flex-end;
  margin-top: 12px;
}
/* One code, in full */
.qrc-detail-dest {
  margin: 0 0 16px;
  color: var(--text-secondary);
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.qrc-detail-grid {
  display: grid;
  grid-template-columns: 240px 1fr;
  grid-template-areas:
    'code results'
    'code settings';
  column-gap: 24px;
  align-items: start;
}
.qrc-detail-code {
  grid-area: code;
}
.qrc-detail-results {
  grid-area: results;
}
.qrc-detail-settings {
  grid-area: settings;
}
.qrc-detail-code {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.qrc-detail-qr {
  line-height: 0;
  padding: 12px;
  background: var(--qr-ground);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.qrc-detail-qr svg {
  width: 100%;
  height: auto;
}
.qrc-detail-downloads {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.qrc-detail-downloads .btn {
  flex: 1 1 auto;
}
/* The code as a link, for a post, a story sticker or a bio. */
.qrc-detail-link {
  display: flex;
  gap: 6px;
  align-items: center;
}
.qrc-detail-link .form-input {
  flex: 1 1 auto;
  min-width: 0;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
}
.qrc-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}
.qrc-stat {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px;
}
.qrc-stat b {
  display: block;
  font-family: var(--font-display);
  font-size: var(--text-xl);
  color: var(--primary);
  line-height: 1.1;
}
.qrc-stat span {
  font-size: var(--text-xs);
  color: var(--text-secondary);
}
.qrc-stats + .qrc-hint {
  margin-top: 8px;
}
.qrc-trend {
  margin: 14px 0 4px;
}
.qrc-trend-label,
.qrc-trend-foot {
  font-size: var(--text-xs);
  color: var(--text-secondary);
}
.qrc-trend-label {
  font-weight: 600;
  margin-bottom: 6px;
}
.qrc-trend-foot {
  margin-top: 6px;
}
.qrc-bars {
  display: block;
  width: 100%;
  height: 64px;
  fill: var(--primary);
}
.qrc-bars .is-zero {
  fill: var(--border);
}
.qrc-settings {
  margin-top: 18px;
  border-top: 1px solid var(--border);
}
.qrc-setting {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 0;
  border-bottom: 1px solid var(--border);
}
.qrc-setting > div {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.qrc-setting b {
  font-size: var(--text-sm);
}
.qrc-setting span {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  overflow-wrap: anywhere;
}
.qrc-setting-toggle {
  cursor: pointer;
}
.qrc-dialog .qrc-brand {
  margin-top: 8px;
}
/* What your customer sees: their outgoing message, as their WhatsApp will show it. */
.qrc-sees {
  margin-top: 16px;
}
.qrc-sees-intro,
.qrc-sees-note {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin: 0 0 8px;
  line-height: 1.5;
}
.qrc-sees-note {
  margin: 8px 0 0;
  font-size: var(--text-xs);
}
.qrc-sees-phone {
  display: flex;
  justify-content: flex-end;
  padding: 14px;
  border-radius: var(--radius);
  background: var(--surface-2);
  border: 1px solid var(--border);
}
.qrc-sees-bubble {
  max-width: 85%;
  padding: 8px 12px;
  border-radius: 12px 12px 2px 12px;
  background: color-mix(in srgb, var(--primary) 16%, var(--surface));
  color: var(--text);
  font-size: var(--text-sm);
  line-height: 1.45;
  overflow-wrap: anywhere;
}
/* The platform owner's funnel, under the list. */
.qrc-funnel {
  margin-top: 28px;
  padding-top: 18px;
  border-top: 1px dashed var(--border);
}
.qrc-funnel-steps {
  list-style: none;
  margin: 8px 0 0;
  padding: 0;
  display: grid;
  gap: 8px;
}
.qrc-funnel-steps li {
  display: grid;
  grid-template-columns: 200px 1fr auto;
  align-items: center;
  gap: 12px;
  font-size: var(--text-sm);
}
.qrc-funnel-bar {
  height: 10px;
  border-radius: 999px;
  background: var(--surface-2);
  overflow: hidden;
}
.qrc-funnel-bar span {
  display: block;
  height: 100%;
  min-width: 2px;
  background: var(--primary);
  border-radius: 999px;
}
.qrc-funnel-num {
  color: var(--text-secondary);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  white-space: nowrap;
}
.qrc-meta.qrc-wrap {
  white-space: normal;
}
.qrc-badge-retired {
  background: var(--surface-2);
  color: var(--text-secondary);
}
.qrc-badge-warn {
  background: var(--warn-bg);
  color: var(--warn-fg);
}
#cc-stats {
  font-family: var(--font-mono);
  margin-bottom: 12px;
}
@media (max-width: 768px) {
  .qrc-section {
    padding: 16px;
  }
  .qrc-brand {
    flex-direction: column;
    align-items: center;
  }
  .qrc-brand-controls {
    width: 100%;
  }
  .qrc-create-row {
    flex-direction: column;
  }
  .qrc-spark {
    display: none;
  }
  .qrc-steps,
  .qrc-kinds {
    grid-template-columns: 1fr;
  }
  .qrc-detail-code {
    max-width: 280px;
    margin: 0 auto;
  }
  /* On a phone the answer comes first (what the code brought in), then the code and its print
     button, then the settings you change rarely. */
  .qrc-detail-grid {
    grid-template-columns: 1fr;
    grid-template-areas:
      'results'
      'code'
      'settings';
    row-gap: 18px;
  }
  .qrc-overlay {
    padding: 0;
    align-items: flex-end;
  }
  .qrc-dialog,
  .qrc-dialog.is-wide {
    max-width: none;
    max-height: 92vh;
    border-radius: var(--radius) var(--radius) 0 0;
  }
  .qrc-top-actions {
    width: 100%;
  }
  .qrc-top-actions .btn {
    flex: 1 1 auto;
  }
  .qrc-funnel-steps li {
    grid-template-columns: 1fr auto;
  }
  .qrc-funnel-bar {
    grid-column: 1 / -1;
    order: 3;
  }
  /* On a phone a status badge must never be the part that gets cut off: "Quiet this week" is the
     reason to look at that row. Titles and scan lines wrap instead of ending in an ellipsis. */
  .qrc-title,
  .qrc-row .qrc-meta {
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
  }
  .qrc-summary-hint {
    display: block;
    margin: 2px 0 0;
  }
}

/* ── EventsHub: Events home and event workspace ────────────────────────────────────────────────
   Two levels, one navigation. The home is a grid of event cards; an event opens into a workspace
   with one tab bar (ui/category-rail.js, horizontal here, sticky under the header). Few boxes:
   hierarchy comes from type and space, and each number appears once. */
.eh-event-state {
  display: none;
}
.eh-home-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.eh-home-head .tab-eyebrow {
  margin-bottom: 0;
}
#eh-readiness:not([hidden]) {
  display: block;
  margin-top: 16px;
}
.eh-seg {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  margin-top: 20px;
  border-radius: 999px;
  background: var(--surface-2);
}
.eh-seg-btn {
  border: 0;
  background: transparent;
  color: var(--text-secondary);
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 600;
  padding: 6px 14px;
  border-radius: 999px;
  cursor: pointer;
}
.eh-seg-btn[data-count]:not([data-count=''])::after {
  content: attr(data-count);
  margin-inline-start: 6px;
  font-size: var(--text-2xs);
  color: var(--dim);
}
.eh-seg-btn.active {
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-sm);
}
.eh-event-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 16px;
  margin-top: 16px;
}
.eh-ev-card {
  --eh-accent: var(--primary);
  display: flex;
  flex-direction: column;
  text-align: start;
  padding: 0;
  font: inherit;
  color: inherit;
  cursor: pointer;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  overflow: hidden;
  transition:
    box-shadow var(--transition),
    transform var(--transition);
}
.eh-ev-card:hover {
  box-shadow: var(--shadow-card);
  transform: translateY(-1px);
}
.eh-ev-card:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}
.eh-ev-cover {
  position: relative;
  height: 112px;
  background: linear-gradient(135deg, var(--eh-accent), var(--surface-3));
  background-size: cover;
  background-position: center;
}
.eh-ev-cover .eh-date {
  position: absolute;
  left: 14px;
  bottom: -18px;
}
.eh-ev-body {
  padding: 26px 16px 16px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1;
}
.eh-ev-status,
.eh-status {
  font-size: var(--text-2xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ok-fg);
}
.eh-ev-status.is-live,
.eh-status.is-live {
  color: var(--primary);
}
.eh-ev-status.is-ended,
.eh-status.is-ended {
  color: var(--dim);
}
.eh-ev-status.is-undated,
.eh-status.is-undated {
  color: var(--warn-fg);
}
.eh-ev-name {
  font-family: var(--font-display);
  font-size: 1.15rem;
  line-height: 1.25;
  overflow-wrap: anywhere;
}
.eh-ev-meta {
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.eh-ev-numbers {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  margin-top: auto;
  padding-top: 10px;
  font-size: var(--text-sm);
  font-weight: 600;
}
.eh-ev-week {
  color: var(--ok-fg);
  font-weight: 600;
}
.eh-home-empty {
  grid-column: 1 / -1;
  padding: 40px 24px;
  border: 1px dashed var(--border-light);
  border-radius: var(--radius-lg);
  text-align: center;
}
.eh-home-empty h2 {
  font-family: var(--font-display);
  margin: 0 0 6px;
}
.eh-home-empty p {
  color: var(--text-secondary);
  max-width: 520px;
  margin: 0 auto 16px;
}
.eh-home-none {
  color: var(--dim);
  grid-column: 1 / -1;
}

/* ── EventsHub: organisations, their people, venues (ui/eventshub-library.js) ──────────────────
   The switcher is the organisations themselves; the strip under it is the chosen one, marked with
   its own colour. The library view reuses the workspace's tab bar, sections and flat rows. */
.eh-home-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.eh-orgbar:not([hidden]) {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 18px;
}
.eh-orgbar .eh-chip,
.eh-crew-suggest .eh-chip {
  align-items: center;
}
.eh-org-logo {
  border-radius: 4px;
  object-fit: contain;
  background: var(--surface);
  flex: none;
}
.eh-org-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--eh-org, var(--dim));
  flex: none;
}
.eh-org-strip:not([hidden]) {
  --eh-org: var(--primary);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 12px;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-inline-start: 4px solid var(--eh-org);
  border-radius: var(--radius-lg);
  background: var(--surface);
}
.eh-org-id {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}
.eh-org-strip-name {
  font-family: var(--font-display);
  font-size: 1.1rem;
  overflow-wrap: anywhere;
}
.eh-row-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}
.eh-ev-org {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-xs);
  color: var(--text-secondary);
}
.eh-ev-with {
  color: var(--dim);
}
#eh-manage .eh-tabs {
  margin-top: 16px;
}
#eh-manage .eh-panes {
  margin-top: 16px;
}
.eh-manage-head {
  margin-top: 10px;
}
.eh-lib-sender:not([hidden]) {
  margin: 14px 0 0;
  padding-top: 12px;
  border-top: 1px solid var(--border);
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.eh-lib-tools .form-input {
  width: 100%;
  max-width: 360px;
}
.eh-lib-empty {
  padding: 24px;
  text-align: center;
  color: var(--text-secondary);
  border: 1px dashed var(--border-light);
  border-radius: var(--radius-lg);
}
.eh-lib-empty p {
  margin: 0;
}
.eh-row.eh-org-row,
.eh-row.eh-person {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
}
.eh-row.eh-person {
  grid-template-columns: auto minmax(0, 1fr) auto;
}
.eh-person-main {
  min-width: 0;
}
.eh-person-orgline {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  margin-top: 4px;
  font-size: var(--text-xs);
  color: var(--text-secondary);
}
.eh-person-org {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
.eh-person-org.is-none {
  color: var(--dim);
}
.eh-person-orgs {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.eh-person-orgset {
  margin: 0;
  padding: 8px 12px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.eh-person-orgset.is-on {
  border-color: var(--primary);
}
.eh-person-orgset legend label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 4px;
  font-weight: 600;
  cursor: pointer;
}
.eh-role-set {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
}
.eh-role,
.eh-cohost {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-sm);
  cursor: pointer;
}
.eh-invite {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}
.eh-invite-preview img {
  display: block;
  max-width: 160px;
  max-height: 200px;
  border-radius: var(--radius);
  border: 1px solid var(--border);
}
.eh-invite-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
/* .btn sets its own display, which beats the UA [hidden] rule: "Remove" showed with nothing to remove. */
.eh-invite-actions [hidden] {
  display: none;
}
/* One co-host per line: the name, then the part it plays, so the role pickers line up. */
.eh-cohosts:has(.eh-cohost-role) {
  flex-direction: column;
  align-items: stretch;
}
.eh-cohost-row {
  display: grid;
  grid-template-columns: minmax(0, 280px) minmax(0, 220px);
  align-items: center;
  gap: 12px;
}
.eh-cohost-row .eh-cohost-role {
  width: auto;
  padding-block: 4px;
  font-size: var(--text-sm);
}
.eh-cohosts {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 18px;
}
.eh-color-pair {
  display: flex;
  align-items: center;
  gap: 8px;
}
.eh-color-pair input[type='color'] {
  width: 56px;
  height: 36px;
  padding: 2px;
}
.eh-color-pair.is-cleared input[type='color'] {
  opacity: 0.3;
}
.eh-danger-link {
  color: var(--danger-fg);
  margin-inline-end: auto;
}
.eh-crew-suggest:not([hidden]) {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: 12px 0 4px;
}
.eh-chip-sub {
  font-size: var(--text-2xs);
  opacity: 0.75;
}
.eh-region-add {
  margin-top: 16px;
}
#eh-venue-list .eh-select {
  width: auto;
  max-width: 220px;
}
#eh-manage .eh-section-head .btn {
  flex: none;
  white-space: nowrap;
}
#modal-eh-watch .eh-share-url {
  margin-top: 14px;
}
/* Links that are buttons, as in the event workspace (#eh-workspace a.btn); a dialog sits outside it. */
#modal-eh-watch a.btn {
  background: var(--surface-2);
  color: var(--text);
  text-decoration: none;
}
#modal-eh-watch a.btn:hover {
  background: var(--surface-3);
}

/* The date block: a calendar leaf, the fastest way to read "when". */
.eh-date {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 54px;
  height: 58px;
  border-radius: var(--radius);
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-sm);
  flex: none;
}
.eh-date-m {
  font-size: var(--text-2xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--eh-accent, var(--primary));
}
.eh-date-d {
  font-family: var(--font-display);
  font-size: 1.5rem;
  line-height: 1;
}

/* ── Workspace header ── */
.eh-back {
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  font-size: var(--text-sm);
  color: var(--text-secondary);
  cursor: pointer;
}
.eh-back:hover {
  color: var(--text);
}
.eh-hero {
  --eh-accent: var(--primary);
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas:
    'date text cover'
    'date actions cover';
  column-gap: 18px;
  row-gap: 12px;
  margin-top: 12px;
}
.eh-hero > .eh-date {
  grid-area: date;
}
.eh-hero-text {
  grid-area: text;
  min-width: 0;
}
.eh-hero-kicker {
  display: flex;
  align-items: center;
  gap: 10px;
}
.eh-hero-title {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 2.4vw, 2.1rem);
  line-height: 1.15;
  margin: 4px 0;
  overflow-wrap: anywhere;
}
.eh-hero .eh-where {
  margin: 0;
}
.eh-hero-lang {
  margin: 4px 0 0;
}
.eh-hero-cover {
  grid-area: cover;
  width: 200px;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: var(--radius);
}
.eh-hero-actions {
  grid-area: actions;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* ── One tab bar ── */
.eh-tabs {
  position: sticky;
  top: calc(56px + var(--banner-h, 0px));
  z-index: 5;
  display: flex;
  gap: 4px;
  margin: 20px -24px 0;
  padding: 0 24px;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  overflow-x: auto;
  scrollbar-width: none;
}
.eh-tabs::-webkit-scrollbar {
  display: none;
}
.eh-tabs .eh-cat-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  flex: none;
  border: 0;
  border-bottom: 2px solid transparent;
  background: none;
  padding: 12px 10px 10px;
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-secondary);
  cursor: pointer;
}
.eh-tabs .eh-cat-btn:hover {
  color: var(--text);
}
.eh-tabs .eh-cat-btn.active {
  color: var(--text);
  border-bottom-color: var(--primary);
}
.eh-tab-icon {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.eh-tab-count {
  font-size: var(--text-2xs);
  font-weight: 700;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--text-secondary);
}
.eh-panes {
  margin-top: 20px;
}
.eh-panes .eh-category > * + * {
  margin-top: 16px;
}

/* ── Sections: one quiet container, a title and an optional action ── */
.eh-section {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  padding: 18px;
}
.eh-section-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}
.eh-section-title {
  font-family: var(--font-display);
  font-size: 1.05rem;
  margin: 0;
}
.eh-section-note {
  color: var(--text-secondary);
  font-size: var(--text-sm);
  margin: 4px 0 0;
}
.eh-mini-title {
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--dim);
  margin: 18px 0 8px;
}
.eh-fact {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  padding: 3px 0;
}
.eh-fact:empty {
  display: none;
}
.eh-muted {
  color: var(--dim);
}

/* Needs you: every problem once, with its fix. */
.eh-needs {
  border: 1px solid var(--warn-border);
  background: var(--warn-bg);
  color: var(--warn-fg);
  border-radius: var(--radius-lg);
  padding: 12px 16px;
}
.eh-needs-title {
  font-size: var(--text-2xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-bottom: 4px;
}
.eh-need {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  font-size: var(--text-sm);
  padding: 4px 0;
}

/* Momentum: one band, four figures, no boxes inside boxes. */
.eh-momentum {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
}
.eh-momentum:empty {
  display: none;
}
.eh-fig {
  padding: 16px 18px;
}
.eh-fig + .eh-fig {
  border-inline-start: 1px solid var(--border);
}
.eh-fig-value {
  font-family: var(--font-display);
  font-size: 1.9rem;
  line-height: 1.1;
}
.eh-fig-label {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--text-secondary);
  margin-top: 2px;
}
.eh-fig-sub {
  font-size: var(--text-xs);
  color: var(--dim);
  margin-top: 2px;
}
.eh-m-bar {
  height: 5px;
  border-radius: 3px;
  background: var(--surface-2);
  margin-top: 8px;
  overflow: hidden;
}
.eh-m-bar span {
  display: block;
  height: 100%;
  background: var(--primary);
}
.eh-overview-grid {
  display: grid;
  gap: 16px;
}

/* The automatic journey. */
.eh-journey {
  list-style: none;
  margin: 4px 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 12px;
}
.eh-step {
  position: relative;
  padding-top: 20px;
}
.eh-step::before {
  content: '';
  position: absolute;
  top: 5px;
  left: 14px;
  right: -12px;
  height: 2px;
  background: var(--border);
}
.eh-step:last-child::before {
  display: none;
}
.eh-step-dot {
  position: absolute;
  top: 0;
  left: 0;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--primary);
  box-shadow: 0 0 0 3px var(--surface);
}
.eh-step.is-off .eh-step-dot,
.eh-step.is-needs_date .eh-step-dot {
  background: var(--border-light);
}
.eh-step.is-recording .eh-step-dot {
  background: var(--amber);
}
.eh-step-name {
  font-weight: 600;
  font-size: var(--text-sm);
}
.eh-step-when {
  font-size: var(--text-xs);
  color: var(--text-secondary);
  margin-top: 2px;
}
.eh-step-state {
  display: inline-block;
  margin-top: 6px;
  font-size: var(--text-2xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ok-fg);
}
.eh-step.is-off .eh-step-state,
.eh-step.is-needs_date .eh-step-state {
  color: var(--dim);
}
.eh-step.is-recording .eh-step-state {
  color: var(--warn-fg);
}

/* The page people share, shown the way they see it. */
.eh-share-body {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 24px;
  align-items: start;
}
.eh-phone {
  width: 250px;
  height: 440px;
  border: 8px solid var(--text);
  border-radius: 30px;
  overflow: hidden;
  background: var(--surface-2);
}
.eh-phone iframe {
  width: 390px;
  height: 680px;
  border: 0;
  transform: scale(0.6);
  transform-origin: 0 0;
  pointer-events: none;
}
.eh-share-url {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  overflow-wrap: anywhere;
}
.eh-share-actions {
  display: flex;
  gap: 8px;
  margin: 10px 0 12px;
}
.eh-src {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 90px auto;
  align-items: center;
  gap: 10px;
  font-size: var(--text-sm);
  padding: 3px 0;
}
.eh-src span:first-child {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.eh-src-bar {
  height: 6px;
  border-radius: 3px;
  background: var(--surface-2);
  overflow: hidden;
}
.eh-src-bar i {
  display: block;
  height: 100%;
  background: var(--amber);
}
.eh-fig-inline {
  margin-bottom: 10px;
}
.eh-door-note {
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.eh-crew .eh-team-form {
  margin-bottom: 8px;
}

/* ── Guests ── */
.eh-guests-bar {
  display: flex;
  gap: 8px;
}
.eh-guests-bar input {
  flex: 1;
  max-width: 420px;
}
.eh-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 14px;
}
.eh-chip {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-secondary);
  border-radius: 999px;
  padding: 6px 12px;
  font: inherit;
  font-size: var(--text-sm);
  cursor: pointer;
}
.eh-chip:hover {
  border-color: var(--border-light);
  color: var(--text);
}
.eh-chip.active {
  background: var(--text);
  border-color: var(--text);
  color: var(--surface);
}
.eh-chip-n {
  font-weight: 700;
}
.eh-guest-headline {
  margin: 12px 0 4px;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.eh-guest-headline:empty {
  display: none;
}
.eh-guest-list {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  margin-top: 10px;
}
.eh-row.eh-guest {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 12px;
}
.eh-avatar {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: var(--text-xs);
  font-weight: 700;
  background: var(--ok-bg);
  color: var(--ok-fg);
}
.eh-guest-main {
  min-width: 0;
}
.eh-guest-main .eh-row-sub {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.eh-guest-state {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: center;
  gap: 6px;
}
.eh-guest-state:empty {
  display: none;
}
@media (max-width: 600px) {
  .eh-row.eh-guest {
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas:
      'avatar main menu'
      '. state state';
    row-gap: 6px;
  }
  .eh-row.eh-guest .eh-avatar {
    grid-area: avatar;
  }
  .eh-row.eh-guest .eh-guest-main {
    grid-area: main;
  }
  .eh-row.eh-guest .eh-guest-state {
    grid-area: state;
    justify-content: flex-start;
  }
  .eh-guests-bar input {
    max-width: none;
  }
}

/* ── The event editor: sections, form, live page ── */
.modal.eh-editor {
  width: min(1180px, calc(100vw - 32px));
  max-width: none;
  height: min(88vh, 900px);
  display: flex;
  flex-direction: column;
  padding: 0;
  overflow: hidden;
}
.eh-editor-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding: 16px 22px;
  border-bottom: 1px solid var(--border);
}
.eh-editor-head .modal-title {
  margin: 0;
}
.eh-editor-nav {
  display: flex;
  gap: 4px;
  overflow-x: auto;
  scrollbar-width: none;
}
.eh-editor-nav button {
  border: 0;
  background: none;
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-secondary);
  padding: 6px 10px;
  border-radius: 999px;
  cursor: pointer;
  flex: none;
}
.eh-editor-nav button.active {
  background: var(--surface-2);
  color: var(--text);
}
.eh-editor-body {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
}
.eh-editor-form {
  overflow-y: auto;
  padding: 18px 22px 0;
  position: relative;
}
.eh-sec-title {
  font-family: var(--font-display);
  font-size: 1.05rem;
  margin: 26px 0 10px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}
#eh-sec-basics {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}
.eh-editor-actions {
  position: sticky;
  bottom: 0;
  background: var(--surface);
  margin: 20px -22px 0;
  padding: 12px 22px;
  border-top: 1px solid var(--border);
}
.eh-editor-preview {
  border-inline-start: 1px solid var(--border);
  background: var(--bg);
  padding: 18px 25px;
  overflow-y: auto;
}
.eh-editor-preview-label {
  font-size: var(--text-2xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--dim);
  margin-bottom: 10px;
}
.eh-editor-preview-note {
  font-size: var(--text-xs);
  color: var(--dim);
  margin: 10px 0 0;
}
@media (max-width: 900px) {
  .eh-editor-body {
    grid-template-columns: 1fr;
  }
  .eh-editor-preview {
    display: none;
  }
  .modal.eh-editor {
    width: 100vw;
    height: 100dvh;
    max-height: none;
    border-radius: 0;
  }
  .eh-editor-head {
    padding: 12px 16px;
  }
  .eh-editor-form {
    padding: 14px 16px 0;
  }
  .eh-editor-actions {
    margin: 20px -16px 0;
    padding: 12px 16px;
  }
}

/* ── Messages: the journey, and the phone ── */
.eh-msg-summary {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin-bottom: 18px;
}
.eh-msg-summary:empty {
  display: none;
}
.eh-msg-summary .eh-fig-value {
  font-size: 1.5rem;
}
.eh-msg-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 290px;
  gap: 24px;
  align-items: start;
}
.eh-msg-group + .eh-msg-group {
  margin-top: 6px;
}
.eh-msg-group .eh-mini-title {
  margin-top: 8px;
}
.eh-msg-item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 12px;
  align-items: center;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  cursor: pointer;
  margin-bottom: 8px;
}
.eh-msg-item:hover {
  border-color: var(--border-light);
}
.eh-msg-item.active {
  border-color: var(--primary);
  box-shadow: 0 0 0 1px var(--primary);
}
.eh-msg-item:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}
.eh-msg-item.is-off .eh-msg-main {
  opacity: 0.55;
}
.eh-msg-name {
  font-weight: 600;
  font-size: var(--text-sm);
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.eh-channel {
  font-size: var(--text-2xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--ok-bg);
  color: var(--ok-fg);
}
.eh-channel.is-template {
  background: var(--warn-bg);
  color: var(--warn-fg);
}
.eh-msg-when {
  font-size: var(--text-xs);
  color: var(--text-secondary);
  margin-top: 2px;
}
.eh-msg-snippet {
  font-size: var(--text-xs);
  color: var(--dim);
  margin-top: 4px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.eh-msg-review {
  font-size: var(--text-xs);
  color: var(--warn-fg);
  margin-top: 4px;
}
.eh-msg-state {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--ok-fg);
}
.eh-msg-state.is-off {
  color: var(--dim);
}
.eh-mode {
  min-width: 130px;
}
.eh-msg-phone {
  position: sticky;
  top: calc(56px + var(--banner-h, 0px) + 64px);
}
.eh-phone-chat {
  width: 290px;
  height: 520px;
  background: var(--surface-2);
}
.eh-chat {
  height: 100%;
  overflow-y: auto;
  padding: 16px 12px;
  background: var(--surface-2);
}
.eh-chat-day {
  text-align: center;
  font-size: var(--text-2xs);
  color: var(--text-secondary);
  background: var(--surface);
  border-radius: 999px;
  padding: 3px 10px;
  margin: 0 auto 12px;
  width: fit-content;
  max-width: 100%;
}
.eh-chat-bubble {
  background: var(--surface);
  color: var(--text);
  border-radius: 10px 10px 10px 2px;
  padding: 8px 10px 16px;
  font-size: 0.8rem;
  line-height: 1.45;
  position: relative;
  box-shadow: var(--shadow-sm);
  overflow-wrap: anywhere;
}
.eh-chat-time {
  position: absolute;
  right: 8px;
  bottom: 3px;
  font-size: 0.65rem;
  color: var(--dim);
}
.eh-chat-btns {
  display: grid;
  gap: 2px;
  margin-top: 2px;
}
.eh-chat-btn {
  background: var(--surface);
  color: var(--blue);
  text-align: center;
  font-size: 0.8rem;
  font-weight: 600;
  padding: 7px;
  border-radius: 8px;
}
.eh-chat-off {
  margin-top: 10px;
  text-align: center;
  font-size: var(--text-xs);
  color: var(--dim);
}
@media (max-width: 900px) {
  .eh-msg-layout {
    grid-template-columns: 1fr;
  }
  .eh-msg-phone {
    position: static;
    display: flex;
    justify-content: center;
  }
}
@media (max-width: 600px) {
  .eh-msg-summary {
    grid-template-columns: 1fr;
  }
  .eh-msg-summary .eh-fig + .eh-fig {
    border-inline-start: 0;
    border-top: 1px solid var(--border);
  }
  .eh-msg-item {
    grid-template-columns: 1fr;
  }
  .eh-phone-chat {
    width: 100%;
    max-width: 320px;
  }
}

/* A link that is a button looks like one. */
#eh-workspace a.btn {
  background: var(--surface-2);
  color: var(--text);
  text-decoration: none;
}
#eh-workspace a.btn:hover {
  background: var(--surface-3);
}

/* A class that sets `display` beats [hidden]; hidden means hidden here. */
.eh-status[hidden],
.eh-hero-lang[hidden],
.eh-hero-cover[hidden],
.eh-needs[hidden],
.eh-section[hidden],
.eh-tab-count[hidden],
#eh-home[hidden],
#eh-workspace[hidden],
#eh-open-page[hidden] {
  display: none !important;
}

@media (max-width: 900px) {
  .eh-journey {
    grid-template-columns: 1fr;
    gap: 14px;
  }
  .eh-step {
    padding: 0 0 0 24px;
  }
  .eh-step::before {
    top: 16px;
    bottom: -14px;
    left: 5px;
    right: auto;
    width: 2px;
    height: auto;
  }
  .eh-hero-cover {
    display: none !important;
  }
  .eh-hero {
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas:
      'date text'
      'actions actions';
  }
}
@media (max-width: 600px) {
  .eh-momentum {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .eh-fig:nth-child(3) {
    border-inline-start: 0;
  }
  .eh-fig:nth-child(n + 3) {
    border-top: 1px solid var(--border);
  }
  .eh-share-body {
    grid-template-columns: 1fr;
  }
  /* The page preview is the phone they are already holding; the message preview still helps. */
  .eh-share .eh-phone {
    display: none;
  }
  .eh-tabs {
    margin: 16px -12px 0;
    padding: 0 12px;
  }
  .eh-tabs .eh-cat-btn {
    padding: 11px 8px 9px;
  }
  .eh-section {
    padding: 14px;
  }
  .eh-fig {
    padding: 12px 14px;
  }
  .eh-fig-value {
    font-size: 1.5rem;
  }
}

/* EventsHub organisations and people, at phone width (see the base rules beside .eh-home-none). */
@media (max-width: 768px) {
  .eh-home-actions {
    width: 100%;
  }
  .eh-home-actions .btn {
    flex: 1 1 auto;
  }
  .eh-row.eh-org-row,
  .eh-row.eh-person {
    grid-template-columns: minmax(0, 1fr);
  }
  .eh-row.eh-person {
    grid-template-columns: auto minmax(0, 1fr);
  }
  .eh-row.eh-person .eh-row-actions {
    grid-column: 1 / -1;
  }
  .eh-org-strip .eh-row-actions {
    width: 100%;
  }
  /* `.eh-row .btn` goes full width at this size so an attendee's three actions stay readable. These
     rows carry two or three short buttons, which read better sharing one line than stacked 150px deep. */
  .eh-row-actions .btn {
    width: auto;
    flex: 1 1 auto;
  }
  .eh-cohost-row {
    grid-template-columns: minmax(0, 1fr);
    gap: 4px;
  }
}

/* Pages & QR: the search row held a search box and two buttons on one line and pushed the page
   55px wider than a phone. Search takes its own line; the two actions share the next. */
@media (max-width: 768px) {
  #tab-pages .search-bar {
    flex-wrap: wrap;
  }
  #tab-pages .search-input {
    flex: 1 1 100%;
  }
  #tab-pages .search-bar .btn {
    flex: 1 1 0;
  }
}

/* The view-link banner stays hidden unless its desktop flow reveals it (pages.js). */
.pages-action-banner[hidden] {
  display: none;
}

/* ── Follow-ups (ui/follow-ups.js) ─────────────────────────────────────────────────────────────
   The sheet reuses .inbox-pop; the strip is what we owe the person in this chat, quiet unless
   something is due; the chip is one question after a reply that promised something. */
.inbox-followup-pop .fu-label {
  display: block;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--dim);
  margin: 8px 0 4px;
}
.inbox-followup-pop textarea,
.inbox-followup-pop select,
.inbox-followup-pop input[type='datetime-local'] {
  width: 100%;
}
.fu-presets {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.fu-preset {
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  border-radius: 999px;
  padding: 4px 10px;
  font: inherit;
  font-size: var(--text-sm);
  cursor: pointer;
}
.fu-preset.active {
  border-color: var(--primary);
  background: var(--primary-glow);
  color: var(--primary-dark);
  font-weight: 600;
}
.fu-when-echo {
  font-size: var(--text-xs);
  color: var(--dim);
  margin-top: 6px;
}
.fu-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-top: 10px;
}

.inbox-owed {
  margin: 0 16px 8px;
  padding: 6px 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
}
.inbox-owed-title {
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--dim);
  margin-bottom: 2px;
}
.inbox-owed-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 0;
}
.inbox-owed-row + .inbox-owed-row {
  border-top: 1px solid var(--border);
}
.inbox-owed-main {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1 1 auto;
}
.inbox-owed-what {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.inbox-owed-when,
.inbox-owed-why {
  font-size: var(--text-xs);
  color: var(--dim);
}
.inbox-owed-row.is-overdue .inbox-owed-when {
  color: var(--red);
  font-weight: 600;
}
.inbox-owed-row.is-system .inbox-owed-what {
  font-weight: 500;
  color: var(--text-secondary);
}
.inbox-owed-actions {
  display: flex;
  gap: 6px;
  flex: none;
}
.inbox-owed-more {
  border: none;
  background: none;
  color: var(--primary-dark);
  font: inherit;
  font-size: var(--text-xs);
  padding: 2px 0;
  cursor: pointer;
}

.inbox-commit-chip {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 16px 8px;
  padding: 6px 12px;
  border: 1px solid var(--primary);
  border-radius: 10px;
  background: var(--primary-glow);
}
.inbox-commit-text {
  font-size: var(--text-sm);
  color: var(--text);
  flex: 1 1 200px;
}

/* The header button: icon + label where there is room, icon alone where there is not. The recorded
   user test (2026-09-30) showed the label squeezing the contact's name to "Meen…" on a desktop
   with the contact pane open, and pushing it out entirely on a phone. The query is on the header's
   own width, not the window's: three panes make the header narrow on a wide screen too. */
.inbox2-thread-head {
  container-type: inline-size;
  container-name: threadhead;
}
#inbox-followup-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.fu-btn-icon {
  width: 16px;
  height: 16px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
@container threadhead (max-width: 820px) {
  #inbox-followup-btn .fu-btn-label {
    display: none;
  }
}
/* Who you are talking to is never squeezed out. Measured 2026-09-30: at 1280px with the contact pane
   open the header is 370px wide, the actions need ~300px, and the name got 18px. So the name and
   number claim at least 176px (a typical name and masked number); when the row cannot give both that
   and the actions, the actions wrap
   to a second line, right-aligned. One rule for laptops, three-pane layouts and phones. */
.inbox2-thread-head {
  flex-wrap: wrap;
  row-gap: 6px;
}
.inbox2-thread-title {
  flex: 1 1 176px;
}
.inbox2-thread-head-right {
  margin-inline-start: auto;
}
/* Within the title, the name outranks the number beside it (which is also in the contact pane): the
   name does not shrink while the number can, and a name longer than the whole title still ends in an
   ellipsis (max-width). Weighted shrinking still took pixels from the name. */
.inbox2-thread-name {
  flex-shrink: 0;
  max-width: 100%;
}
.inbox2-thread-num {
  flex-shrink: 1;
  min-width: 0;
}

@media (max-width: 768px) {
  .inbox-owed,
  .inbox-commit-chip,
  .inbox-followup-pop {
    margin: 0 8px 8px;
  }
  .inbox-owed-row {
    flex-wrap: wrap;
  }
  .inbox-owed-what {
    white-space: normal;
  }
  .inbox-owed-actions {
    width: 100%;
    justify-content: flex-end;
  }
  #inbox-followup-btn {
    padding-inline: 8px;
  }
}

/* ── Products tab: its own views, one toolbar, a side sheet (2026-10-03) ─────────────────────────
   The tab used to stack eight panels on one page. It now has four views (ui/products-nav.js):
   Catalogue, Rates, Sales and Channels, switched by a segmented control under the title. The
   catalogue's actions moved from under the list into one toolbar above it, and adding or editing a
   product opens a sheet on the right instead of a form in the middle of the list. */
/* The views use the house tab bar (.eh-tabs, as Pages & QR and EventsHub do). Two additions:
   its count badge can say "this needs you", and the panels inside carry an inline top margin that
   the pane's own spacing already provides. */
/* The house tab rule sets display on every button, which beat the hidden attribute; no rail hid a
   tab until Products began hiding a view with nothing in it. */
.eh-tabs .eh-cat-btn[hidden] {
  display: none;
}
.eh-tab-count.alert {
  background: var(--warn-bg);
  color: var(--warn-fg);
}
#pl-panes .eh-category > .overview-panel:first-child {
  margin-top: 0 !important;
}

/* The catalogue: one toolbar above the list. */
.pl-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 14px;
}
.pl-count {
  font-weight: 600;
  color: var(--text);
}
.pl-toolbar-gap {
  flex: 1 1 auto;
}
.pl-menu {
  position: relative;
}
.pl-menu > summary {
  list-style: none;
  cursor: pointer;
}
.pl-menu > summary::-webkit-details-marker {
  display: none;
}
.pl-menu > summary::after {
  content: '';
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-left: 8px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
}
.pl-menu-body {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  z-index: 60;
  width: min(380px, calc(100vw - 32px));
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.pl-menu-action {
  align-self: flex-start;
}
.pl-menu-help {
  display: flex;
  flex-direction: column;
  gap: 4px;
  line-height: 1.45;
}
.pl-grid-bar {
  display: none;
  gap: 12px;
  align-items: center;
  margin-bottom: 8px;
}
.pl-grid-bar.open {
  display: flex;
}

/* Adding or editing a product: a sheet on the right, the list still there behind it. */
#product-library-form.pl-sheet {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(560px, 100vw);
  margin: 0;
  z-index: 140;
  background: var(--surface);
  border-left: 1px solid var(--border);
  box-shadow: var(--shadow);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 0 20px calc(20px + env(safe-area-inset-bottom, 0px));
  animation: pl-sheet-in 0.2s ease-out;
}
.pl-sheet-head {
  position: sticky;
  top: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: calc(16px + env(safe-area-inset-top, 0px)) 0 12px;
  margin-bottom: 12px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}
.pl-sheet-title {
  font: 600 var(--text-lg) / 1.3 var(--font-body);
  color: var(--text);
}
.pl-sheet-close {
  appearance: none;
  border: 0;
  flex: 0 0 32px;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--surface-2);
  color: var(--text-secondary);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}
.pl-sheet-close:hover {
  color: var(--text);
}
.pl-sheet-foot {
  position: sticky;
  bottom: calc(-20px - env(safe-area-inset-bottom, 0px));
  z-index: 2;
  display: flex;
  gap: 8px;
  margin: 16px -20px 0;
  padding: 12px 20px calc(12px + env(safe-area-inset-bottom, 0px));
  background: var(--surface);
  border-top: 1px solid var(--border);
}
.pl-sheet-backdrop {
  position: fixed;
  inset: 0;
  z-index: 139;
  background: var(--scrim);
  animation: pl-fade 0.2s ease-out;
}
body.pl-sheet-open {
  overflow: hidden;
}
@keyframes pl-sheet-in {
  from {
    transform: translateX(24px);
    opacity: 0;
  }
  to {
    transform: none;
    opacity: 1;
  }
}
@keyframes pl-fade {
  from {
    opacity: 0;
  }
}
@media (prefers-reduced-motion: reduce) {
  #product-library-form.pl-sheet,
  .pl-sheet-backdrop {
    animation: none;
  }
}
@media (max-width: 768px) {
  .pl-toolbar-gap {
    display: none;
  }
  .pl-count {
    flex: 1 0 100%;
  }
  #product-library-form.pl-sheet {
    border-left: 0;
  }
}

/* Products tab, calmer type: panel titles in the interface face inside this tab, and the sheet's
   field groups named once instead of every label shouting in capitals. */
#tab-products .overview-panel-title {
  font-family: var(--font-body);
  font-size: var(--text-lg);
  font-weight: 600;
  letter-spacing: 0;
}
.pl-sheet-section {
  margin: 22px 0 10px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
  font: 600 var(--text-base) / 1.3 var(--font-body);
  color: var(--text);
}
#product-library-form.pl-sheet .form-label {
  text-transform: none;
  letter-spacing: 0;
  font-weight: 500;
  color: var(--text-secondary);
}
@media (max-width: 768px) {
  .pl-toolbar > .btn,
  .pl-toolbar > .pl-menu {
    flex: 1 1 calc(50% - 4px);
  }
  .pl-menu > summary {
    width: 100%;
    justify-content: center;
  }
}
/* On a phone the sheet's two-column rows (numeric price beside stock) stack. The rows are inline
   flex in the markup, so the override has to be !important, and is scoped to the sheet alone. */
@media (max-width: 480px) {
  #product-library-form.pl-sheet [style*='display:flex'] {
    flex-wrap: wrap;
  }
  #product-library-form.pl-sheet [style*='display:flex'] > .form-group {
    flex: 1 1 100% !important;
    min-width: 0 !important;
  }
}

/* ── Products > Rates: the rate board, grouped by metal (renderOneBoard in ui/product-library.js) ──
   The board was a row of grey boxes with "/g" hanging outside each one, a status sentence set in the
   display face at title size, and an "add" pair whose placeholders read as rates already set. Now:
   the board's name as the title, the status as one quiet line with a dot, each metal a group, and
   the currency and unit inside the box they qualify. */
.rate-board .overview-panel-head {
  align-items: flex-start;
}
.rate-status {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin: 4px 0 0;
  font-size: var(--text-sm);
  line-height: 1.45;
  color: var(--text-secondary);
}
.rate-status-dot {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--dim);
  transform: translateY(-1px);
}
.rate-status.tone-ok .rate-status-dot {
  background: var(--primary);
}
.rate-status.tone-warn {
  color: var(--warn-fg);
}
.rate-status.tone-warn .rate-status-dot {
  background: var(--amber);
}
.rate-set-at {
  color: var(--dim);
  font-weight: 500;
  white-space: nowrap;
}
.rate-groups {
  display: grid;
  gap: 18px;
  margin: 16px 0 4px;
}
.rate-group-title {
  margin: 0 0 8px;
  font: 600 var(--text-xs) / 1.2 var(--font-body);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-secondary);
}
.rate-group-hint {
  margin: -2px 0 8px;
  font-size: var(--text-xs);
  color: var(--dim);
}
.rate-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(176px, 1fr));
  gap: 10px;
}
.rate-cell {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
  margin: 0;
  padding: 10px 12px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
}
.rate-cell.is-stale {
  border-color: var(--warn-border);
  background: var(--warn-bg);
}
.rate-cell-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 6px;
}
.rate-key {
  font: 600 var(--text-sm) / 1.2 var(--font-mono);
  color: var(--text);
}
.rate-flag {
  font-size: var(--text-2xs);
  font-weight: 600;
  color: var(--warn-fg);
  white-space: nowrap;
}
.rate-value {
  font: 600 var(--text-lg) / 1.2 var(--font-body);
  font-variant-numeric: tabular-nums;
}
/* One field with its currency and unit inside it, drawn as the house .form-input draws a field. */
.rate-input {
  display: flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
  padding: 0 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  transition: var(--transition);
}
.rate-input:focus-within {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-glow);
}
.rate-cell.is-stale .rate-input {
  border-color: var(--amber);
  background: var(--surface);
}
.rate-input input {
  flex: 1 1 auto;
  min-width: 0;
  width: 100%;
  padding: 9px 0;
  border: 0;
  background: transparent;
  color: var(--text);
  font: 600 var(--text-base) / 1.2 var(--font-body);
  font-variant-numeric: tabular-nums;
  outline: none;
}
.rate-affix {
  flex: none;
  font-size: var(--text-sm);
  color: var(--dim);
}
.rate-cell .board-trend {
  margin-top: 0;
}
.rate-del {
  align-self: flex-start;
}
.rate-add {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  margin: 14px 0 16px;
  padding-top: 14px;
  border-top: 1px dashed var(--border);
}
.rate-add-title {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-secondary);
}
.rate-add-fields {
  display: flex;
  flex: 1 1 320px;
  gap: 8px;
  min-width: 0;
}
.rate-add-key {
  flex: 1 1 55%;
  min-width: 0;
}
.rate-add-fields .rate-input {
  flex: 1 1 45%;
}
.rate-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}
/* The "916 has no rate" fix, as a notice above the rates it points at. */
.rate-board .board-aliases {
  margin: 14px 0 0;
  padding: 10px 12px;
  border: 1px solid var(--warn-border);
  border-radius: var(--radius-sm);
  background: var(--warn-bg);
}
.rate-board .board-alias .form-input {
  width: auto;
  min-width: 0;
  padding: 6px 10px;
  font-size: var(--text-sm);
  background: var(--surface);
}
.rate-board .board-alias-set {
  background: var(--surface);
}
.rate-board .board-aliases:not(:has(.board-alias:not(.board-alias-set))) {
  border-color: var(--border);
  background: var(--surface-2);
}
@media (max-width: 480px) {
  .rate-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .rate-add-fields {
    flex-basis: 100%;
  }
  .rate-board .board-alias {
    flex-wrap: wrap;
  }
  .rate-actions > .btn {
    flex: 1 1 calc(50% - 4px);
  }
}

/* ── Rates: a group's unit switch (silver per kg) and the buying side under each rate ─────────── */
.rate-group-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin: 0 0 8px;
}
.rate-group-head .rate-group-title {
  margin: 0;
}
.rate-unit-switch {
  display: inline-flex;
  padding: 2px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-2);
}
.rate-unit-btn {
  padding: 3px 10px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--text-secondary);
  font: 500 var(--text-xs) / 1.3 var(--font-body);
  cursor: pointer;
}
.rate-unit-btn.active {
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-sm);
}
.rate-unit-btn:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 1px;
}
/* Products' four tabs and a count badge do not fit a 390 px phone with their icons: the house bar
   scrolls, with its scrollbar hidden, so Channels was simply cut off at the edge (seen on
   production, 2026-10-04). Below 420 px the labels carry the tabs alone. */
@media (max-width: 420px) {
  #pl-tabs .eh-tab-icon {
    display: none;
  }
  #pl-tabs .eh-cat-btn {
    gap: 5px;
  }
}

/* ── Rates: field errors and the save note (renderOneBoard, 2026-10-04) ───────────────────────────
   An error sits under the box it is about; a refused save says so above Save, where the shop is
   looking; a saved board keeps saying so after the redraw. */
.rate-field-error:empty {
  display: none;
}
.rate-field-error {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--danger-fg);
}
.rate-input.is-invalid,
.rate-input.is-invalid:focus-within,
.rate-board .form-input.is-invalid {
  border-color: var(--danger-border);
  box-shadow: 0 0 0 3px var(--danger-bg);
}
.rate-board-error {
  margin: 0 0 12px;
  padding: 10px 12px;
  border: 1px solid var(--danger-border);
  border-radius: var(--radius-sm);
  background: var(--danger-bg);
  color: var(--danger-fg);
  font-size: var(--text-sm);
  font-weight: 500;
}
.rate-save-note {
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.rate-save-note.ok {
  color: var(--ok-fg);
  font-weight: 600;
}

/* ── Products > Buying: the counter appraisal and buying terms (ui/appraisals.js, 2026-10-04) ─────
   The sheets are the product sheet's pattern (.pl-sheet-head/-foot/-section/-backdrop); only the
   container is named here. Mobile first: this screen is used on a phone at the counter. */
.ap-sheet {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(560px, 100vw);
  margin: 0;
  z-index: 140;
  background: var(--surface);
  border-left: 1px solid var(--border);
  box-shadow: var(--shadow);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 0 20px calc(20px + env(safe-area-inset-bottom, 0px));
  animation: pl-sheet-in 0.2s ease-out;
}
.ap-sheet .form-label {
  text-transform: none;
  letter-spacing: 0;
  font-weight: 500;
  color: var(--text-secondary);
}
.ap-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 14px 0 4px;
}
.ap-list-title {
  margin: 20px 0 8px;
}
.ap-list {
  display: grid;
  gap: 8px;
}
.ap-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  text-align: start;
  cursor: pointer;
  transition: var(--transition);
}
.ap-row:hover {
  border-color: var(--primary);
}
.ap-row:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}
.ap-row-main,
.ap-row-side {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.ap-row-side {
  align-items: flex-end;
  flex: none;
}
.ap-row-ref {
  font: 600 var(--text-sm) / 1.2 var(--font-mono);
}
.ap-row-who {
  font-size: var(--text-xs);
  color: var(--text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ap-row-total {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.ap-chip {
  padding: 1px 8px;
  border-radius: 999px;
  font-size: var(--text-2xs);
  font-weight: 600;
  background: var(--surface-2);
  color: var(--text-secondary);
  white-space: nowrap;
}
.ap-chip-shared {
  background: var(--info-bg);
  color: var(--info-fg);
}
.ap-chip-accepted {
  background: var(--ok-bg);
  color: var(--ok-fg);
}
.ap-chip-expired,
.ap-chip-declined {
  background: var(--surface-2);
  color: var(--dim);
}
.ap-empty {
  margin: 4px 0 0;
}
.ap-intro {
  margin: 4px 0 12px;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.ap-hint {
  margin: -4px 0 6px;
}
.ap-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}
.ap-grid .form-group {
  margin: 0;
}
.ap-seg {
  display: inline-flex;
  padding: 3px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-2);
}
.ap-seg-btn {
  padding: 6px 16px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--text-secondary);
  font: 600 var(--text-sm) / 1.2 var(--font-body);
  cursor: pointer;
}
.ap-seg-btn.active {
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-sm);
}
.ap-seg-btn:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 1px;
}
.ap-piece {
  position: relative;
  margin: 0 0 10px;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
}
.ap-piece .form-group {
  margin: 0 0 10px;
}
.ap-piece-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 0 0 8px;
}
.ap-piece-n {
  font: 600 var(--text-xs) / 1.2 var(--font-body);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-secondary);
}
.ap-piece-remove.line-remove {
  position: static;
}
.ap-check {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 10px;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.ap-narrow {
  max-width: 180px;
}
.ap-unit {
  flex: none;
  padding: 6px 4px;
  border: 0;
  background: transparent;
  color: var(--text-secondary);
  font: 500 var(--text-sm) / 1.2 var(--font-body);
}
.ap-piece-result {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
}
.ap-piece-result:empty {
  display: none;
}
.ap-value {
  font: 600 var(--text-lg) / 1.2 var(--font-body);
  font-variant-numeric: tabular-nums;
}
.ap-working {
  font-size: var(--text-xs);
  color: var(--text-secondary);
}
.ap-add {
  margin: 2px 0 8px;
}
.ap-foot {
  align-items: center;
  justify-content: space-between;
}
.ap-total {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.ap-total-label {
  font-size: var(--text-xs);
  color: var(--text-secondary);
}
.ap-total-value {
  font: 700 var(--text-lg) / 1.2 var(--font-body);
  font-variant-numeric: tabular-nums;
}
.ap-total-value.is-hint {
  font: 500 var(--text-sm) / 1.3 var(--font-body);
  color: var(--text-secondary);
}
.ap-summary {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin: 4px 0 2px;
}
.ap-summary-total {
  font: 700 var(--text-xl) / 1.2 var(--font-body);
  font-variant-numeric: tabular-nums;
}
.ap-send {
  margin: 14px 0 0;
}
.ap-send-error {
  margin-top: 8px;
  font-size: var(--text-sm);
  color: var(--danger-fg);
}
.ap-send-error:empty {
  display: none;
}
.ap-qr {
  display: flex;
  align-items: flex-start;
  gap: 14px;
}
.ap-qr canvas {
  flex: none;
  width: 160px;
  height: 160px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  image-rendering: pixelated;
}
.ap-qr .hint-text {
  margin: 0 0 8px;
}
.ap-copy {
  margin: 0;
  padding: 12px;
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  font: 400 var(--text-sm) / 1.5 var(--font-body);
  white-space: pre-wrap;
  word-break: break-word;
}
.ap-term {
  padding: 10px 0 12px;
  border-bottom: 1px solid var(--border);
}
.ap-term:last-of-type {
  border-bottom: 0;
}
.ap-switch {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
}
.ap-term-label {
  font-weight: 600;
  color: var(--text);
}
.ap-term-route {
  margin: 2px 0 8px 26px;
}
.ap-term-fields {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 8px;
  margin: 0 0 6px 26px;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.ap-term-value {
  width: 96px;
  background: var(--surface);
}
.ap-term-value input {
  padding: 6px 0;
  text-align: end;
}
.ap-term-today {
  margin: 2px 0 0 26px;
  font-size: var(--text-xs);
  color: var(--ok-fg);
}
.ap-term-today.is-blocked {
  color: var(--warn-fg);
}
.ap-term-today:empty {
  display: none;
}
.ap-term:not(.is-on) .ap-term-fields,
.ap-term:not(.is-on) .ap-term-today {
  opacity: 0.65;
}
.ap-row-chat {
  color: var(--primary);
  font-weight: 600;
}
.ap-send-fix {
  margin-top: 8px;
}
.ap-modes {
  margin: 0 0 14px;
  padding: 0;
  border: 0;
  min-width: 0;
}
.ap-modes legend {
  padding: 0;
  margin: 0 0 8px;
}
.ap-mode {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 8px 0;
  cursor: pointer;
}
.ap-mode input {
  margin-top: 3px;
  flex: none;
}
.ap-mode strong {
  display: block;
  font-size: var(--text-sm);
  color: var(--text);
}
.ap-mode .hint-text {
  display: block;
  margin: 2px 0 0;
}
.ap-delivery {
  padding: 12px 0 4px;
  border-top: 1px solid var(--border);
}
.ap-delivery .hint-text {
  margin: 4px 0 8px;
}
@media (prefers-reduced-motion: reduce) {
  .ap-sheet {
    animation: none;
  }
}
@media (max-width: 768px) {
  .ap-sheet {
    border-left: 0;
  }
}
@media (max-width: 480px) {
  .ap-grid {
    grid-template-columns: 1fr;
  }
  .ap-actions > .btn {
    flex: 1 1 calc(50% - 4px);
  }
  .ap-qr {
    flex-direction: column;
  }
}
/* The Buying panel's own status line and list heading: the rate board's look, its own names, so a
   selector for one board never reaches the other. */
.ap-status {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin: 4px 0 0;
  font-size: var(--text-sm);
  line-height: 1.45;
  color: var(--text-secondary);
}
.ap-status-dot {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--dim);
  transform: translateY(-1px);
}
.ap-status.tone-ok .ap-status-dot {
  background: var(--primary);
}
.ap-status.tone-warn {
  color: var(--warn-fg);
}
.ap-status.tone-warn .ap-status-dot {
  background: var(--amber);
}
.ap-list-title {
  font: 600 var(--text-xs) / 1.2 var(--font-body);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-secondary);
}

/* Costs > "Where chats and sales came from" on a phone: the traced-revenue summary goes under the
   title instead of squeezing it into a column one word wide. */
@media (max-width: 768px) {
  #cost-ctwa-panel .overview-panel-head {
    flex-wrap: wrap;
    row-gap: 6px;
  }
  #cost-ctwa-panel .overview-panel-head > div {
    flex: 1 1 100%;
  }
}

/* ── Instagram bio page dialog (qr-codes.js, services/instagram-posts.mjs) ── */
.qrc-thumb img {
  width: 40px;
  height: 40px;
  display: block;
  object-fit: cover;
  border-radius: var(--radius-xs);
}
.qrc-ig-head {
  display: grid;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}
.qrc-ig-link {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}
.qrc-ig-link code {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  overflow-wrap: anywhere;
}
.qrc-ig-error {
  color: var(--danger-fg);
  font-size: var(--text-sm);
}
.qrc-ig-list {
  display: grid;
  gap: var(--space-3);
}
.qrc-ig-post {
  display: grid;
  grid-template-columns: 56px 1fr auto;
  gap: var(--space-3);
  align-items: start;
}
.qrc-ig-post.is-hidden {
  opacity: 0.6;
}
.qrc-ig-post > img,
.qrc-ig-nopic {
  width: 56px;
  height: 56px;
  object-fit: cover;
  border-radius: var(--radius-xs);
  background: var(--surface-2);
  display: block;
}
.qrc-ig-about {
  font-weight: 600;
}
.qrc-ig-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  justify-content: flex-end;
}
.qrc-ig-pick {
  margin-top: var(--space-2);
  display: grid;
  gap: var(--space-2);
}
.qrc-ig-pick[hidden] {
  display: none;
}
@media (max-width: 768px) {
  .qrc-ig-post {
    grid-template-columns: 56px 1fr;
  }
  .qrc-ig-actions {
    grid-column: 1 / -1;
    justify-content: flex-start;
  }
}

/* Instagram as a channel (docs/INSTAGRAM_EXTENSION_SCOPE_2026-10-09.md): the dialog's health line,
   its three tabs, the comments list and the reply settings; the thread's channel mark and its quiet
   event rows; the composer's Instagram strip. */
.qrc-ig-banner {
  margin: 0;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--warn-border);
  background: var(--warn-bg);
  color: var(--warn-fg);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
}
.qrc-ig-tabs {
  display: flex;
  gap: var(--space-1);
  border-bottom: 1px solid var(--border-subtle);
  margin-bottom: var(--space-3);
}
.qrc-ig-tab {
  background: none;
  border: 0;
  border-bottom: 2px solid transparent;
  padding: var(--space-2) var(--space-3);
  font: inherit;
  color: inherit;
  cursor: pointer;
}
.qrc-ig-tab.is-active {
  border-bottom-color: var(--primary);
  font-weight: 600;
}
.qrc-ig-comment {
  display: grid;
  gap: var(--space-1);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--border-subtle);
}
.qrc-ig-comment .btn {
  justify-self: start;
}
.qrc-ig-said {
  overflow-wrap: anywhere;
}
.qrc-ig-warm {
  display: grid;
  gap: var(--space-1);
  margin-bottom: var(--space-4);
}
.qrc-ig-fieldset {
  border: 0;
  padding: 0;
  margin: 0 0 var(--space-3);
  display: grid;
  gap: var(--space-1);
}
.qrc-ig-radio {
  display: flex;
  gap: var(--space-2);
  align-items: baseline;
  margin: var(--space-1) 0;
}
.msg-channel-mark {
  font-size: var(--text-xs);
  opacity: 0.75;
  margin-right: var(--space-1);
}
.msg-event-row {
  text-align: center;
  font-size: var(--text-xs);
  color: var(--text-secondary, inherit);
  opacity: 0.8;
  margin: var(--space-2) auto;
  max-width: 85%;
  overflow-wrap: anywhere;
}
.inbox-ig-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  padding: var(--space-1) 0;
}
.inbox-ig-strip[hidden] {
  display: none;
}
@media (max-width: 768px) {
  .qrc-ig-tabs {
    overflow-x: auto;
  }
  .msg-event-row {
    max-width: 100%;
  }
}

/* ── Where a reply goes (inbox.js renderInstagramStrip, services/delivery-route.mjs) ── */
.inbox-route {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--text-secondary);
  min-width: 0;
  overflow-wrap: anywhere;
}
.inbox-route-dot {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--dim);
}
.inbox-route-whatsapp {
  background: var(--primary);
}
.inbox-route-instagram {
  background: var(--channel-instagram);
}
/* The reply-channel switch in the thread header: one two-way control, cost on it, nothing to read. */
.inbox-route-switch {
  display: inline-flex;
  border: 1px solid var(--border-light);
  border-radius: 999px;
  padding: 2px;
  gap: 2px;
}
.inbox-route-switch[hidden] {
  display: none;
}
.inbox-route-seg {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font: inherit;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--dim);
  background: none;
  border: 0;
  border-radius: 999px;
  padding: 3px 10px;
  cursor: pointer;
  white-space: nowrap;
}
.inbox-route-seg.on {
  color: var(--text);
  background: var(--surface-2);
}
.inbox-route-free {
  font-weight: 700;
  color: var(--primary);
}

/* ── Owner alerts card in Settings (ui/owner-alerts.js, services/owner-alerts.mjs) ── */
.oa-morning-control { display: flex; align-items: center; gap: var(--space-2); }
.oa-hour { display: inline-flex; align-items: center; gap: var(--space-1); font-size: var(--text-sm); color: var(--text-secondary); }
.oa-problem { color: var(--warning); }
.oa-actions { flex-wrap: wrap; gap: var(--space-2); }
.oa-preview { white-space: pre-wrap; font-size: var(--text-sm); background: var(--surface-2); padding: var(--space-3); border-radius: 8px; max-width: 100%; overflow-wrap: anywhere; }
.oa-alerts { list-style: none; margin: var(--space-2) 0 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-1); }
.oa-alert { display: flex; gap: var(--space-2); font-size: var(--text-sm); align-items: baseline; min-width: 0; }
.oa-alert-text { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.oa-alert-time, .oa-alert-status { color: var(--text-secondary); white-space: nowrap; }
.oa-sent { color: var(--primary); }
.oa-failed { color: var(--warning); }

/* An Instagram link suggestion: who, why it is only a suggestion, and the one-tap fix (inbox.js). */
.detail-field.ig-suggestion { flex-wrap: wrap; justify-content: flex-start; }
.ig-suggestion .detail-fv { flex: 1 1 100%; text-align: start; font-weight: 400; color: var(--text-secondary); }
.ig-suggestion-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); }

/* The house tab bar bleeds to the edges by the main column's padding, which is 16px at 768px and
   below (.dash-main) but stayed -24px until 600px: 8px of sideways scroll on Pages & QR and EventsHub
   between 601 and 768px (measured 2026-10-12). */
@media (min-width: 601px) and (max-width: 768px) {
  .eh-tabs {
    margin-left: -16px;
    margin-right: -16px;
    padding: 0 16px;
  }
}

/* ── A product's design details, relations and photo roles (docs/PIM_REQUIREMENTS_2026-10-13.md) ─
   A multi-choice detail is a row of tick boxes that wraps; a relation is a chip with a remove;
   a photo's role is a small select under its thumbnail. */
.attr-multi { display: flex; flex-wrap: wrap; gap: 6px 14px; padding: 6px 0; }
.attr-multi-option { display: inline-flex; align-items: center; gap: 6px; font-size: var(--text-sm); white-space: nowrap; }
.rel-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }
.rel-chips:empty { display: none; }
.rel-chip {
  display: inline-flex; align-items: center; gap: 4px; padding: 3px 4px 3px 10px;
  border: 1px solid var(--border); border-radius: 999px; background: var(--surface-2); font-size: var(--text-sm);
}

/* What a release filled in on existing products (product-library.js renderUpgradeNotice). One line
   that wraps its two buttons under the text on a phone rather than squeezing them. */
.pl-upgrade-notice {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  margin: 8px 0;
  padding: 8px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-2);
  font-size: 0.875rem;
}
.pl-upgrade-notice > span:first-child {
  flex: 1 1 240px;
  min-width: 0;
}
.pl-upgrade-actions {
  display: flex;
  gap: 8px;
}

/* ── The counter (ui/counter.js): the Settings card and the inbox thread strip ─────────────────── */
.ctr-hours { display: grid; gap: var(--space-2); }
.ctr-day { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.ctr-day-name { width: 3.5em; color: var(--text-secondary); font-size: var(--text-sm); }
.ctr-time { width: 7.5em; }
.ctr-closed { font-size: var(--text-xs); color: var(--text-secondary); }
.ctr-num { width: 5em; }
.ctr-modes { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.ctr-mode { display: inline-flex; align-items: center; gap: var(--space-1); font-size: var(--text-sm); }
.ctr-insight { padding-top: var(--space-3); border-top: 1px solid var(--border-light); }
.ctr-list { margin: var(--space-2) 0 0; padding-left: var(--space-5); display: grid; gap: var(--space-1); font-size: var(--text-sm); }
.ctr-muted { color: var(--text-secondary); font-size: var(--text-xs); }
.ctr-strip { display: grid; gap: var(--space-2); padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--border-light); background: var(--surface-2); }
.ctr-strip-title { font-size: var(--text-xs); font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-secondary); }
.ctr-item { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.ctr-badge { padding: 2px var(--space-2); border-radius: var(--radius-xs); font-size: var(--text-xs); font-weight: 600; background: var(--surface-3); color: var(--text); }
.ctr-badge.ctr-open, .ctr-badge.ctr-waiting_book { background: var(--warn-bg); color: var(--warn-fg); }
.ctr-badge.ctr-live { background: var(--ok-bg); color: var(--ok-fg); }
.ctr-badge.ctr-hold { background: var(--info-bg); color: var(--info-fg); }
.ctr-facts { flex: 1 1 12em; min-width: 0; font-size: var(--text-sm); color: var(--text); overflow-wrap: anywhere; }
.ctr-actions { display: inline-flex; gap: var(--space-1); flex-wrap: wrap; }
@media (max-width: 768px) {
  .ctr-item { align-items: flex-start; }
  .ctr-actions { width: 100%; }
  .ctr-actions .btn { flex: 1 1 auto; min-height: 40px; }
}

/* The Available / Away row in the account menu is hidden for the workspace owner (header.js
   wireAvailability); the menu item's own display rule must not override that. */
.account-menu-item[hidden] { display: none; }

/* ── Outlets (ui/outlets.js, Retail operations): the Settings card ──────────────────────────────── */
.out-list { display: grid; gap: var(--space-3); }
.out-row { display: flex; align-items: flex-start; gap: var(--space-3); padding: var(--space-3) 0; border-bottom: 1px solid var(--border-light); }
.out-row.is-closed .out-name { color: var(--text-secondary); }
.out-main { flex: 1 1 16em; min-width: 0; display: grid; gap: 2px; }
.out-name { font-weight: 600; }
.out-badge { padding: 1px var(--space-2); border-radius: var(--radius-xs); font-size: var(--text-xs); font-weight: 600; background: var(--surface-3); color: var(--text-secondary); }
.out-more { font-size: var(--text-xs); color: var(--text-secondary); overflow-wrap: anywhere; }
.out-actions { display: inline-flex; gap: var(--space-1); flex-wrap: wrap; }
.out-form { display: grid; gap: var(--space-3); padding: var(--space-3); border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface-2); }
.out-field { display: grid; gap: var(--space-1); }
.out-inline { display: inline-flex; align-items: center; gap: var(--space-2); }
.out-team { display: flex; flex-wrap: wrap; gap: var(--space-3); }
/* The hours block is hidden until "Its own opening hours" is on; .ctr-hours sets display: grid. */
.out-hours[hidden] { display: none; }
@media (max-width: 768px) {
  .out-row { flex-direction: column; }
  .out-actions .btn { flex: 1 1 auto; min-height: 40px; }
}

/* Product sheet: how a worked-out price is made (product-library.js loadPriceBreakdown). */
.pl-breakdown { border: 1px solid var(--border); border-radius: var(--radius); padding: 10px 12px; margin: 4px 0 12px; }
.pl-breakdown-title { font-weight: 600; color: var(--text); margin-bottom: 6px; }
.pl-breakdown-row { display: flex; justify-content: space-between; gap: 12px; padding: 2px 0; font-variant-numeric: tabular-nums; }
.pl-breakdown-total { border-top: 1px solid var(--border); margin-top: 6px; padding-top: 6px; font-weight: 600; color: var(--text); }

/* Product sheet: the photos to post to Instagram (product-library.js openInstagramPanel). */
.pl-ig-photos { display: flex; gap: 8px; flex-wrap: wrap; margin: 8px 0 10px; }
.pl-ig-photo { position: relative; width: 88px; display: flex; flex-direction: column; align-items: center; gap: 4px; font-size: 12px; color: var(--text-secondary); cursor: pointer; }
.pl-ig-photo img, .pl-ig-photo video { width: 88px; height: 88px; object-fit: cover; border-radius: var(--radius); border: 1px solid var(--border); background: var(--surface-2); }
.pl-ig-photo input { position: absolute; top: 4px; left: 4px; }
.pl-ig-photo.is-off { opacity: 0.5; cursor: not-allowed; }

/* ── Posts view in Products (ui/posts.js): the next post waiting for a yes, then the coming days ── */
.posts-blocked { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 14px; margin-bottom: 14px; border: 1px solid var(--warn-border); background: var(--warn-bg); color: var(--warn-fg); border-radius: var(--radius); }
.posts-subhead { font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-secondary); margin: 6px 0 8px; }
.posts-empty { color: var(--text-secondary); margin: 4px 0 12px; }
.posts-card { display: grid; grid-template-columns: 220px 1fr; gap: 18px; padding: 14px; border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--surface); }
.posts-photo { width: 220px; height: 220px; object-fit: cover; border-radius: var(--radius); border: 1px solid var(--border); background: var(--surface-2); }
.posts-photo-none { display: block; background: var(--surface-2); }
.posts-card-body { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.posts-when { display: flex; align-items: center; gap: 8px; font-weight: 600; color: var(--text); }
.posts-name { font-family: var(--font-display); font-size: var(--text-lg); margin: 0; color: var(--text); }
.posts-why { margin: 0; color: var(--text-secondary); }
.posts-outcome { margin: 2px 0 0; padding: 8px 10px; border-radius: var(--radius-sm); background: var(--ok-bg); color: var(--ok-fg); font-weight: 500; }
.posts-reason { margin: 0; color: var(--danger-fg); }
.posts-caption { margin: 4px 0 0; color: var(--text); white-space: pre-line; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.posts-caption-edit { width: 100%; font: inherit; padding: 8px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); color: var(--text); }
.posts-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.posts-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.posts-small { font-size: var(--text-sm); }
.posts-chip { font-size: var(--text-xs); font-weight: 500; padding: 2px 8px; border-radius: 999px; background: var(--surface-2); color: var(--text-secondary); }
.posts-chip-draft { background: var(--warn-bg); color: var(--warn-fg); }
.posts-chip-approved, .posts-chip-published { background: var(--ok-bg); color: var(--ok-fg); }
.posts-chip-failed { background: var(--danger-bg); color: var(--danger-fg); }
.posts-tiles { display: flex; gap: 10px; overflow-x: auto; padding-bottom: 4px; }
.posts-tile { flex: 0 0 auto; width: 112px; display: flex; flex-direction: column; align-items: flex-start; gap: 4px; padding: 6px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); cursor: pointer; text-align: left; font: inherit; color: var(--text); }
.posts-tile img, .posts-tile .posts-photo-none { width: 100px; height: 100px; object-fit: cover; border-radius: var(--radius-sm); }
.posts-tile-when { font-size: var(--text-xs); color: var(--text-secondary); }
.posts-how { margin: 14px 0 0; color: var(--text-secondary); }
.posts-settings { display: flex; flex-direction: column; gap: 10px; margin-top: 14px; padding: 12px; border: 1px solid var(--border); border-radius: var(--radius); }
.posts-settings fieldset { border: 0; padding: 0; margin: 0; display: flex; flex-wrap: wrap; gap: 8px 14px; align-items: center; }
.posts-settings legend { font-weight: 600; margin-bottom: 4px; color: var(--text); }
.posts-choice { display: inline-flex; align-items: center; gap: 6px; color: var(--text); }
.posts-link { background: none; border: 0; padding: 0; font: inherit; color: var(--primary); cursor: pointer; text-decoration: underline; text-underline-offset: 2px; }
.posts-link:hover { color: var(--primary-dark); }
.posts-occasion-ask { padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius-sm); margin: 4px 0 8px; }
.posts-occasion-q { margin: 0 0 2px; font-weight: 600; color: var(--text); }
.posts-occasions { list-style: none; padding: 0; margin: 4px 0 8px; display: flex; flex-direction: column; gap: 4px; }
.posts-occasions li { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; padding: 8px 0; border-bottom: 1px solid var(--border); }
.posts-occasions li:last-child { border-bottom: none; }
.posts-occasion-twin { flex-basis: 100%; color: var(--warn-fg); }
.posts-occasion-warn { background: var(--warn-bg); border-color: var(--warn-border); }
.posts-occasion-warn .posts-occasion-q { color: var(--warn-fg); }
.posts-occasion-actions { display: flex; gap: 14px; margin-left: auto; }
.posts-outcome:empty { display: none; }
.pl-cover-preview { display: block; width: 112px; height: 112px; object-fit: cover; border-radius: var(--radius-sm); border: 1px solid var(--border); margin: 4px 0 8px; }
.pl-cover-preview[hidden] { display: none; }
.pl-photo-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.health-chip { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 999px; background: var(--warn-bg); color: var(--warn-fg); font-size: var(--text-sm); font-weight: 500; text-decoration: none; white-space: nowrap; }
.health-chip:hover { text-decoration: underline; }
.health-chip-short { display: none; }
.trial-chip { display: inline-flex; align-items: center; padding: 4px 10px; border-radius: 999px; background: var(--warn-bg); color: var(--warn-fg); font-size: var(--text-sm); font-weight: 600; text-decoration: none; white-space: nowrap; }
.trial-chip:hover { text-decoration: underline; }
.nav-badge-quiet { background: var(--surface-2); color: var(--dim); }
.sidebar-trial { display: none; }
.account-menu-theme { display: none; }
/* The set-up card belongs to the screens about getting set up, not to every screen (2026-10-21). */
body[data-screen]:not([data-screen="today"]):not([data-screen="overview"]) #trial-activation-bar { display: none !important; }
.pl-rates-bar { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; padding: 10px 12px; margin-bottom: 12px; border-radius: var(--radius-sm); background: var(--warn-bg); color: var(--warn-fg); font-weight: 500; }
.pl-rates-bar[hidden] { display: none; }
.pl-bar-actions { display: flex; gap: 8px; flex-wrap: wrap; }
/* Declaring a compliance rule does not apply to the shop (renderComplianceBar): its own row under the bar's line. */
.pl-waive { flex-basis: 100%; display: grid; gap: 8px; font-weight: 400; }
.pl-waive[hidden] { display: none; }
.pl-waive p { margin: 0; }
.pl-waive label { display: flex; gap: 8px; align-items: flex-start; }
.pl-waive input { margin-top: 3px; }
.pl-names-bar { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; padding: 10px 12px; margin-bottom: 12px; border-radius: var(--radius-sm); background: var(--surface-2); color: var(--text); }
.pl-names-bar[hidden] { display: none; }
.pl-bulk-status:not(:empty) { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 8px 0 12px; }
.pl-more { border-top: 1px solid var(--border); padding: 10px 0 2px; margin-top: 4px; }
.pl-more > summary { cursor: pointer; font-weight: 600; color: var(--text); padding: 2px 0 8px; }
.pl-more-inner { border-top: 0; padding-top: 0; margin-top: 0; }
.pl-more-inner > summary { font-weight: 500; color: var(--text-secondary); font-size: var(--text-sm); }
.posts-notice.posts-notice-soft { color: var(--text-secondary); margin: 0 0 8px; }
.posts-notice { margin: 8px 0 0; color: var(--danger); font-size: var(--text-sm); }
.posts-tile-name { display: block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--text-xs); color: var(--text); }
.posts-compose { display: flex; flex-direction: column; gap: 8px; }
.posts-compose-when { border: 0; padding: 0; margin: 4px 0 0; display: flex; flex-direction: column; gap: 6px; }
.posts-compose-when label { display: inline-flex; align-items: center; gap: 8px; color: var(--text); }
.posts-compose-when input[type="datetime-local"] { max-width: 260px; }
/* Posts: the pipeline of coming posts and the post editor (ui/posts.js pipelineHtml, slidesHtml). */
.posts-pipe-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 0 0 8px; }
.posts-pipe-head .posts-subhead { margin: 0; }
.posts-pipeline { display: flex; gap: 10px; overflow-x: auto; padding: 2px 2px 8px; margin-bottom: 14px; scroll-snap-type: x proximity; }
.posts-pipe { flex: 0 0 auto; width: 128px; display: flex; flex-direction: column; align-items: flex-start; gap: 4px; padding: 6px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); cursor: pointer; text-align: left; font: inherit; color: var(--text); scroll-snap-align: start; }
.posts-pipe:hover { border-color: var(--primary); }
.posts-pipe.is-on { border-color: var(--primary); box-shadow: 0 0 0 2px var(--primary); }
.posts-pipe:focus-visible, .posts-strip-item:focus-visible, .posts-strip-add:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.posts-pipe-photo { position: relative; display: block; width: 100%; aspect-ratio: 4 / 5; border-radius: var(--radius-sm); overflow: hidden; background: var(--surface-2); }
.posts-pipe-photo img, .posts-pipe-photo video { width: 100%; height: 100%; object-fit: cover; display: block; }
.posts-pipe-count { position: absolute; right: 4px; bottom: 4px; padding: 1px 6px; border-radius: 999px; font-size: var(--text-xs); background: var(--media-badge-bg); color: var(--media-badge-fg); }
.posts-pipe-when { font-size: var(--text-xs); color: var(--text-secondary); }
.posts-pipe-name { display: block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--text-sm); font-weight: 500; }
.posts-pipe-unsaved { font-size: var(--text-xs); color: var(--warn-fg); }
.posts-card.posts-editor { grid-template-columns: minmax(240px, 340px) 1fr; }
.posts-slides { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.posts-stage { position: relative; width: 100%; aspect-ratio: 4 / 5; border-radius: var(--radius); border: 1px solid var(--border); background: var(--surface-2); overflow: hidden; }
.posts-stage img, .posts-stage video { width: 100%; height: 100%; object-fit: contain; display: block; }
.posts-stage-count { position: absolute; top: 8px; right: 8px; padding: 2px 8px; border-radius: 999px; font-size: var(--text-xs); background: var(--media-badge-bg); color: var(--media-badge-fg); }
.posts-strip { display: flex; flex-wrap: wrap; gap: 6px; }
.posts-strip-item { position: relative; width: 56px; height: 56px; padding: 0; border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: hidden; background: var(--surface-2); cursor: pointer; }
.posts-strip-item img, .posts-strip-item video, .posts-strip-item .posts-photo-none { width: 100%; height: 100%; object-fit: cover; display: block; }
.posts-strip-item.is-on { border-color: var(--primary); box-shadow: 0 0 0 2px var(--primary); }
.posts-strip-cover { position: absolute; left: 0; right: 0; bottom: 0; font-size: 9px; line-height: 14px; text-align: center; background: var(--media-badge-bg); color: var(--media-badge-fg); }
.posts-strip-add { width: 56px; height: 56px; display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 0; padding: 2px; border: 1px dashed var(--border); border-radius: var(--radius-sm); background: none; color: var(--text-secondary); font: inherit; font-size: 9px; line-height: 1.1; cursor: pointer; }
.posts-strip-add span { font-size: 18px; line-height: 1; }
.posts-strip-add:hover { border-color: var(--primary); color: var(--primary); }
.posts-link:disabled { color: var(--text-secondary); text-decoration: none; cursor: default; opacity: 0.6; }
.posts-field { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; font-size: var(--text-sm); color: var(--text-secondary); }
.posts-field input[type="datetime-local"] { max-width: 260px; font: inherit; color: var(--text); }
/* With (collaborators) and Made with AI on a post (ui/posts.js, posts/options.mjs). */
.posts-field input[type="text"], .posts-field select { max-width: 420px; font: inherit; color: var(--text); padding: 6px 8px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); }
.posts-check { display: flex; align-items: center; gap: 8px; margin-top: 6px; font-size: var(--text-sm); color: var(--text); }
/* A Reel's cover picker under the player (ui/posts.js slidesHtml). */
.posts-cover { margin-top: 6px; color: var(--text-secondary); }
/* The Instagram profile check (ui/posts.js profileHtml, services/posts/profile.mjs). */
.posts-profile { display: flex; flex-direction: column; gap: 10px; margin: 0 0 14px; padding: 12px 14px; border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--surface); }
.posts-profile-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.posts-profile-head .posts-subhead { margin: 0; }
.posts-profile-step { display: flex; flex-direction: column; gap: 6px; padding-top: 10px; border-top: 1px solid var(--border); }
.posts-profile-suggest { margin: 0; padding: 8px 10px; white-space: pre-wrap; overflow-wrap: anywhere; font: inherit; color: var(--text); background: var(--surface-2); border-radius: var(--radius-sm); }
.posts-hint { margin: 0; font-size: var(--text-xs); color: var(--text-secondary); }
.posts-savebar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 8px 10px; border: 1px solid var(--warn-border); border-radius: var(--radius-sm); background: var(--warn-bg); color: var(--warn-fg); font-size: var(--text-sm); }
.posts-savebar[hidden] { display: none; }
.posts-savebar span { margin-right: auto; }
/* A published post's first hour (ui/posts.js firstHourHtml): set apart from the post above it. */
.posts-firsthour { display: flex; flex-direction: column; gap: 6px; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border); }
.posts-firsthour .posts-subhead, .posts-firsthour .posts-actions { margin: 0; }
.posts-firsthour .posts-row { gap: 4px 14px; }
#modal-post-composer .modal { max-width: 560px; }
@media (max-width: 768px) {
  .posts-card { grid-template-columns: 1fr; }
  .posts-photo { width: 100%; height: auto; aspect-ratio: 1 / 1; }
  .posts-blocked { flex-direction: column; align-items: flex-start; }
}
@media (max-width: 640px) {
  /* A phone header holds only what a shop uses there: menu, logo, search, the WhatsApp number, the
     account (2026-10-21: it ran to 531px on a 390px screen). Routine notices go to Settings' badge;
     Synced shows only when it is not; the trial countdown heads the menu, with a dot on its button;
     the theme switch moves into the account menu. */
  .health-chip { display: none; }
  .sync-indicator:has(.sync-dot:not(.offline)) { display: none; }
  .dash-header-center .trial-chip { display: none; }
  .sidebar-trial { display: block; margin: 0 12px 12px; text-align: center; }
  .menu-toggle.has-notice { position: relative; }
  .menu-toggle.has-notice::after { content: ''; position: absolute; top: 4px; right: 2px; width: 8px; height: 8px; border-radius: 50%; background: var(--amber); }
  #btn-theme { display: none; }
  .account-menu-theme { display: flex; }
  .dash-logo img { height: 24px !important; }
  .trial-bar-eyebrow { display: none; }
}

/* Products on a phone (2026-10-22). The toolbar was four full-width buttons in two rows, so the
   first product started more than halfway down a 390px screen, and every grid ran one card per
   row. Now: the count and both ways of adding on one line, the table and import/export under it,
   and two cards per row everywhere in the list, including a design's opened pieces. */
@media (max-width: 768px) {
  .pl-toolbar {
    gap: 6px;
  }
  .pl-toolbar .pl-count {
    order: 0;
    flex: 1 1 auto;
  }
  /* Both ways of adding beside the count; the table and import/export on the row under them. */
  .pl-toolbar #product-bulk-btn {
    order: 1;
    flex: 0 0 auto;
  }
  .pl-toolbar #product-library-add-btn {
    order: 2;
    flex: 0 0 auto;
  }
  .pl-toolbar .pl-toolbar-gap {
    display: block;
    order: 3;
    flex: 1 0 100%;
    height: 0;
  }
  .pl-toolbar > .btn:not(#product-library-add-btn):not(#product-bulk-btn),
  .pl-toolbar > .pl-menu {
    order: 4;
    flex: 0 0 auto;
  }
  .pl-toolbar > .btn:not(#product-library-add-btn),
  .pl-toolbar > .pl-menu > summary {
    width: auto;
    padding: 6px 10px;
    font-size: var(--text-sm);
  }
  #product-library-list .media-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
  }
  .design-pieces {
    padding: 8px;
  }
}

/* Products: shelves flow side by side, each as wide as its tiles (renderList, data-tiles), so small
   categories share a row instead of each taking one. A shelf whose design is open, and every shelf
   while products are being ticked, takes the full width so the pieces have room. 172px is one tile
   at the list's grid (150px minimum, 14px gap) on a desktop list. */
@media (min-width: 769px) {
  .product-shelves {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    column-gap: 28px;
  }
  .product-shelves > .product-shelf {
    flex: 0 1 100%;
    min-width: 0;
    max-width: 100%;
  }
  .product-shelves > .product-shelf[data-tiles='1'] {
    flex-basis: 172px;
  }
  .product-shelves > .product-shelf[data-tiles='2'] {
    flex-basis: 358px;
  }
  .product-shelves > .product-shelf[data-tiles='3'] {
    flex-basis: 544px;
  }
  .product-shelves > .product-shelf[data-tiles='4'] {
    flex-basis: 730px;
  }
  .product-shelves > .product-shelf[data-tiles='5'] {
    flex-basis: 916px;
  }
  .product-shelves > .product-shelf:has(.design-tile.is-open),
  #product-library-list.is-selecting .product-shelves > .product-shelf {
    flex-basis: 100%;
  }
}
/* On a phone, a shelf of one product is half a row, so two such shelves pair up as one row of the
   two-column grid. */
@media (max-width: 768px) {
  .product-shelves {
    display: flex;
    flex-wrap: wrap;
    column-gap: 10px;
  }
  .product-shelves > .product-shelf {
    flex: 0 1 100%;
    min-width: 0;
  }
  .product-shelves > .product-shelf[data-tiles='1'] {
    flex-basis: calc(50% - 5px);
  }
  /* #product-library-list, to outrank the list's own two-column phone grid above. */
  #product-library-list .product-shelves > .product-shelf[data-tiles='1'] .product-shelf-grid {
    grid-template-columns: minmax(0, 1fr);
  }
  .product-shelves > .product-shelf:has(.design-tile.is-open),
  #product-library-list.is-selecting .product-shelves > .product-shelf {
    flex-basis: 100%;
  }
  #product-library-list .product-shelves > .product-shelf:has(.design-tile.is-open) .product-shelf-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* Closing a compliance gap where it is reported (fixBlock in ui/product-library.js): the field
   under its reason on the product's own view, and "Add HUID" on the card. */
.pl-status-fix {
  display: inline-block;
  margin: 0 10px 8px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--primary);
  font: 600 var(--text-xs) / 1.4 var(--font-body);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
.pv-fix {
  margin: 6px 0 12px;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-2);
  list-style: none;
}
.pv-fix-row {
  display: flex;
  gap: 8px;
  align-items: center;
}
.pv-fix-row .form-input {
  flex: 1 1 auto;
  min-width: 0;
  font-family: var(--font-mono);
  letter-spacing: 0.08em;
}
.pv-fix [data-tone='amber'] {
  color: var(--amber);
}
.pv-fix [data-tone='red'] {
  color: var(--red);
}
.pv-fix-doc {
  margin-top: 10px;
}
.pv-fix-read {
  display: grid;
  gap: 4px;
  margin-top: 8px;
  font-size: var(--text-sm);
}
.pv-fix-found {
  font-weight: 600;
  color: var(--text);
}
.pv-fix-own,
.pv-fix-codes {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-top: 8px;
}
.pv-fix-own .pv-thumb {
  flex: 0 0 48px;
  width: 48px;
  height: 48px;
}
/* A hallmarking report's rows, matched to pieces (openReport). */
.pv-report {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}
.pv-report th {
  text-align: start;
  font-weight: 600;
  color: var(--dim);
  padding: 6px 8px;
  border-bottom: 1px solid var(--border);
}
.pv-report td {
  padding: 6px 8px;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}
.pv-report .pv-report-code {
  width: 7.5em;
  font-family: var(--font-mono);
  letter-spacing: 0.06em;
}
.pv-report tr.has-problem td {
  background: var(--warn-bg);
}
.pv-report-text pre {
  white-space: pre-wrap;
  font-size: var(--text-xs);
  color: var(--text-secondary);
}
@media (max-width: 768px) {
  .pv-report thead {
    display: none;
  }
  /* Code, weight and purity on one line; the piece and what was found under them. */
  .pv-report tr {
    display: grid;
    grid-template-columns: minmax(0, 8.5em) auto 1fr;
    align-items: center;
    gap: 6px 10px;
    padding: 8px 0;
    border-bottom: 1px solid var(--border);
  }
  .pv-report td {
    border: 0;
    padding: 0;
  }
  .pv-report td:nth-child(4),
  .pv-report td:nth-child(5) {
    grid-column: 1 / -1;
  }
}

/* ── Savings Plans (ui/savings.js) ─────────────────────────────────────────────────────────────── */
.sp-scroll {
  overflow-x: auto;
}
.sp-table td,
.sp-table th {
  vertical-align: top;
}
.sp-num {
  text-align: right;
  font-family: var(--font-mono);
  white-space: nowrap;
}
.sp-sub,
.sp-muted {
  color: var(--text-secondary);
  font-size: var(--text-xs);
}
.sp-row {
  cursor: pointer;
}
.sp-row:hover {
  background: var(--surface-2);
}
.sp-link {
  background: none;
  border: 0;
  padding: 0;
  color: var(--primary);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  text-align: left;
}
.sp-link:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}
.sp-filter {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 140px;
}
.sp-note {
  margin: var(--space-3) 0;
}
.sp-gap {
  margin-top: var(--space-6);
}
.sp-account-head {
  margin: var(--space-4) 0;
}
.sp-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--space-3);
  margin: var(--space-3) 0;
}
.sp-tile {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-4);
}
.sp-tile-good {
  border-color: var(--ok-border);
  background: var(--ok-bg);
}
.sp-tile-warn {
  border-color: var(--warn-border);
  background: var(--warn-bg);
}
.sp-tile-label {
  color: var(--text-secondary);
  font-size: var(--text-sm);
}
.sp-tile-value {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  margin: var(--space-1) 0;
}
.sp-tile-note {
  color: var(--text-secondary);
  font-size: var(--text-xs);
}
.sp-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.sp-chip {
  display: inline-block;
  border-radius: var(--radius-sm);
  padding: 2px var(--space-2);
  font-size: var(--text-xs);
  border: 1px solid var(--border);
  background: var(--surface-2);
  white-space: nowrap;
}
.sp-chip-good {
  background: var(--ok-bg);
  border-color: var(--ok-border);
  color: var(--ok-fg);
}
.sp-chip-warn {
  background: var(--warn-bg);
  border-color: var(--warn-border);
  color: var(--warn-fg);
}
.sp-chip-bad {
  background: var(--danger-bg);
  border-color: var(--danger-border);
  color: var(--danger-fg);
}
.sp-chip-info {
  background: var(--info-bg);
  border-color: var(--info-border);
  color: var(--info-fg);
}
.sp-fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-3);
  margin: var(--space-3) 0;
}
.sp-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
@media (max-width: 768px) {
  .sp-tiles {
    grid-template-columns: 1fr 1fr;
  }
}
@media (max-width: 480px) {
  .sp-tiles,
  .sp-fields {
    grid-template-columns: 1fr;
  }
  .sp-filter {
    min-width: 0;
  }
}

/* Savings Plans coin goal (ui/savings.js goalHtml) */
.sp-goal {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-4);
}
.sp-goal-figure {
  font-family: var(--font-display);
  font-size: var(--text-xl);
}
.sp-progress {
  height: 8px;
  border-radius: 999px;
  background: var(--border);
  overflow: hidden;
  margin: var(--space-2) 0;
}
.sp-progress > span {
  display: block;
  height: 100%;
  background: var(--primary);
}
.sp-goal-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-2);
}

/* Savings Plans: a piece priced with the savings (ui/savings.js billHtml) */
.sp-bill-form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-2);
  margin: var(--space-3) 0;
}
.sp-bill {
  max-width: 560px;
}
.sp-bill .sp-bill-good td {
  color: var(--ok-fg);
}

/* Savings Plans at the counter (ui/savings-counter.js) */
.sp-head-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-2);
}
.sp-check {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: var(--space-2) 0;
}
.sp-kfs {
  padding-inline-start: var(--space-5);
}
.sp-kfs li {
  margin-bottom: var(--space-3);
}
.sp-kfs p {
  margin: var(--space-1) 0 0;
}

/* A screen still loading (ui.js loadTab sets aria-busy after 300 ms): a thin bar along its top and its
   placeholder dimmed, so a slow screen never reads as an empty one ("Loaded 0 synced contacts"). */
.dash-tab[aria-busy='true'] {
  position: relative;
}
.dash-tab[aria-busy='true']::before {
  content: '';
  position: absolute;
  inset: 0 0 auto;
  height: 3px;
  z-index: 5;
  background: linear-gradient(90deg, transparent, var(--primary), transparent) no-repeat;
  background-size: 40% 100%;
  animation: tab-busy 1.1s linear infinite;
}
.dash-tab[aria-busy='true'] > * {
  opacity: 0.45;
  transition: opacity 0.2s;
}
@keyframes tab-busy {
  from {
    background-position: -40% 0;
  }
  to {
    background-position: 140% 0;
  }
}
@media (prefers-reduced-motion: reduce) {
  .dash-tab[aria-busy='true']::before {
    animation: none;
    background: var(--primary);
    opacity: 0.6;
  }
}

/* Posts editor at phone width (ui/posts.js): one column, the slides first. */
@media (max-width: 768px) {
  .posts-card.posts-editor { grid-template-columns: 1fr; }
  .posts-pipe { width: 112px; }
}
