/* ============================================================================
   components.css — ASPAM Admissions CRM component library
   Hand-written. No framework, no build step.
   Load order: tokens.css -> base.css -> components.css -> layout.css
   ----------------------------------------------------------------------------
   CONTENTS
     01 Buttons            08 Tabs                 15 Kanban / pipeline
     02 Form controls      09 Toasts               16 Activity timeline
     03 Cards & panels     10 Empty states         17 Stat tiles
     04 Tables             11 Skeletons            18 Charts (funnel, bars)
     05 Badges & chips     12 Avatars              19 Seat capacity meter
     06 Modals             13 Menus & tooltips     20 SLA indicators
     07 Drawers            14 Misc (alert, kv…)    21 Responsive / touch
   ========================================================================== */

/* ==========================================================================
   01. BUTTONS
   ========================================================================== */

.btn {
  --btn-bg: transparent;
  --btn-fg: var(--text-primary);
  --btn-bd: var(--border-strong);
  --btn-ring: var(--shadow-focus);

  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  height: var(--control-h);
  padding: 0 var(--space-4);
  border: 1px solid var(--btn-bd);
  border-radius: var(--radius-sm);
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-family: var(--font-ui);
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-tight);
  line-height: 1;
  white-space: nowrap;
  text-decoration: none;
  position: relative;
  isolation: isolate;
  transition:
    background-color var(--dur-1) var(--ease-out),
    border-color var(--dur-1) var(--ease-out),
    color var(--dur-1) var(--ease-out),
    box-shadow var(--dur-2) var(--ease-out),
    transform var(--dur-1) var(--ease-out);
}
.btn:hover { text-decoration: none; }
.btn:active:not(:disabled):not([aria-disabled="true"]) { transform: translateY(1px); }
.btn:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 2px; }
.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: 0.46;
  pointer-events: none;
  box-shadow: none;
}

/* — variants — */
.btn-primary {
  --btn-bg: var(--brand);
  --btn-fg: var(--on-brand);
  --btn-bd: var(--brand);
  box-shadow: var(--shadow-xs);
}
.btn-primary:hover { --btn-bg: var(--brand-hover); --btn-bd: var(--brand-hover); box-shadow: var(--shadow-sm); }
.btn-primary:active { --btn-bg: var(--brand-active); }

.btn-secondary {
  --btn-bg: var(--surface-elevated);
  --btn-fg: var(--text-primary);
  --btn-bd: var(--border-strong);
  box-shadow: var(--shadow-xs);
}
.btn-secondary:hover { --btn-bd: var(--brand); --btn-fg: var(--brand); }

.btn-ghost {
  --btn-bg: transparent;
  --btn-fg: var(--text-secondary);
  --btn-bd: transparent;
}
.btn-ghost:hover { --btn-bg: var(--surface-hover); --btn-fg: var(--text-primary); }

.btn-accent {
  --btn-bg: var(--accent);
  --btn-fg: var(--on-accent);
  --btn-bd: var(--accent);
  box-shadow: var(--shadow-xs);
}
.btn-accent:hover { --btn-bg: var(--accent-hover); --btn-bd: var(--accent-hover); }

.btn-danger {
  --btn-bg: var(--danger-fill);
  --btn-fg: #FFFFFF;
  --btn-bd: var(--danger-fill);
}
.btn-danger:hover { filter: brightness(0.93); }
.btn-danger:focus-visible { outline-color: var(--danger-ink); }

.btn-quiet-danger {
  --btn-bg: transparent;
  --btn-fg: var(--danger-ink);
  --btn-bd: transparent;
}
.btn-quiet-danger:hover { --btn-bg: var(--danger-soft); }

.btn-link {
  --btn-bd: transparent;
  --btn-fg: var(--text-link);
  height: auto;
  padding: 0;
  font-weight: var(--weight-medium);
}
.btn-link:hover { text-decoration: underline; --btn-fg: var(--text-link-hover); }

/* — sizes — */
.btn-sm { height: var(--control-h-sm); padding: 0 var(--space-3); font-size: var(--text-sm); gap: var(--space-1); }
.btn-lg { height: var(--control-h-lg); padding: 0 var(--space-6); font-size: var(--text-md); }
.btn-block { width: 100%; }

.btn-icon { width: var(--control-h); padding: 0; }
.btn-icon.btn-sm { width: var(--control-h-sm); }
.btn-icon.btn-lg { width: var(--control-h-lg); }

/* — loading — */
.btn.is-loading { color: transparent !important; pointer-events: none; }
.btn.is-loading > * { visibility: hidden; }
.btn.is-loading::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 1em; height: 1em;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: var(--radius-full);
  color: var(--btn-fg);
  visibility: visible;
  animation: spin var(--dur-5) linear infinite;
}

/* — group — */
.btn-group { display: inline-flex; }
.btn-group > .btn { border-radius: 0; margin-left: -1px; }
.btn-group > .btn:first-child { border-radius: var(--radius-sm) 0 0 var(--radius-sm); margin-left: 0; }
.btn-group > .btn:last-child  { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
.btn-group > .btn:hover, .btn-group > .btn:focus-visible { z-index: var(--z-raised); }

/* — segmented control — */
.segmented {
  display: inline-flex;
  padding: 3px;
  gap: 2px;
  background: var(--surface-sunken);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
}
.segmented > button {
  height: 28px;
  padding: 0 var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text-secondary);
  display: inline-flex; align-items: center; gap: var(--space-2);
  transition: background-color var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out);
}
.segmented > button:hover { color: var(--text-primary); }
.segmented > button[aria-pressed="true"],
.segmented > button.is-active {
  background: var(--surface-elevated);
  color: var(--text-primary);
  box-shadow: var(--shadow-xs);
}

/* ==========================================================================
   02. FORM CONTROLS
   ========================================================================== */

.field { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
.field-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-4) var(--space-5);
}

.field-label {
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text-secondary);
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}
.field-label .req { color: var(--danger-ink); font-weight: var(--weight-bold); }
.field-hint { font-size: var(--text-xs); color: var(--text-muted); }
.field-error {
  font-size: var(--text-xs);
  color: var(--danger-ink);
  display: flex;
  align-items: center;
  gap: var(--space-1);
  font-weight: var(--weight-medium);
}

.input, .textarea, .select {
  width: 100%;
  min-width: 0;
  height: var(--control-h);
  padding: 0 var(--space-3);
  background: var(--surface-elevated);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-size: var(--text-base);
  font-family: var(--font-ui);
  box-shadow: var(--shadow-inset);
  transition: border-color var(--dur-1) var(--ease-out), box-shadow var(--dur-2) var(--ease-out);
}
.textarea { height: auto; min-height: 88px; padding: var(--space-3); line-height: var(--leading-normal); }
.input:hover:not(:disabled), .textarea:hover:not(:disabled), .select:hover:not(:disabled) {
  border-color: var(--text-muted);
}
.input:disabled, .textarea:disabled, .select:disabled {
  background: var(--surface-sunken);
  color: var(--text-muted);
  cursor: not-allowed;
  box-shadow: none;
}
.input[readonly] { background: var(--surface-sunken); }

.input.is-invalid, .textarea.is-invalid, .select.is-invalid,
[aria-invalid="true"].input, [aria-invalid="true"].textarea, [aria-invalid="true"].select {
  border-color: var(--danger-ink);
}
.input.is-invalid:focus-visible, .textarea.is-invalid:focus-visible, .select.is-invalid:focus-visible {
  box-shadow: var(--shadow-focus-danger);
  outline-color: var(--danger-ink);
}

.select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: var(--space-8);
  background-image:
    linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position:
    calc(100% - 17px) calc(50% + 1px),
    calc(100% - 12px) calc(50% + 1px);
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

.input-sm, .select-sm { height: var(--control-h-sm); font-size: var(--text-sm); padding-inline: var(--space-2); }
.input-lg { height: var(--control-h-lg); font-size: var(--text-md); }

/* Input with a leading / trailing affix */
.input-group { position: relative; display: flex; align-items: center; min-width: 0; }
.input-group > .ic {
  position: absolute;
  left: var(--space-3);
  color: var(--text-muted);
  z-index: var(--z-raised);
}
.input-group > .ic:last-child { left: auto; right: var(--space-3); }
.input-group > .input { padding-left: var(--space-8); }
.input-group.affix-end > .input { padding-left: var(--space-3); padding-right: var(--space-8); }
.input-affix {
  display: inline-flex; align-items: center;
  height: var(--control-h);
  padding: 0 var(--space-3);
  background: var(--surface-sunken);
  border: 1px solid var(--border-strong);
  border-right: 0;
  border-radius: var(--radius-sm) 0 0 var(--radius-sm);
  color: var(--text-muted);
  font-size: var(--text-sm);
  white-space: nowrap;
}
.input-affix + .input { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }

/* Checkbox & radio — hand-drawn, no native chrome */
.check, .radio {
  display: inline-flex;
  align-items: flex-start;
  gap: var(--space-3);
  cursor: pointer;
  font-size: var(--text-base);
  color: var(--text-primary);
  min-height: 22px;
  user-select: none;
}
.check > input, .radio > input {
  appearance: none;
  -webkit-appearance: none;
  width: 18px; height: 18px;
  flex: none;
  margin-top: 2px;
  border: 1px solid var(--border-strong);
  background: var(--surface-elevated);
  box-shadow: var(--shadow-inset);
  transition: background-color var(--dur-1) var(--ease-out),
              border-color var(--dur-1) var(--ease-out);
  display: grid;
  place-content: center;
  cursor: pointer;
}
.check > input { border-radius: var(--radius-xs); }
.radio > input { border-radius: var(--radius-full); }

.check > input::after {
  content: "";
  width: 10px; height: 6px;
  border-left: 2px solid var(--on-brand);
  border-bottom: 2px solid var(--on-brand);
  transform: rotate(-45deg) translate(1px, -1px) scale(0.4);
  opacity: 0;
  transition: opacity var(--dur-1) var(--ease-out), transform var(--dur-2) var(--ease-spring);
}
.check > input:checked { background: var(--brand); border-color: var(--brand); box-shadow: none; }
.check > input:checked::after { opacity: 1; transform: rotate(-45deg) translate(1px, -1px) scale(1); }
.check > input:indeterminate { background: var(--brand); border-color: var(--brand); }
.check > input:indeterminate::after {
  opacity: 1;
  width: 9px; height: 0;
  border-left: 0;
  border-bottom: 2px solid var(--on-brand);
  transform: none;
}

.radio > input::after {
  content: "";
  width: 8px; height: 8px;
  border-radius: var(--radius-full);
  background: var(--on-brand);
  transform: scale(0);
  transition: transform var(--dur-2) var(--ease-spring);
}
.radio > input:checked { background: var(--brand); border-color: var(--brand); box-shadow: none; }
.radio > input:checked::after { transform: scale(1); }

.check > input:disabled, .radio > input:disabled { opacity: 0.45; cursor: not-allowed; }
.check:has(input:disabled), .radio:has(input:disabled) { color: var(--text-muted); cursor: not-allowed; }

/* Switch */
.switch { display: inline-flex; align-items: center; gap: var(--space-3); cursor: pointer; }
.switch > input {
  appearance: none; -webkit-appearance: none;
  width: 38px; height: 22px;
  flex: none;
  border-radius: var(--radius-full);
  background: var(--border-strong);
  position: relative;
  cursor: pointer;
  transition: background-color var(--dur-2) var(--ease-out);
}
.switch > input::after {
  content: "";
  position: absolute;
  top: 3px; left: 3px;
  width: 16px; height: 16px;
  border-radius: var(--radius-full);
  background: #FFFFFF;
  box-shadow: var(--shadow-sm);
  transition: transform var(--dur-2) var(--ease-spring);
}
.switch > input:checked { background: var(--brand); }
.switch > input:checked::after { transform: translateX(16px); }
.switch > input:disabled { opacity: 0.45; cursor: not-allowed; }

/* Search box (topbar + toolbars) */
.search {
  position: relative;
  display: flex;
  align-items: center;
  min-width: 0;
}
.search > .ic { position: absolute; left: var(--space-3); color: var(--text-muted); }
.search > input {
  width: 100%;
  height: var(--control-h);
  padding: 0 var(--space-4) 0 var(--space-9, 2.25rem);
  padding-left: 2.25rem;
  background: var(--surface-inset);
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  color: var(--text-primary);
  font-size: var(--text-base);
  transition: background-color var(--dur-2) var(--ease-out), border-color var(--dur-1) var(--ease-out);
}
.search > input:hover { background: var(--surface-active); }
.search > input:focus-visible {
  background: var(--surface-elevated);
  border-color: var(--border-focus);
  box-shadow: var(--shadow-focus);
  outline: none;
}
.search > kbd { position: absolute; right: var(--space-2); }

/* ==========================================================================
   03. CARDS & PANELS
   ========================================================================== */

.card {
  background: var(--surface-elevated);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  min-width: 0;
  position: relative;
}
.card-hoverable { transition: box-shadow var(--dur-2) var(--ease-out), border-color var(--dur-2) var(--ease-out), transform var(--dur-2) var(--ease-out); }
.card-hoverable:hover { box-shadow: var(--shadow-md); border-color: var(--border-strong); transform: translateY(-1px); }

.card-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-5) var(--space-5) var(--space-4);
  border-bottom: 1px solid var(--divider);
}
.card-title {
  font-family: var(--font-display);
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight);
  color: var(--text-primary);
  margin: 0;
}
.card-subtitle { font-size: var(--text-xs); color: var(--text-muted); margin-top: 2px; }
.card-actions { display: flex; align-items: center; gap: var(--space-2); flex: none; }
.card-body { padding: var(--space-5); }
.card-body-flush { padding: 0; }
.card-footer {
  padding: var(--space-4) var(--space-5);
  border-top: 1px solid var(--divider);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  background: var(--surface-sunken);
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}

/* A card whose top edge carries the gold rule — used for hero/summary cards */
.card-accent::before {
  content: "";
  position: absolute;
  top: -1px; left: var(--space-5); right: var(--space-5);
  height: 2px;
  background: var(--accent-rule);
  border-radius: var(--radius-full);
}

.panel {
  background: var(--surface-elevated);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.section-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
  flex-wrap: wrap;
}
.section-title {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight);
}

/* ==========================================================================
   04. TABLES
   ========================================================================== */

.table-wrap {
  width: 100%;
  max-width: 100%;
  overflow-x: auto;
  overflow-y: visible;
  -webkit-overflow-scrolling: touch;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  background: var(--surface-elevated);
}
.card > .table-wrap,
.panel > .table-wrap { border: 0; border-radius: 0; }

.table {
  width: 100%;
  min-width: 720px;
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums lining-nums;
}
.table thead th {
  position: sticky;
  top: 0;
  z-index: var(--z-raised);
  background: var(--surface-sunken);
  text-align: left;
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  color: var(--text-muted);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-subtle);
  white-space: nowrap;
}
.table tbody td {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--divider);
  color: var(--text-secondary);
  vertical-align: middle;
}
.table tbody tr:last-child td { border-bottom: 0; }
.table tbody td.strong,
.table tbody td:first-child { color: var(--text-primary); font-weight: var(--weight-medium); }
.table tbody tr {
  transition: background-color var(--dur-1) var(--ease-out);
}
.table tbody tr:hover { background: var(--surface-hover); }
.table tbody tr[aria-selected="true"],
.table tbody tr.is-selected { background: var(--surface-selected); }
.table tbody tr.is-clickable { cursor: pointer; }

.table td.num, .table th.num { text-align: right; font-family: var(--font-mono); font-size: var(--text-xs); }
.table td.shrink, .table th.shrink { width: 1%; white-space: nowrap; }

.table-compact tbody td, .table-compact thead th { padding: var(--space-2) var(--space-3); }
.table-zebra tbody tr:nth-child(even) { background: var(--surface-sunken); }
.table-zebra tbody tr:nth-child(even):hover { background: var(--surface-hover); }

/* Sortable header */
.th-sort {
  cursor: pointer;
  user-select: none;
}
.th-sort:hover { color: var(--text-secondary); }
.th-sort > span { display: inline-flex; align-items: center; gap: var(--space-1); }
.th-sort .ic { opacity: 0.35; }
.th-sort[aria-sort="ascending"] .ic,
.th-sort[aria-sort="descending"] .ic { opacity: 1; color: var(--brand); }
.th-sort[aria-sort="descending"] .ic { transform: rotate(180deg); }

/* Row actions reveal on hover but stay reachable by keyboard */
.row-actions { display: flex; gap: var(--space-1); justify-content: flex-end; opacity: 0; transition: opacity var(--dur-1) var(--ease-out); }
tr:hover .row-actions,
tr:focus-within .row-actions { opacity: 1; }
@media (hover: none) { .row-actions { opacity: 1; } }

/* Pagination */
.pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--divider);
  font-size: var(--text-sm);
  color: var(--text-muted);
  flex-wrap: wrap;
}
.pagination-pages { display: flex; gap: var(--space-1); align-items: center; }
.page-btn {
  min-width: 30px; height: 30px;
  padding: 0 var(--space-2);
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  color: var(--text-secondary);
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background-color var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out);
}
.page-btn:hover { background: var(--surface-hover); color: var(--text-primary); }
.page-btn[aria-current="page"] {
  background: var(--brand);
  border-color: var(--brand);
  color: var(--on-brand);
  font-weight: var(--weight-semibold);
}

/* ==========================================================================
   05. BADGES, CHIPS & STATUS
   ========================================================================== */

.badge {
  --bd-ink: var(--neutral-ink);
  --bd-soft: var(--neutral-soft);
  --bd-line: var(--neutral-border);

  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  height: 21px;
  padding: 0 var(--space-2);
  border: 1px solid var(--bd-line);
  border-radius: var(--radius-sm);
  background: var(--bd-soft);
  color: var(--bd-ink);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  line-height: 1;
  white-space: nowrap;
  vertical-align: middle;
}
.badge .ic { width: 0.9em; height: 0.9em; stroke-width: 2; }
.badge-lg { height: 26px; font-size: var(--text-xs); padding: 0 var(--space-3); }

.badge-neutral { --bd-ink: var(--neutral-ink); --bd-soft: var(--neutral-soft); --bd-line: var(--neutral-border); }
.badge-brand   { --bd-ink: var(--brand-ink);   --bd-soft: var(--brand-soft);   --bd-line: var(--border-brand); }
.badge-accent  { --bd-ink: var(--accent-ink);  --bd-soft: var(--accent-soft);  --bd-line: var(--accent); }
.badge-success { --bd-ink: var(--success-ink); --bd-soft: var(--success-soft); --bd-line: var(--success-border); }
.badge-warning { --bd-ink: var(--warning-ink); --bd-soft: var(--warning-soft); --bd-line: var(--warning-border); }
.badge-danger  { --bd-ink: var(--danger-ink);  --bd-soft: var(--danger-soft);  --bd-line: var(--danger-border); }
.badge-info    { --bd-ink: var(--info-ink);    --bd-soft: var(--info-soft);    --bd-line: var(--info-border); }

.badge-solid { background: var(--bd-ink); color: var(--surface-elevated); border-color: var(--bd-ink); }

/* Leading dot — a second, non-colour cue is always the label text itself */
.badge-dot::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: var(--radius-full);
  background: currentColor;
  flex: none;
}

/* Enquiry stage badges — one class per pipeline stage.
   The stage NAME is always the badge text, so colour is never the only cue. */
.stage-badge {
  display: inline-flex; align-items: center; gap: var(--space-2);
  height: 22px;
  padding: 0 var(--space-2) 0 var(--space-1);
  border-radius: var(--radius-sm);
  background: var(--surface-inset);
  border: 1px solid var(--border-subtle);
  color: var(--text-secondary);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  white-space: nowrap;
}
.stage-badge::before {
  content: "";
  width: 3px;
  align-self: stretch;
  margin: 3px 0;
  border-radius: var(--radius-full);
  background: var(--stage-1);
}
.stage-new::before          { background: var(--stage-1); }
.stage-contacted::before    { background: var(--stage-2); }
.stage-counselling::before  { background: var(--stage-3); }
.stage-visit::before        { background: var(--stage-4); }
.stage-visited::before      { background: var(--stage-5); }
.stage-registered::before   { background: var(--stage-6); }
.stage-assessment::before   { background: var(--stage-7); }
.stage-offered::before      { background: var(--stage-8); }
.stage-admitted::before     { background: var(--stage-9); }
.stage-admitted { color: var(--accent-ink); background: var(--accent-soft); border-color: var(--accent); }
.stage-lost::before         { background: var(--danger-fill); }
.stage-lost { color: var(--danger-ink); background: var(--danger-soft); border-color: var(--danger-border); }

/* Lead score badge — Hot / Warm / Cold, always with the numeric score */
.score {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  height: 24px;
  padding: 0 var(--space-2);
  border-radius: var(--radius-sm);
  border: 1px solid var(--sc-line, var(--neutral-border));
  background: var(--sc-soft, var(--neutral-soft));
  color: var(--sc-ink, var(--neutral-ink));
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  white-space: nowrap;
}
.score .score-n {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
  padding-left: var(--space-2);
  border-left: 1px solid currentColor;
  opacity: 0.95;
}
.score .ic { width: 13px; height: 13px; stroke-width: 1.9; }
.score-hot  { --sc-ink: var(--hot-ink);  --sc-soft: var(--hot-soft);  --sc-line: var(--hot-border); }
.score-warm { --sc-ink: var(--warm-ink); --sc-soft: var(--warm-soft); --sc-line: var(--warm-border); }
.score-cold { --sc-ink: var(--cold-ink); --sc-soft: var(--cold-soft); --sc-line: var(--cold-border); }

/* Chips / filter tokens */
.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  height: 28px;
  padding: 0 var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-full);
  background: var(--surface-elevated);
  color: var(--text-secondary);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  white-space: nowrap;
  transition: border-color var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out), background-color var(--dur-1) var(--ease-out);
}
.chip:hover { border-color: var(--border-strong); color: var(--text-primary); }
.chip[aria-pressed="true"], .chip.is-active {
  background: var(--brand-soft);
  border-color: var(--border-brand);
  color: var(--brand-ink);
}
.chip-x {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px;
  margin-right: -4px;
  border-radius: var(--radius-full);
  color: var(--text-muted);
}
.chip-x:hover { background: var(--surface-active); color: var(--text-primary); }

/* ==========================================================================
   06. MODALS
   ========================================================================== */

.scrim {
  position: fixed;
  inset: 0;
  background: var(--surface-overlay);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  z-index: var(--z-scrim);
  animation: fade-in var(--dur-2) var(--ease-out);
}

.modal-layer {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: grid;
  place-items: center;
  padding: var(--space-4);
  overflow-y: auto;
  pointer-events: none;
}
.modal {
  pointer-events: auto;
  width: min(560px, 100%);
  max-height: calc(100vh - var(--space-8));
  display: flex;
  flex-direction: column;
  background: var(--surface-elevated);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-xl);
  animation: scale-in var(--dur-3) var(--ease-out);
  overflow: hidden;
}
.modal-sm { width: min(420px, 100%); }
.modal-lg { width: min(820px, 100%); }
.modal-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-5) var(--space-6);
  border-bottom: 1px solid var(--divider);
}
.modal-title {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight);
}
.modal-desc { font-size: var(--text-sm); color: var(--text-muted); margin-top: var(--space-1); }
.modal-body { padding: var(--space-6); overflow-y: auto; flex: 1; }
.modal-footer {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-6);
  border-top: 1px solid var(--divider);
  background: var(--surface-sunken);
}
.modal-footer.split { justify-content: space-between; }

/* ==========================================================================
   07. DRAWERS  (record detail panel)
   ========================================================================== */

.drawer {
  position: fixed;
  top: 0; right: 0; bottom: 0;
  width: var(--drawer-w);
  max-width: 100vw;
  z-index: var(--z-drawer);
  display: flex;
  flex-direction: column;
  background: var(--surface-elevated);
  border-left: 1px solid var(--border-subtle);
  box-shadow: var(--shadow-xl);
  animation: slide-in-right var(--dur-3) var(--ease-out);
}
.drawer-header {
  padding: var(--space-5) var(--space-6) var(--space-4);
  border-bottom: 1px solid var(--divider);
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  background:
    linear-gradient(180deg, var(--surface-sunken), transparent);
}
.drawer-eyebrow {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wider);
  color: var(--text-muted);
  text-transform: uppercase;
}
.drawer-title {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight);
  margin-top: var(--space-1);
}
.drawer-meta { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-3); }
.drawer-body { flex: 1; overflow-y: auto; padding: var(--space-6); }
.drawer-footer {
  padding: var(--space-4) var(--space-6);
  border-top: 1px solid var(--divider);
  background: var(--surface-sunken);
  display: flex;
  gap: var(--space-3);
  justify-content: flex-end;
}

/* ==========================================================================
   08. TABS
   ========================================================================== */

.tabs {
  display: flex;
  align-items: stretch;
  gap: var(--space-1);
  border-bottom: 1px solid var(--divider);
  overflow-x: auto;
  scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }
.tab {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  height: 38px;
  padding: 0 var(--space-3);
  color: var(--text-muted);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  white-space: nowrap;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color var(--dur-1) var(--ease-out), border-color var(--dur-2) var(--ease-out);
}
.tab:hover { color: var(--text-primary); }
.tab[aria-selected="true"], .tab.is-active {
  color: var(--text-primary);
  border-bottom-color: var(--accent);
  font-weight: var(--weight-semibold);
}
.tab:disabled { opacity: 0.45; pointer-events: none; }
.tab-count {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  padding: 1px 5px;
  border-radius: var(--radius-full);
  background: var(--surface-inset);
  color: var(--text-muted);
}
.tab[aria-selected="true"] .tab-count { background: var(--brand-soft); color: var(--brand-ink); }

.tabs-pill { border-bottom: 0; gap: var(--space-2); }
.tabs-pill .tab {
  border-bottom: 0;
  margin-bottom: 0;
  height: 30px;
  border-radius: var(--radius-full);
  padding: 0 var(--space-4);
  border: 1px solid var(--border-subtle);
}
.tabs-pill .tab[aria-selected="true"] {
  background: var(--brand);
  border-color: var(--brand);
  color: var(--on-brand);
}
.tabs-pill .tab[aria-selected="true"] .tab-count { background: rgba(255,255,255,0.2); color: inherit; }

.tabpanel { padding-top: var(--space-5); }

/* ==========================================================================
   09. TOASTS
   ========================================================================== */

.toast-region {
  position: fixed;
  bottom: var(--space-5);
  right: var(--space-5);
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  width: min(380px, calc(100vw - var(--space-8)));
  pointer-events: none;
}
.toast {
  pointer-events: auto;
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background: var(--surface-elevated);
  border: 1px solid var(--border-subtle);
  border-left: 3px solid var(--toast-line, var(--brand));
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  animation: rise-in var(--dur-3) var(--ease-out);
}
.toast > .ic { color: var(--toast-line, var(--brand)); margin-top: 1px; }
.toast-title { font-size: var(--text-sm); font-weight: var(--weight-semibold); color: var(--text-primary); }
.toast-text  { font-size: var(--text-xs); color: var(--text-secondary); margin-top: 2px; }
.toast-close { margin-left: auto; color: var(--text-muted); padding: var(--space-1); border-radius: var(--radius-xs); }
.toast-close:hover { color: var(--text-primary); background: var(--surface-hover); }

.toast-success { --toast-line: var(--success-fill); }
.toast-warning { --toast-line: var(--warning-fill); }
.toast-danger  { --toast-line: var(--danger-fill); }
.toast-info    { --toast-line: var(--info-fill); }

/* ==========================================================================
   10. EMPTY STATES & ALERTS
   ========================================================================== */

.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-3);
  padding: var(--space-12) var(--space-6);
  color: var(--text-muted);
}
.empty-art {
  width: 64px; height: 64px;
  display: grid; place-items: center;
  border-radius: var(--radius-lg);
  border: 1px solid var(--border-subtle);
  background: var(--surface-sunken);
  color: var(--text-muted);
  position: relative;
}
.empty-art::after {
  content: "";
  position: absolute;
  inset: auto var(--space-4) -1px;
  height: 2px;
  background: var(--accent-rule);
}
.empty-title {
  font-family: var(--font-display);
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
}
.empty-text { font-size: var(--text-sm); max-width: 42ch; }

.alert {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--al-line, var(--info-border));
  background: var(--al-soft, var(--info-soft));
  color: var(--al-ink, var(--info-ink));
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
}
.alert .ic { margin-top: 2px; flex: none; }
.alert strong { color: inherit; }
.alert-success { --al-ink: var(--success-ink); --al-soft: var(--success-soft); --al-line: var(--success-border); }
.alert-warning { --al-ink: var(--warning-ink); --al-soft: var(--warning-soft); --al-line: var(--warning-border); }
.alert-danger  { --al-ink: var(--danger-ink);  --al-soft: var(--danger-soft);  --al-line: var(--danger-border); }
.alert-info    { --al-ink: var(--info-ink);    --al-soft: var(--info-soft);    --al-line: var(--info-border); }

/* ==========================================================================
   11. SKELETONS & LOADING
   ========================================================================== */

.skel {
  --skel-a: var(--surface-sunken);
  --skel-b: var(--surface-inset);
  background-color: var(--skel-a);
  background-image: linear-gradient(90deg, transparent 0%, var(--skel-b) 40%, var(--skel-b) 60%, transparent 100%);
  background-size: 200% 100%;
  border-radius: var(--radius-sm);
  animation: shimmer 1.4s var(--ease-linear) infinite;
  display: block;
}
.skel-text  { height: 10px; width: 100%; border-radius: var(--radius-full); }
.skel-title { height: 16px; width: 42%; border-radius: var(--radius-full); }
.skel-line-sm { height: 10px; width: 62%; border-radius: var(--radius-full); }
.skel-circle { width: 34px; height: 34px; border-radius: var(--radius-full); }
.skel-block { height: 92px; border-radius: var(--radius-md); }
.skel-stack { display: flex; flex-direction: column; gap: var(--space-3); }
.skel-row { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3) 0; }

.spinner {
  width: 16px; height: 16px;
  border: 2px solid var(--border-strong);
  border-top-color: var(--brand);
  border-radius: var(--radius-full);
  animation: spin var(--dur-5) linear infinite;
  display: inline-block;
}
.spinner-lg { width: 28px; height: 28px; border-width: 3px; }

.progress {
  height: 6px;
  background: var(--viz-track);
  border-radius: var(--radius-full);
  overflow: hidden;
}
.progress-bar {
  height: 100%;
  background: var(--brand);
  border-radius: var(--radius-full);
  transform-origin: left;
  transition: width var(--dur-4) var(--ease-out);
}
.progress-indeterminate .progress-bar { width: 40%; animation: grow-x var(--dur-5) var(--ease-in-out) infinite alternate; }

/* ==========================================================================
   12. AVATARS
   ========================================================================== */

.avatar {
  --av-size: 32px;
  width: var(--av-size);
  height: var(--av-size);
  flex: none;
  border-radius: var(--radius-full);
  display: grid;
  place-items: center;
  background: var(--brand-soft);
  color: var(--brand-ink);
  border: 1px solid var(--border-subtle);
  font-family: var(--font-ui);
  font-size: calc(var(--av-size) * 0.38);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  overflow: hidden;
  user-select: none;
}
.avatar-xs { --av-size: 22px; }
.avatar-sm { --av-size: 26px; }
.avatar-lg { --av-size: 40px; }
.avatar-xl { --av-size: 56px; }
.avatar-brand { background: var(--brand); color: var(--on-brand); border-color: var(--brand); }
.avatar-accent { background: var(--accent-soft); color: var(--accent-ink); border-color: var(--accent); }

.avatar-group { display: flex; }
.avatar-group > .avatar + .avatar { margin-left: -8px; }
.avatar-group > .avatar { box-shadow: 0 0 0 2px var(--surface-elevated); border-color: transparent; }

/* ==========================================================================
   13. MENUS, TOOLTIPS, BREADCRUMBS
   ========================================================================== */

.menu {
  min-width: 200px;
  padding: var(--space-2);
  background: var(--surface-elevated);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  z-index: var(--z-dropdown);
  animation: scale-in var(--dur-2) var(--ease-out);
}
.menu-label {
  padding: var(--space-2) var(--space-3) var(--space-1);
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-widest);
  color: var(--text-muted);
  font-weight: var(--weight-semibold);
}
.menu-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  font-size: var(--text-sm);
  text-align: left;
  transition: background-color var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out);
}
.menu-item:hover { background: var(--surface-hover); color: var(--text-primary); text-decoration: none; }
.menu-item .ic { color: var(--text-muted); }
.menu-item:hover .ic { color: var(--brand); }
.menu-item.is-danger { color: var(--danger-ink); }
.menu-item.is-danger:hover { background: var(--danger-soft); }
.menu-item kbd { margin-left: auto; }
.menu-sep { height: 1px; background: var(--divider); margin: var(--space-2) calc(var(--space-1) * -1); }

.tt { position: relative; }
.tt::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%) translateY(3px);
  padding: var(--space-1) var(--space-2);
  background: var(--n-900);
  color: var(--n-0);
  font-size: var(--text-2xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-normal);
  border-radius: var(--radius-xs);
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  z-index: var(--z-tooltip);
  box-shadow: var(--shadow-md);
  transition: opacity var(--dur-2) var(--ease-out), transform var(--dur-2) var(--ease-out);
}
.tt:hover::after, .tt:focus-visible::after { opacity: 1; transform: translateX(-50%) translateY(0); }

.crumbs { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-xs); color: var(--text-muted); flex-wrap: wrap; }
.crumbs a { color: var(--text-muted); }
.crumbs a:hover { color: var(--text-primary); }
.crumbs .sep { opacity: 0.5; }
.crumbs [aria-current="page"] { color: var(--text-primary); font-weight: var(--weight-medium); }

/* ==========================================================================
   14. MISC — key/value grid, toolbar, page head, dividers
   ========================================================================== */

.page-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-5);
  flex-wrap: wrap;
  padding-bottom: var(--space-5);
  margin-bottom: var(--space-6);
  border-bottom: 1px solid var(--divider);
  position: relative;
}
.page-head::after {
  content: "";
  position: absolute;
  left: 0; bottom: -1px;
  width: 56px; height: 2px;
  background: var(--accent-rule);
}
.page-title {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tighter);
  line-height: var(--leading-tight);
}
.page-sub { font-size: var(--text-sm); color: var(--text-muted); margin-top: var(--space-1); }
.page-actions { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }

.toolbar {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  padding: var(--space-3) 0;
}
.toolbar-spacer { flex: 1 1 auto; min-width: var(--space-2); }

.kv { display: grid; grid-template-columns: minmax(120px, 34%) 1fr; gap: var(--space-3) var(--space-4); font-size: var(--text-sm); }
.kv dt { color: var(--text-muted); font-size: var(--text-xs); padding-top: 1px; }
.kv dd { color: var(--text-primary); margin: 0; min-width: 0; overflow-wrap: anywhere; }

.stack   { display: flex; flex-direction: column; gap: var(--space-4); }
.stack-2 { display: flex; flex-direction: column; gap: var(--space-2); }
.row     { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.row-tight { display: flex; align-items: center; gap: var(--space-2); }
.grid-2  { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: var(--space-5); }
.grid-3  { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: var(--space-5); }

.divider-label {
  display: flex; align-items: center; gap: var(--space-3);
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-widest);
  color: var(--text-muted);
  font-weight: var(--weight-semibold);
}
.divider-label::before, .divider-label::after {
  content: ""; flex: 1; height: 1px; background: var(--divider);
}

/* ==========================================================================
   15. KANBAN / PIPELINE BOARD
   ========================================================================== */

.kanban {
  display: flex;
  gap: var(--space-3);
  overflow-x: auto;
  overflow-y: hidden;
  padding-bottom: var(--space-3);
  align-items: flex-start;
  scroll-snap-type: x proximity;
}
.kanban-col {
  scroll-snap-align: start;
  flex: 0 0 296px;
  width: 296px;
  max-height: 100%;
  display: flex;
  flex-direction: column;
  background: var(--surface-sunken);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: border-color var(--dur-2) var(--ease-out), background-color var(--dur-2) var(--ease-out);
}
.kanban-col.is-dropzone {
  border-color: var(--brand);
  background: var(--brand-soft);
  box-shadow: var(--shadow-focus);
}

.kanban-col-head {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-subtle);
  background: var(--surface-elevated);
  position: relative;
}
/* the stage rail — decorative progress, name/count always present as text */
.kanban-col-head::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
  background: var(--col-rail, var(--stage-1));
}
.kanban-col[data-stage="new"]          { --col-rail: var(--stage-1); }
.kanban-col[data-stage="contacted"]    { --col-rail: var(--stage-2); }
.kanban-col[data-stage="counselling"]  { --col-rail: var(--stage-3); }
.kanban-col[data-stage="visit"]        { --col-rail: var(--stage-4); }
.kanban-col[data-stage="visited"]      { --col-rail: var(--stage-5); }
.kanban-col[data-stage="registered"]   { --col-rail: var(--stage-6); }
.kanban-col[data-stage="assessment"]   { --col-rail: var(--stage-7); }
.kanban-col[data-stage="offered"]      { --col-rail: var(--stage-8); }
.kanban-col[data-stage="admitted"]     { --col-rail: var(--stage-9); }

.kanban-col-name {
  display: flex; align-items: center; gap: var(--space-2);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  text-transform: uppercase;
  letter-spacing: var(--tracking-widest);
  color: var(--text-secondary);
}
.kanban-count {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  padding: 1px 6px;
  border-radius: var(--radius-full);
  background: var(--surface-inset);
  color: var(--text-secondary);
  letter-spacing: var(--tracking-normal);
}
.kanban-value {
  margin-top: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}
.kanban-value small { color: var(--text-muted); font-family: var(--font-ui); font-size: var(--text-2xs); }

.kanban-body {
  flex: 1;
  min-height: 96px;
  overflow-y: auto;
  padding: var(--space-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.kanban-card {
  background: var(--surface-elevated);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  padding: var(--space-3);
  box-shadow: var(--shadow-xs);
  cursor: grab;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  text-align: left;
  width: 100%;
  transition: box-shadow var(--dur-2) var(--ease-out),
              border-color var(--dur-2) var(--ease-out),
              transform var(--dur-2) var(--ease-out);
}
.kanban-card:hover { box-shadow: var(--shadow-md); border-color: var(--border-strong); transform: translateY(-2px); }
.kanban-card:active { cursor: grabbing; }
.kanban-card.is-dragging { opacity: 0.5; transform: rotate(1.4deg) scale(0.99); box-shadow: var(--shadow-lg); }
.kanban-card-top { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-2); }
.kanban-card-name {
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
  line-height: var(--leading-snug);
}
.kanban-card-meta {
  display: flex; align-items: center; gap: var(--space-2);
  font-size: var(--text-2xs);
  color: var(--text-muted);
  flex-wrap: wrap;
}
.kanban-card-meta .mono { font-size: var(--text-2xs); }
.kanban-card-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px solid var(--divider);
}
/* drag handle affordance — six dots, appears on hover */
.kanban-grip {
  width: 12px; height: 16px;
  flex: none;
  opacity: 0;
  color: var(--text-muted);
  background-image: radial-gradient(currentColor 1px, transparent 1.2px);
  background-size: 5px 5px;
  transition: opacity var(--dur-1) var(--ease-out);
}
.kanban-card:hover .kanban-grip { opacity: 0.7; }

.kanban-placeholder {
  height: 64px;
  border: 1px dashed var(--brand);
  border-radius: var(--radius-md);
  background: var(--brand-soft);
}
.kanban-add {
  margin: 0 var(--space-3) var(--space-3);
  height: 32px;
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-md);
  color: var(--text-muted);
  font-size: var(--text-xs);
  display: flex; align-items: center; justify-content: center; gap: var(--space-2);
  transition: color var(--dur-1) var(--ease-out), border-color var(--dur-1) var(--ease-out);
}
.kanban-add:hover { color: var(--brand); border-color: var(--brand); }

/* ==========================================================================
   16. ACTIVITY TIMELINE
   ========================================================================== */

.timeline { display: flex; flex-direction: column; position: relative; }
.tl-item {
  display: grid;
  grid-template-columns: 30px 1fr;
  gap: var(--space-3);
  padding-bottom: var(--space-5);
  position: relative;
}
.tl-item:last-child { padding-bottom: 0; }
/* the spine */
.tl-item:not(:last-child)::before {
  content: "";
  position: absolute;
  left: 15px;
  top: 30px;
  bottom: 0;
  width: 1px;
  background: var(--divider);
}
.tl-marker {
  width: 30px; height: 30px;
  border-radius: var(--radius-full);
  display: grid; place-items: center;
  background: var(--tl-soft, var(--neutral-soft));
  color: var(--tl-ink, var(--neutral-ink));
  border: 1px solid var(--tl-line, var(--neutral-border));
  z-index: var(--z-raised);
  flex: none;
}
.tl-marker .ic { width: 14px; height: 14px; stroke-width: 1.8; }
.tl-call     { --tl-ink: var(--info-ink);    --tl-soft: var(--info-soft);    --tl-line: var(--info-border); }
.tl-email    { --tl-ink: var(--brand-ink);   --tl-soft: var(--brand-soft);   --tl-line: var(--border-brand); }
.tl-whatsapp { --tl-ink: var(--success-ink); --tl-soft: var(--success-soft); --tl-line: var(--success-border); }
.tl-sms      { --tl-ink: var(--accent-ink);  --tl-soft: var(--accent-soft);  --tl-line: var(--accent); }
.tl-meeting  { --tl-ink: var(--warning-ink); --tl-soft: var(--warning-soft); --tl-line: var(--warning-border); }
.tl-note     { --tl-ink: var(--neutral-ink); --tl-soft: var(--neutral-soft); --tl-line: var(--neutral-border); }
.tl-stage    { --tl-ink: var(--danger-ink);  --tl-soft: var(--danger-soft);  --tl-line: var(--danger-border); }

.tl-body { min-width: 0; padding-top: 3px; }
.tl-head { display: flex; align-items: baseline; gap: var(--space-2); flex-wrap: wrap; }
.tl-title { font-size: var(--text-sm); font-weight: var(--weight-semibold); color: var(--text-primary); }
.tl-channel {
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  color: var(--tl-ink, var(--text-muted));
  font-weight: var(--weight-semibold);
}
.tl-time { font-size: var(--text-2xs); color: var(--text-muted); margin-left: auto; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tl-text { font-size: var(--text-sm); color: var(--text-secondary); margin-top: var(--space-1); line-height: var(--leading-normal); }
.tl-foot { display: flex; align-items: center; gap: var(--space-2); margin-top: var(--space-2); font-size: var(--text-2xs); color: var(--text-muted); flex-wrap: wrap; }
.tl-quote {
  margin-top: var(--space-2);
  padding: var(--space-3);
  background: var(--surface-sunken);
  border-radius: var(--radius-md);
  border-left: 2px solid var(--tl-line, var(--border-subtle));
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

/* ==========================================================================
   17. STAT TILES
   ========================================================================== */

.stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(196px, 1fr));
  gap: var(--space-4);
}
.stat {
  position: relative;
  background: var(--surface-elevated);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-5) var(--space-5);
  min-width: 0;
  overflow: hidden;
  transition: border-color var(--dur-2) var(--ease-out), box-shadow var(--dur-2) var(--ease-out);
}
.stat:hover { border-color: var(--border-strong); box-shadow: var(--shadow-sm); }
.stat-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.stat-label {
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  text-transform: uppercase;
  letter-spacing: var(--tracking-widest);
  color: var(--text-muted);
}
.stat-icon { color: var(--text-muted); opacity: 0.7; }
.stat-value {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tighter);
  line-height: var(--leading-none);
  color: var(--text-primary);
  margin-top: var(--space-3);
  font-variant-numeric: tabular-nums lining-nums;
  display: flex;
  align-items: baseline;
  gap: var(--space-1);
}
.stat-value .unit { font-size: var(--text-md); color: var(--text-muted); font-weight: var(--weight-regular); }
.stat-foot { display: flex; align-items: center; gap: var(--space-2); margin-top: var(--space-3); flex-wrap: wrap; }
.stat-delta {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
}
.stat-delta .ic { width: 11px; height: 11px; stroke-width: 2.2; }
.delta-up   { color: var(--success-ink); background: var(--success-soft); border-color: var(--success-border); }
.delta-down { color: var(--danger-ink);  background: var(--danger-soft);  border-color: var(--danger-border); }
.delta-flat { color: var(--text-muted);  background: var(--neutral-soft); border-color: var(--neutral-border); }
/* an "up" delta is not always good — .is-inverse flips the reading, and the
   arrow direction plus the caption keep it readable without colour */
.delta-up.is-inverse   { color: var(--danger-ink);  background: var(--danger-soft);  border-color: var(--danger-border); }
.delta-down.is-inverse { color: var(--success-ink); background: var(--success-soft); border-color: var(--success-border); }
.stat-caption { font-size: var(--text-2xs); color: var(--text-muted); }

.stat-spark { margin-top: var(--space-3); height: 34px; width: 100%; display: block; overflow: visible; }
.stat-spark path { fill: none; stroke: var(--viz-primary); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.stat-spark .spark-fill { fill: var(--viz-primary); opacity: 0.10; stroke: none; }
.stat-spark .spark-dot  { fill: var(--viz-primary); stroke: var(--surface-elevated); stroke-width: 2; }

/* Hero figure — one big number, no plot */
.stat-hero .stat-value { font-size: var(--text-3xl); }

/* ==========================================================================
   18. CHARTS — funnel, conversion bar, bar chart, legend
   ========================================================================== */

.chart-frame { display: flex; flex-direction: column; gap: var(--space-4); min-width: 0; }
.chart-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-4); }
.chart-title { font-size: var(--text-sm); font-weight: var(--weight-semibold); color: var(--text-primary); }
.chart-note  { font-size: var(--text-2xs); color: var(--text-muted); }

.legend { display: flex; flex-wrap: wrap; gap: var(--space-3) var(--space-4); }
.legend-item { display: inline-flex; align-items: center; gap: var(--space-2); font-size: var(--text-xs); color: var(--text-secondary); }
.legend-swatch { width: 10px; height: 10px; border-radius: 2px; flex: none; background: var(--sw, var(--viz-1)); }
.legend-swatch.round { border-radius: var(--radius-full); }

/* ---- FUNNEL ----
   Magnitude is encoded by bar WIDTH. One hue throughout; the terminal stage
   takes the gold accent. Every row is directly labelled with count + rate. */
.funnel { display: flex; flex-direction: column; gap: var(--space-2); }
.funnel-row { display: grid; grid-template-columns: 150px 1fr auto; gap: var(--space-3); align-items: center; min-width: 0; }
.funnel-name {
  font-size: var(--text-xs);
  color: var(--text-secondary);
  text-align: right;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.funnel-track {
  position: relative;
  height: 26px;
  background: var(--viz-track);
  border-radius: var(--radius-xs);
  overflow: hidden;
}
.funnel-bar {
  height: 100%;
  width: var(--pct, 100%);
  background: var(--viz-primary);
  border-radius: 0 4px 4px 0;   /* rounded data-end, anchored to the baseline */
  transform-origin: left;
  animation: grow-x var(--dur-4) var(--ease-out) both;
  display: flex;
  align-items: center;
  padding-left: var(--space-2);
}
.funnel-row:last-child .funnel-bar { background: var(--accent); }
.funnel-bar-label {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  color: var(--surface-elevated);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.funnel-row:last-child .funnel-bar-label { color: var(--on-accent); }
.funnel-rate {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  min-width: 52px;
  text-align: right;
}
.funnel-rate.is-drop { color: var(--danger-ink); }

/* ---- CONVERSION BAR (100% stacked, single row) ----
   2px surface gap between adjacent segments so fills never touch. */
.convbar {
  display: flex;
  height: 14px;
  border-radius: var(--radius-full);
  background: var(--viz-track);
  overflow: hidden;
  gap: 2px;
  padding: 0;
}
.convbar-seg {
  height: 100%;
  width: var(--pct, 25%);
  background: var(--sw, var(--viz-1));
  min-width: 2px;
  transition: width var(--dur-4) var(--ease-out);
}
.convbar-seg:first-child { border-radius: var(--radius-full) 0 0 var(--radius-full); }
.convbar-seg:last-child  { border-radius: 0 var(--radius-full) var(--radius-full) 0; }
.convbar-scale {
  display: flex; justify-content: space-between;
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  color: var(--text-muted);
  margin-top: var(--space-2);
  font-variant-numeric: tabular-nums;
}

/* ---- VERTICAL BAR CHART (pure CSS grid) ---- */
.bars {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  align-items: end;
  gap: var(--space-2);
  height: 168px;
  padding-top: var(--space-4);
  border-bottom: 1px solid var(--viz-axis);
  background-image: repeating-linear-gradient(to top, var(--viz-grid) 0 1px, transparent 1px 25%);
}
.bar-col { display: flex; flex-direction: column; justify-content: flex-end; align-items: center; gap: var(--space-2); height: 100%; min-width: 0; }
.bar {
  width: min(30px, 78%);
  height: var(--h, 40%);
  background: var(--sw, var(--viz-1));
  border-radius: 4px 4px 0 0;   /* rounded data-end at the top, flat baseline */
  transition: height var(--dur-4) var(--ease-out), filter var(--dur-1) var(--ease-out);
  position: relative;
}
.bar-col:hover .bar { filter: brightness(1.08); }
.bar-val {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}
.bars-axis {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: var(--space-2);
  margin-top: var(--space-2);
}
.bars-axis > span {
  font-size: var(--text-2xs);
  color: var(--text-muted);
  text-align: center;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ---- DONUT (SVG, conic-free so it themes cleanly) ---- */
.donut { width: 132px; height: 132px; flex: none; transform: rotate(-90deg); }
.donut circle { fill: none; stroke-width: 14; stroke-linecap: butt; }
.donut .donut-track { stroke: var(--viz-track); }

/* ==========================================================================
   19. SEAT CAPACITY METER
   ========================================================================== */

.capacity { display: flex; flex-direction: column; gap: var(--space-4); }
.cap-row { display: grid; grid-template-columns: 88px 1fr 110px; gap: var(--space-3); align-items: center; min-width: 0; }
.cap-grade {
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
  white-space: nowrap;
}
.cap-grade small { display: block; font-weight: var(--weight-regular); color: var(--text-muted); font-size: var(--text-2xs); }
.cap-track {
  position: relative;
  display: flex;
  height: 18px;
  gap: 2px;
  background: var(--viz-track);
  border-radius: var(--radius-xs);
  overflow: hidden;
  border: 1px solid var(--border-subtle);
}
.cap-seg { height: 100%; width: var(--pct, 0%); transition: width var(--dur-4) var(--ease-out); min-width: 0; }
.cap-filled   { background: var(--viz-primary); }
.cap-offered  { background: var(--viz-4); }
.cap-available{ background: transparent; }
/* Available is a hatched void, not a colour — reads in print and forced-colors */
.cap-available {
  background-image: repeating-linear-gradient(
    135deg,
    var(--viz-grid) 0 3px,
    transparent 3px 7px
  );
}
.cap-figures {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  color: var(--text-secondary);
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.cap-figures b { color: var(--text-primary); font-weight: var(--weight-semibold); }
.cap-row.is-full .cap-figures b { color: var(--danger-ink); }
.cap-row.is-tight .cap-figures b { color: var(--warning-ink); }

/* ==========================================================================
   20. SLA / OVERDUE INDICATORS
   ========================================================================== */

.sla {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  height: 21px;
  padding: 0 var(--space-2);
  border-radius: var(--radius-sm);
  border: 1px solid var(--sla-line, var(--success-border));
  background: var(--sla-soft, var(--success-soft));
  color: var(--sla-ink, var(--success-ink));
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.sla .ic { width: 12px; height: 12px; stroke-width: 2; }
.sla-ok      { --sla-ink: var(--success-ink); --sla-soft: var(--success-soft); --sla-line: var(--success-border); }
.sla-due     { --sla-ink: var(--warning-ink); --sla-soft: var(--warning-soft); --sla-line: var(--warning-border); }
.sla-overdue { --sla-ink: var(--danger-ink);  --sla-soft: var(--danger-soft);  --sla-line: var(--danger-border); }

/* pulsing dot for a breached SLA — reduced-motion safe (durations collapse) */
.sla-overdue::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: var(--radius-full);
  background: currentColor;
  flex: none;
  animation: pulse-ring 1.8s var(--ease-out) infinite;
}
@media (prefers-reduced-motion: reduce) {
  .sla-overdue::before { animation: none; box-shadow: 0 0 0 3px var(--danger-soft); }
}

/* A left edge marker for overdue rows in a table or list */
.is-overdue-row { box-shadow: inset 3px 0 0 var(--danger-fill); }
.is-due-row     { box-shadow: inset 3px 0 0 var(--warning-fill); }

/* ==========================================================================
   21. RESPONSIVE / TOUCH TARGETS
   ========================================================================== */

@media (max-width: 767px) {
  /* WCAG 2.5.5 — everything tappable is at least 44x44 on small screens */
  .btn, .input, .select, .chip, .tab, .page-btn, .menu-item, .toast-close {
    min-height: var(--touch-min);
  }
  .btn-sm { min-height: var(--touch-min); padding-inline: var(--space-4); }
  .btn-icon { min-width: var(--touch-min); width: var(--touch-min); }
  .check > input, .radio > input { width: 22px; height: 22px; }
  .check, .radio, .switch { min-height: var(--touch-min); align-items: center; }
  .row-actions { opacity: 1; }
  .row-actions .btn-icon { min-width: var(--touch-min); }

  .kanban-col { flex: 0 0 84vw; width: 84vw; }
  .funnel-row { grid-template-columns: 104px 1fr auto; }
  .cap-row { grid-template-columns: 72px 1fr; grid-template-areas: "g t" "f f"; }
  .cap-grade { grid-area: g; }
  .cap-track { grid-area: t; }
  .cap-figures { grid-area: f; text-align: left; }
  .kv { grid-template-columns: 1fr; gap: var(--space-1) 0; }
  .kv dd { margin-bottom: var(--space-3); }
  .modal { width: 100%; max-height: calc(100dvh - var(--space-6)); }
  .modal-footer { flex-direction: column-reverse; align-items: stretch; }
  .modal-footer .btn { width: 100%; }
  .toast-region { left: var(--space-3); right: var(--space-3); bottom: calc(var(--bottomnav-h) + var(--space-3)); width: auto; }
  .drawer { width: 100vw; border-left: 0; }
  .stat-row { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--space-3); }
  .page-title { font-size: var(--text-xl); }
}

/* Coarse pointers of any width still get comfortable hit areas */
@media (pointer: coarse) {
  .menu-item { min-height: 40px; }
  .tab { min-height: 42px; }
}

/* ==========================================================================
   22. MODERNISATION PASS
   These override earlier rules on purpose — the originals stay readable as
   the base definition, and everything below is the current visual language.
   ========================================================================== */

.btn { border-radius: var(--radius-md); font-weight: var(--weight-medium); }
.btn-sm { border-radius: var(--radius-sm); }
.btn-primary { box-shadow: 0 1px 2px rgba(15, 23, 42, 0.10); }
.btn-secondary:hover { --btn-bg: var(--surface-raised); --btn-bd: var(--border-strong); --btn-fg: var(--text-primary); }
.btn-quiet { --btn-bg: transparent; --btn-fg: var(--text-secondary); --btn-bd: transparent; }
.btn-quiet:hover { --btn-bg: var(--surface-hover); --btn-fg: var(--text-primary); }

.input, .select, .textarea {
  border-radius: var(--radius-md);
  border-color: var(--border-subtle);
  background: var(--surface-elevated);
  transition: border-color var(--dur-1) var(--ease-out), box-shadow var(--dur-2) var(--ease-out);
}
.input:hover, .select:hover, .textarea:hover { border-color: var(--border-strong); }
.input:focus, .select:focus, .textarea:focus {
  border-color: var(--brand);
  box-shadow: var(--shadow-focus);
  outline: none;
}
.select-sm { height: var(--control-h-sm); font-size: var(--text-sm); padding-block: 0; }
.select.is-set { border-color: var(--brand-border); background: var(--brand-soft); color: var(--brand-ink); }

.card {
  border-radius: var(--radius-lg);
  border-color: var(--border-subtle);
  box-shadow: var(--shadow-xs);
}
.card-hoverable:hover { box-shadow: var(--shadow-md); border-color: var(--border-strong); }

/* Screen-reader-only text — needed by table action headers. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.text-faint { color: var(--text-faint); }

/* Stop background scroll while an overlay owns the screen. */
body.has-overlay { overflow: hidden; }

/* ==========================================================================
   23. FORM GRID
   Fields lay out on a 2-column grid; a spec's `width` picks how many it
   spans. This is what makes a generated form look designed rather than
   stacked.
   ========================================================================== */

.form {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-4) var(--space-4);
  align-items: start;
}
.form-cols-1 { grid-template-columns: minmax(0, 1fr); }
.form-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

.field { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
.field-full { grid-column: 1 / -1; }
.field-half { grid-column: span 1; }
.field-third { grid-column: span 1; }
.field.is-hidden { display: none; }

.field-label {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-secondary);
}
.field-label .req { color: var(--danger-ink); font-weight: var(--weight-bold); }
.field-help { display: inline-flex; color: var(--text-faint); cursor: help; }
.field-help .ic { width: 13px; height: 13px; }
.field-hint { font-size: var(--text-xs); color: var(--text-muted); line-height: var(--leading-snug); }
.field-error {
  font-size: var(--text-xs);
  color: var(--danger-ink);
  font-weight: var(--weight-medium);
  display: flex;
  gap: var(--space-1);
}
.field.has-error .input,
.field.has-error .select,
.field.has-error .textarea,
.field.has-error .combo-control,
.field.has-error .tags { border-color: var(--danger-ink); }
.field.has-error .input:focus { box-shadow: var(--shadow-focus-danger); }
.field-static {
  font-size: var(--text-base);
  color: var(--text-primary);
  padding-block: var(--space-1);
  min-height: var(--control-h);
  display: flex;
  align-items: center;
}

.form-section {
  grid-column: 1 / -1;
  border-top: 1px solid var(--divider);
  padding-top: var(--space-4);
  margin-top: var(--space-2);
  gap: var(--space-1);
}
.form-section:first-child { border-top: 0; padding-top: 0; margin-top: 0; }
.form-section-title {
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-widest);
  text-transform: uppercase;
  color: var(--text-muted);
}
.form-section-hint { font-size: var(--text-xs); color: var(--text-muted); }

.radio-group { display: flex; flex-direction: column; gap: var(--space-2); }
.radio-group .radio { display: flex; align-items: center; gap: var(--space-2); cursor: pointer; }
.radio-hint { color: var(--text-muted); font-size: var(--text-xs); }

/* Switch — a checkbox that reads as an on/off setting. */
.switch { display: inline-flex; align-items: center; gap: var(--space-3); cursor: pointer; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch-track {
  width: 36px; height: 20px; flex: none;
  border-radius: var(--radius-full);
  background: var(--border-strong);
  position: relative;
  transition: background-color var(--dur-2) var(--ease-out);
}
.switch-track::after {
  content: ""; position: absolute; top: 2px; left: 2px;
  width: 16px; height: 16px; border-radius: 50%;
  background: #FFFFFF;
  box-shadow: var(--shadow-sm);
  transition: transform var(--dur-2) var(--ease-out);
}
.switch input:checked + .switch-track { background: var(--brand); }
.switch input:checked + .switch-track::after { transform: translateX(16px); }
.switch input:focus-visible + .switch-track { box-shadow: var(--shadow-focus); }
.switch-label { font-size: var(--text-base); }

.codefield { display: flex; flex-direction: column; }
.codefield-input { font-size: var(--text-sm); line-height: var(--leading-snug); }
.codefield-foot:empty { display: none; }
.codefield-foot {
  font-size: var(--text-xs);
  color: var(--text-muted);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border-subtle);
  border-top: 0;
  border-radius: 0 0 var(--radius-md) var(--radius-md);
  background: var(--surface-sunken);
}
.codefield-foot.is-valid { color: var(--success-ink); }
.codefield-foot.is-invalid { color: var(--danger-ink); }

/* ==========================================================================
   24. COMBOBOX / TAGS / COLOUR
   ========================================================================== */

.combo { position: relative; }
.combo-control { position: relative; display: flex; align-items: center; }
.combo-input { width: 100%; padding-right: 56px; }
.combo-caret,
.combo-clear {
  position: absolute;
  display: inline-flex;
  align-items: center;
  color: var(--text-faint);
  background: none;
  border: 0;
  cursor: pointer;
  padding: var(--space-1);
}
.combo-caret { right: var(--space-2); pointer-events: none; }
.combo-clear { right: 26px; border-radius: var(--radius-full); }
.combo-clear:hover { color: var(--text-primary); background: var(--surface-hover); }
.combo-caret .ic, .combo-clear .ic { width: 14px; height: 14px; }

.combo-list {
  background: var(--surface-elevated);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  padding: var(--space-1);
  max-height: 320px;
  overflow-y: auto;
}
.combo-option {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  width: 100%;
  text-align: left;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--text-base);
  color: var(--text-primary);
  cursor: pointer;
}
.combo-option:hover, .combo-option.is-active { background: var(--surface-hover); }
.combo-option.is-active { box-shadow: inset 2px 0 0 var(--brand); }
.combo-option-main { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.combo-option-sub { font-size: var(--text-xs); color: var(--text-muted); font-family: var(--font-mono); }
.combo-empty { padding: var(--space-3); color: var(--text-muted); font-size: var(--text-sm); text-align: center; }

.tags {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--control-h);
  padding: var(--space-1) var(--space-2);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-elevated);
}
.tags:focus-within { border-color: var(--brand); box-shadow: var(--shadow-focus); }
.tags-input-host { flex: 1 1 160px; min-width: 120px; }
.tags-input-host .combo-input { border: 0; box-shadow: none; height: 26px; padding: 0 24px 0 0; background: transparent; }
.tags-input-host .combo-input:focus { box-shadow: none; }
.tags-input-host .combo-caret { display: none; }
.tags-free {
  flex: 1 1 140px;
  min-width: 100px;
  border: 0;
  background: transparent;
  height: 26px;
  outline: none;
  font-size: var(--text-base);
  color: var(--text-primary);
}

.colorfield { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.colorfield-swatch { position: relative; display: inline-flex; cursor: pointer; }
.colorfield-swatch input[type="color"] { position: absolute; inset: 0; opacity: 0; cursor: pointer; }
.colorfield-chip {
  width: var(--control-h);
  height: var(--control-h);
  border-radius: var(--radius-md);
  border: 1px solid var(--border-strong);
  box-shadow: var(--shadow-inset);
  display: block;
}
.colorfield-hex { width: 108px; text-transform: uppercase; }
.colorfield-presets { display: flex; gap: var(--space-1); flex-wrap: wrap; }
.colorfield-preset {
  width: 22px; height: 22px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--hairline);
  cursor: pointer;
}
.colorfield-preset:hover { transform: scale(1.12); }
.colorfield-preset:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 2px; }

/* ==========================================================================
   25. FLOATING MENUS
   ========================================================================== */

.menu-floating {
  background: var(--surface-elevated);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  padding: var(--space-1);
  max-height: 70vh;
  overflow-y: auto;
  animation: menu-in var(--dur-2) var(--ease-out);
}
@keyframes menu-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }

.menu-floating .menu-item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  text-align: left;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--text-base);
  color: var(--text-primary);
  cursor: pointer;
}
.menu-floating .menu-item:hover:not(:disabled) { background: var(--surface-hover); }
.menu-floating .menu-item:disabled { opacity: 0.45; cursor: default; }
.menu-floating .menu-item.is-danger { color: var(--danger-ink); }
.menu-floating .menu-item.is-danger:hover { background: var(--danger-soft); }
.menu-icon { display: inline-flex; color: var(--text-muted); }
.menu-icon .ic { width: 15px; height: 15px; }
.menu-item.is-danger .menu-icon { color: var(--danger-ink); }
.menu-text { flex: 1; min-width: 0; }
.menu-hint { font-size: var(--text-xs); color: var(--text-muted); font-family: var(--font-mono); }
.menu-check { display: inline-flex; color: var(--brand); }
.menu-check .ic { width: 14px; height: 14px; }

/* ==========================================================================
   26. SHEET (right-hand editing panel)
   ========================================================================== */

.sheet {
  position: fixed;
  top: 0; right: 0; bottom: 0;
  width: var(--sheet-w);
  display: flex;
  flex-direction: column;
  background: var(--surface-elevated);
  border-left: 1px solid var(--border-subtle);
  box-shadow: var(--shadow-xl);
  z-index: var(--z-drawer);
  animation: sheet-in var(--dur-3) var(--ease-out);
}
.sheet-lg { width: min(880px, 100vw); }
@keyframes sheet-in { from { transform: translateX(24px); opacity: 0; } to { transform: none; opacity: 1; } }

.sheet-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-5) var(--space-6);
  border-bottom: 1px solid var(--divider);
}
.sheet-title { font-size: var(--text-lg); font-weight: var(--weight-semibold); letter-spacing: var(--tracking-tight); }
.sheet-subtitle { font-size: var(--text-sm); color: var(--text-muted); margin-top: 2px; }
.sheet-body { flex: 1; overflow-y: auto; padding: var(--space-6); }
.sheet-footer {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-6);
  border-top: 1px solid var(--divider);
  background: var(--surface);
}
.sheet.is-busy, .modal.is-busy { cursor: progress; }
.sheet.is-busy .sheet-body, .modal.is-busy .modal-body { opacity: 0.6; pointer-events: none; }

/* ==========================================================================
   27. TABLE SHELL — bulk bar, sticky head, footer
   ========================================================================== */

.table-shell { display: flex; flex-direction: column; gap: 0; }
.table-wrap.has-sticky-head { max-height: min(70vh, 900px); overflow: auto; }
.table-wrap.has-sticky-head thead th {
  position: sticky;
  top: 0;
  z-index: var(--z-raised);
  background: var(--surface-elevated);
  box-shadow: inset 0 -1px 0 var(--border-subtle);
}
.table tbody tr.is-selected { background: var(--surface-selected); }
.th-check, .td-check { width: 36px; padding-right: 0; }
.th-actions, .td-actions { width: 44px; text-align: right; }
.td-actions .btn-icon { opacity: 0; transition: opacity var(--dur-1) var(--ease-out); }
.table tbody tr:hover .td-actions .btn-icon,
.td-actions .btn-icon:focus-visible { opacity: 1; }
.th-sort { cursor: pointer; user-select: none; white-space: nowrap; }
.th-sort .th-arrow { opacity: 0; display: inline-flex; vertical-align: middle; margin-left: 2px; }
.th-sort .th-arrow .ic { width: 12px; height: 12px; }
.th-sort:hover .th-arrow, .th-sort.is-sorted .th-arrow { opacity: 1; }
.th-sort.is-sorted { color: var(--text-primary); }

.bulk-bar {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  margin-bottom: var(--space-2);
  border: 1px solid var(--brand-border);
  border-radius: var(--radius-md);
  background: var(--brand-soft);
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
}
.bulk-count { font-weight: var(--weight-semibold); font-size: var(--text-sm); color: var(--brand-ink); }
.bulk-actions { display: flex; gap: var(--space-2); flex-wrap: wrap; flex: 1; }

.table-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-1);
  flex-wrap: wrap;
}
.table-foot-left, .table-foot-right { display: flex; align-items: center; gap: var(--space-3); }
.table-note { font-size: var(--text-xs); color: var(--text-muted); }

/* ==========================================================================
   28. PAGE HEADER / CRUMBS
   ========================================================================== */

.page-title-row { display: flex; align-items: center; gap: var(--space-2); }
.crumbs { display: flex; align-items: center; gap: var(--space-1); font-size: var(--text-xs); color: var(--text-muted); margin-bottom: var(--space-1); }
.crumbs a { color: var(--text-muted); text-decoration: none; }
.crumbs a:hover { color: var(--brand); text-decoration: underline; }
.crumb-sep { display: inline-flex; opacity: 0.6; }
.crumb-sep .ic { width: 12px; height: 12px; }

/* ==========================================================================
   29. SORTABLE LISTS
   ========================================================================== */

.sortable-row { display: flex; align-items: center; gap: var(--space-3); }
[data-grip] { cursor: grab; color: var(--text-faint); display: inline-flex; }
[data-grip]:active { cursor: grabbing; }
[data-grip]:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 2px; border-radius: var(--radius-xs); }
.is-dragging { opacity: 0.45; }
.is-drop-target { box-shadow: 0 -2px 0 var(--brand); }

/* ==========================================================================
   30. COMMAND PALETTE
   ========================================================================== */

.palette-layer { align-items: flex-start; padding-top: 12vh; }
.palette {
  width: min(640px, calc(100vw - 32px));
  background: var(--surface-elevated);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xl);
  overflow: hidden;
  animation: palette-in var(--dur-2) var(--ease-out);
}
@keyframes palette-in { from { opacity: 0; transform: translateY(-8px) scale(0.99); } to { opacity: 1; transform: none; } }
.palette-input-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--divider);
  color: var(--text-muted);
}
.palette-input {
  flex: 1;
  border: 0;
  background: transparent;
  outline: none;
  font-size: var(--text-md);
  color: var(--text-primary);
}
.palette-kbd {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  color: var(--text-muted);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-xs);
  padding: 1px 5px;
}
.palette-results { max-height: 52vh; overflow-y: auto; padding: var(--space-2); }
.palette-group {
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-widest);
  color: var(--text-muted);
  padding: var(--space-3) var(--space-3) var(--space-1);
}
.palette-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  text-align: left;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  cursor: pointer;
  color: var(--text-primary);
}
.palette-item:hover, .palette-item.is-active { background: var(--surface-hover); }
.palette-icon { display: inline-flex; color: var(--text-muted); }
.palette-icon .ic { width: 15px; height: 15px; }
.palette-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.palette-sub { font-size: var(--text-xs); color: var(--text-muted); }
.palette-empty { padding: var(--space-6); text-align: center; color: var(--text-muted); font-size: var(--text-sm); }

/* ==========================================================================
   31. TOASTS — action + leave animation
   ========================================================================== */

.toast-action {
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--brand);
  background: none;
  border: 0;
  cursor: pointer;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  white-space: nowrap;
}
.toast-action:hover { background: var(--surface-hover); }
.toast.is-leaving { opacity: 0; transform: translateY(6px); transition: all var(--dur-2) var(--ease-in); }

/* ==========================================================================
   32. EMPTY STATE ACTIONS
   ========================================================================== */

.empty-actions { display: flex; gap: var(--space-2); justify-content: center; margin-top: var(--space-4); flex-wrap: wrap; }

/* ==========================================================================
   33. BRAND LOGO WITH AN IMAGE
   ========================================================================== */

.sidebar-logo.has-image { background: transparent; padding: 0; overflow: hidden; }
.sidebar-logo.has-image img { width: 100%; height: 100%; object-fit: contain; }

/* ==========================================================================
   34. BUILDER LAYOUTS — palette · canvas · inspector
   ========================================================================== */

.builder {
  display: grid;
  grid-template-columns: 220px minmax(0, 1fr) 320px;
  gap: var(--space-4);
  align-items: start;
  min-height: 60vh;
}
.builder-pane {
  background: var(--surface-elevated);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.builder-pane-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--divider);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--text-muted);
}
.builder-pane-body { padding: var(--space-4); overflow-y: auto; }
.builder-canvas { min-height: 50vh; background: var(--surface-sunken); }

.palette-chip {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-elevated);
  font-size: var(--text-sm);
  cursor: pointer;
  text-align: left;
  color: var(--text-primary);
}
.palette-chip:hover { border-color: var(--brand); background: var(--brand-soft); color: var(--brand-ink); }
.palette-chip .ic { width: 14px; height: 14px; color: var(--text-muted); }
.palette-chip:hover .ic { color: var(--brand); }

/* The canvas mirrors the real form grid so half-width really looks half. */
.canvas-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3);
  align-content: start;
}
.canvas-field {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-elevated);
  cursor: pointer;
}
.canvas-field.is-half { grid-column: span 1; }
.canvas-field:hover { border-color: var(--border-strong); }
.canvas-field.is-active { border-color: var(--brand); box-shadow: 0 0 0 1px var(--brand); }
.canvas-field-main { flex: 1; min-width: 0; }
.canvas-field-label { font-size: var(--text-base); font-weight: var(--weight-medium); }
.canvas-field-meta { font-size: var(--text-xs); color: var(--text-muted); font-family: var(--font-mono); }
.canvas-section {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-3);
  padding-bottom: var(--space-2);
  border-bottom: 2px solid var(--border-strong);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--text-secondary);
}
.canvas-empty {
  grid-column: 1 / -1;
  padding: var(--space-10);
  text-align: center;
  color: var(--text-muted);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-md);
}

@media (max-width: 1200px) {
  .builder { grid-template-columns: 180px minmax(0, 1fr); }
  .builder > .builder-inspector { grid-column: 1 / -1; }
}
@media (max-width: 860px) {
  .builder { grid-template-columns: minmax(0, 1fr); }
  .form { grid-template-columns: minmax(0, 1fr); }
  .field-half, .field-third { grid-column: 1 / -1; }
  .canvas-grid { grid-template-columns: minmax(0, 1fr); }
  .canvas-field.is-half { grid-column: 1 / -1; }
  .sheet, .sheet-lg { width: 100vw; }
}

/* ==========================================================================
   35. FILTER BUILDER
   ========================================================================== */

.filter-rows { display: flex; flex-direction: column; gap: var(--space-2); }
.filter-row {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.9fr) minmax(0, 1.4fr) auto;
  gap: var(--space-2);
  align-items: center;
}
.filter-join {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-xs);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
}
.filter-preview {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--brand-soft);
  border: 1px solid var(--brand-border);
  color: var(--brand-ink);
  font-size: var(--text-sm);
}
.filter-preview strong { font-size: var(--text-lg); color: var(--brand-ink); }
@media (max-width: 720px) {
  .filter-row { grid-template-columns: minmax(0, 1fr) auto; }
}

/* ==========================================================================
   36. BRANDING PREVIEW
   ========================================================================== */

.brand-preview {
  display: grid;
  gap: var(--space-4);
  padding: var(--space-5);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  background: var(--surface-elevated);
}
.brand-swatches { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.brand-swatch {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  align-items: center;
  font-size: var(--text-2xs);
  color: var(--text-muted);
  font-family: var(--font-mono);
}
.brand-swatch i {
  width: 52px; height: 34px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--hairline);
  display: block;
}
.contrast-grid { display: grid; gap: var(--space-2); }
.contrast-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  font-size: var(--text-sm);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--surface-sunken);
}
.contrast-row .ratio { font-family: var(--font-mono); font-weight: var(--weight-semibold); }
.contrast-row.is-pass .ratio { color: var(--success-ink); }
.contrast-row.is-fail .ratio { color: var(--danger-ink); }

/* ==========================================================================
   37. OBJECT BUILDER CARDS
   The card is a <button> so the whole tile is one keyboard target; buttons
   centre their content by default, which is not what a card wants.
   ========================================================================== */

.object-card {
  display: block;
  width: 100%;
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
  padding: 0;
}
.object-card .card-header { align-items: center; }
.object-card .card-title { display: flex; align-items: center; gap: var(--space-2); }
.object-card .card-title .ic { width: 16px; height: 16px; color: var(--text-muted); }
.object-card-api { font-size: var(--text-xs); color: var(--text-muted); }
.object-card-desc {
  margin: var(--space-2) 0 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.object-card-stats {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-3);
  font-size: var(--text-xs);
  color: var(--text-muted);
}
.object-card-stats span { display: inline-flex; align-items: center; gap: var(--space-1); }
.object-card-stats .ic { width: 13px; height: 13px; }
.object-card-menu { margin-left: var(--space-1); }

.cell-sub { font-size: var(--text-xs); color: var(--text-muted); margin-top: 1px; }
.field-static-note {
  font-size: var(--text-2xs);
  color: var(--text-faint);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  margin-left: var(--space-2);
}

/* A toolbar select should size to its content, not stretch. */
.toolbar-left .select { width: auto; min-width: 140px; max-width: 260px; }
.toolbar-left .search { min-width: 220px; flex: 0 1 320px; }

/* ==========================================================================
   38. FORM BUILDER
   ========================================================================== */

.builder-hint { font-size: var(--text-2xs); color: var(--text-faint); text-transform: none; letter-spacing: 0; }
.builder-canvas .builder-pane-body { background: var(--surface-sunken); }
.canvas-grip { color: var(--text-faint); display: inline-flex; cursor: grab; }
.canvas-grip .ic { width: 14px; height: 14px; }
.canvas-section-title { flex: 1; }
.canvas-section .btn-icon { opacity: 0; }
.canvas-section:hover .btn-icon, .canvas-section .btn-icon:focus-visible { opacity: 1; }
.canvas-empty.is-slim { padding: var(--space-5); font-size: var(--text-sm); }
.canvas-field .req { color: var(--danger-ink); margin-left: 2px; }
.canvas-field:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 2px; }
.canvas-grid + .canvas-section { margin-top: var(--space-5); }

.inspector-head {
  padding-bottom: var(--space-3);
  margin-bottom: var(--space-3);
  border-bottom: 1px solid var(--divider);
}
.inspector-api { font-size: var(--text-xs); color: var(--text-muted); }
.inspector-actions {
  display: flex;
  gap: var(--space-2);
  align-items: center;
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: 1px solid var(--divider);
}
.inspector-actions [data-remove] { margin-left: auto; }
.builder-inspector .form { grid-template-columns: minmax(0, 1fr); }
.builder-inspector .field-half,
.builder-inspector .field-third { grid-column: 1 / -1; }

/* Preview — deliberately looks like the public page, not like the admin UI. */
.preview-sheet {
  max-width: 720px;
  margin: var(--space-5) auto;
  padding: var(--space-8);
  background: var(--surface-elevated);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}
.preview-head { margin-bottom: var(--space-6); }
.preview-head h2 { font-size: var(--text-xl); }
.preview-head p { color: var(--text-secondary); margin-top: var(--space-2); }
.preview-section { margin-top: var(--space-8); }
.preview-section-title {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-widest);
  color: var(--text-muted);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--divider);
  margin-bottom: var(--space-4);
}
.preview-section-desc { font-size: var(--text-sm); color: var(--text-muted); margin-bottom: var(--space-4); }
.preview-heading { font-size: var(--text-lg); margin-top: var(--space-4); }
.preview-foot { margin-top: var(--space-8); display: flex; justify-content: flex-end; }

/* ==========================================================================
   39. FORM LIST CARDS
   ========================================================================== */

.form-card-desc { font-size: var(--text-sm); color: var(--text-secondary); margin: 0 0 var(--space-3); }
.form-card-stats { display: flex; gap: var(--space-4); font-size: var(--text-xs); color: var(--text-muted); }
.form-card-stats span { display: inline-flex; align-items: center; gap: var(--space-1); }
.form-card-stats .ic { width: 13px; height: 13px; }
.form-card-url {
  margin-top: var(--space-3);
  font-size: var(--text-2xs);
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.card-footer-spacer { flex: 1; }

/* ==========================================================================
   40. SETUP SHELL
   ========================================================================== */

.setup-shell {
  display: grid;
  grid-template-columns: 268px minmax(0, 1fr);
  gap: var(--space-6);
  align-items: start;
}
.setup-nav {
  position: sticky;
  top: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}
.setup-nav-group { display: flex; flex-direction: column; gap: var(--space-1); }
.setup-nav-label {
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-widest);
  color: var(--text-muted);
  padding: 0 var(--space-3) var(--space-1);
}
.setup-nav-item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3);
  border-radius: var(--radius-md);
  color: var(--text-secondary);
  text-decoration: none;
  border: 1px solid transparent;
}
.setup-nav-item:hover { background: var(--surface-hover); color: var(--text-primary); text-decoration: none; }
.setup-nav-item.is-active {
  background: var(--brand-soft);
  border-color: var(--brand-border);
  color: var(--brand-ink);
}
.setup-nav-icon { display: inline-flex; margin-top: 1px; }
.setup-nav-icon .ic { width: 16px; height: 16px; }
.setup-nav-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.setup-nav-name { font-size: var(--text-base); font-weight: var(--weight-medium); }
.setup-nav-blurb { font-size: var(--text-xs); color: var(--text-muted); line-height: var(--leading-snug); }
.setup-nav-item.is-active .setup-nav-blurb { color: var(--brand-ink); opacity: 0.8; }

.setup-panel { min-width: 0; }
.setup-panel-head { margin-bottom: var(--space-5); }
.setup-cards { display: flex; flex-direction: column; gap: var(--space-5); padding-bottom: var(--space-16); }
.setup-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-4);
  border-radius: var(--radius-lg);
  background: var(--surface-elevated);
  border: 1px solid var(--border-subtle);
  position: sticky;
  bottom: var(--space-4);
  box-shadow: var(--shadow-md);
}

@media (max-width: 980px) {
  .setup-shell { grid-template-columns: minmax(0, 1fr); }
  .setup-nav { position: static; flex-direction: row; flex-wrap: wrap; gap: var(--space-3); }
  .setup-nav-group { flex-direction: row; flex-wrap: wrap; }
  .setup-nav-label { width: 100%; }
  .setup-nav-blurb { display: none; }
}

/* ==========================================================================
   41. CONTRAST REPORT
   ========================================================================== */

.contrast-wrap { margin-top: var(--space-4); }
.contrast-legend {
  display: grid;
  grid-template-columns: 1fr auto auto;
  gap: var(--space-3);
  padding: 0 var(--space-3) var(--space-1);
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  color: var(--text-faint);
}
.contrast-legend span:not(:first-child) { min-width: 62px; text-align: right; }
.contrast-row { display: grid; grid-template-columns: 1fr auto auto; }
.contrast-row .ratio { min-width: 62px; text-align: right; }
.contrast-dot {
  display: inline-block;
  width: 12px; height: 12px;
  border-radius: var(--radius-xs);
  margin-right: var(--space-2);
  vertical-align: -1px;
  border: 1px solid var(--hairline);
}
.contrast-note {
  font-size: var(--text-2xs);
  color: var(--text-muted);
  margin-left: var(--space-2);
}
.contrast-verdict {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  margin-top: var(--space-1);
}
.contrast-verdict .ic { width: 15px; height: 15px; }
.contrast-verdict.is-pass { color: var(--success-ink); }
.contrast-verdict.is-fail { color: var(--danger-ink); }

.brand-preview-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}

/* ==========================================================================
   42. SETUP SECTION ODDS AND ENDS
   ========================================================================== */

.channel-hint { font-size: var(--text-sm); color: var(--text-muted); margin-top: var(--space-3); }
.channel-env {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin-top: var(--space-2);
  font-size: var(--text-xs);
  color: var(--text-secondary);
}
.channel-env li {
  background: var(--surface-sunken);
  border-radius: var(--radius-xs);
  padding: 2px var(--space-2);
}
.is-full { color: var(--danger-ink); }

/* Launch blockers, listed rather than collapsed into one sentence. */
.blocker-list { margin: var(--space-2) 0 0; padding-left: var(--space-4); list-style: disc; }
.blocker-list li { margin-bottom: var(--space-1); }

/* ==========================================================================
   43. FILTER BUILDER
   ========================================================================== */

.filter-builder { display: flex; flex-direction: column; gap: var(--space-3); }
.filter-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.filter-empty {
  font-size: var(--text-sm);
  color: var(--text-muted);
  padding: var(--space-4);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-md);
  text-align: center;
  margin: 0;
}
.filter-pair { display: flex; gap: var(--space-2); }
.filter-pair .input { min-width: 0; }
.filter-novalue {
  font-size: var(--text-xs);
  color: var(--text-faint);
  font-style: italic;
  align-self: center;
}
.filter-row .btn-icon { color: var(--text-faint); }
.filter-row .btn-icon:hover { color: var(--danger-ink); background: var(--danger-soft); }

.segment-sample {
  margin-top: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-sunken);
}
.segment-sample-head {
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  color: var(--text-muted);
  margin-bottom: var(--space-2);
}
.segment-sample ul { display: flex; flex-direction: column; gap: var(--space-1); font-size: var(--text-sm); }

/* ==========================================================================
   44. JOURNEYS & TEMPLATES
   ========================================================================== */

.journey-desc { font-size: var(--text-sm); color: var(--text-secondary); margin: 0 0 var(--space-3); }
.journey-stats { display: flex; gap: var(--space-4); font-size: var(--text-xs); color: var(--text-muted); }
.journey-stats span { display: inline-flex; align-items: center; gap: var(--space-1); }
.journey-stats .ic { width: 13px; height: 13px; }

.journey-steps { display: flex; flex-direction: column; gap: var(--space-2); }
.journey-step {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-elevated);
  position: relative;
}
/* The connecting rail is what makes the list read as a sequence. */
.journey-step:not(:last-child)::after {
  content: "";
  position: absolute;
  left: 46px;
  top: 100%;
  height: var(--space-2);
  width: 2px;
  background: var(--border-strong);
}
.journey-step-grip { color: var(--text-faint); display: inline-flex; cursor: grab; }
.journey-step-index {
  width: 22px; height: 22px;
  border-radius: var(--radius-full);
  background: var(--brand-soft);
  color: var(--brand-ink);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.journey-step-icon { color: var(--text-muted); display: inline-flex; }
.journey-step-main { flex: 1; min-width: 0; }
.journey-step-title { font-size: var(--text-base); font-weight: var(--weight-medium); }
.journey-step-meta { font-size: var(--text-xs); color: var(--text-muted); margin-top: 1px; }
.journey-step .btn-icon { opacity: 0; }
.journey-step:hover .btn-icon, .journey-step .btn-icon:focus-visible { opacity: 1; }

.template-merge {
  margin-top: var(--space-5);
  padding: var(--space-4);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-sunken);
}
.template-merge-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  color: var(--text-muted);
  margin-bottom: var(--space-3);
}
.template-merge-list { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.chip-action { cursor: pointer; font-family: var(--font-mono); font-size: var(--text-2xs); }
.chip-action:hover { background: var(--brand-soft); color: var(--brand-ink); border-color: var(--brand-border); }
.sms-counter.is-over { color: var(--warning-ink); font-weight: var(--weight-medium); }

.template-preview-subject {
  padding-bottom: var(--space-3);
  margin-bottom: var(--space-3);
  border-bottom: 1px solid var(--divider);
}
.template-preview-body {
  white-space: pre-wrap;
  font-size: var(--text-base);
  line-height: var(--leading-relaxed);
}


.user-cell { display: flex; align-items: center; gap: var(--space-2); }
.perm-yes { color: var(--success-ink); display: inline-flex; }
.perm-yes .ic { width: 14px; height: 14px; }

/* ==========================================================================
   45. STUDENT RECORD
   ========================================================================== */

.optin { display: inline-flex; align-items: center; gap: 2px; font-size: var(--text-xs); margin-right: var(--space-2); }
.optin .ic { width: 12px; height: 12px; }
.optin.is-on { color: var(--success-ink); }
.optin.is-off { color: var(--text-faint); text-decoration: line-through; }
.guardian-card .card-footer { justify-content: flex-end; }

.sibling-list { display: flex; flex-direction: column; gap: var(--space-2); }
.sibling-list li {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
}
.sibling-list li .btn-icon { margin-left: auto; }

/* ==========================================================================
   46. TASK LIST
   ========================================================================== */

.task-bucket { margin-bottom: var(--space-6); }
.task-bucket-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  color: var(--text-muted);
  margin-bottom: var(--space-3);
}
.task-bucket-head .ic { width: 14px; height: 14px; }
.task-list { display: flex; flex-direction: column; gap: var(--space-2); }
.task-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-elevated);
}
.task-row.is-done { opacity: 0.55; }
.task-row.is-done .task-title { text-decoration: line-through; }
.task-check {
  width: 24px; height: 24px; flex: none;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-full);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: transparent;
  cursor: pointer;
  background: var(--surface-elevated);
}
.task-check:hover:not(:disabled) { border-color: var(--success-ink); color: var(--success-ink); }
.task-check:disabled { border-color: var(--success-ink); color: var(--success-ink); cursor: default; }
.task-check .ic { width: 14px; height: 14px; }
.task-main { flex: 1; min-width: 0; }
.task-title { font-size: var(--text-base); }
.task-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin-top: 2px;
}
.task-meta span, .task-meta a { display: inline-flex; align-items: center; gap: 3px; }
.task-meta .ic { width: 12px; height: 12px; }
.task-row .task-actions .btn-icon { opacity: 0; }
.task-row:hover .task-actions .btn-icon { opacity: 1; }

/* ==========================================================================
   47. WEEK GRID (counselling calendar)
   ========================================================================== */

.week-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--space-3);
}
.week-day {
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-elevated);
  overflow: hidden;
  min-height: 160px;
}
.week-day-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--divider);
  background: var(--surface-sunken);
}
.week-day-name { font-size: var(--text-xs); font-weight: var(--weight-semibold); }
.week-day-count { font-size: var(--text-2xs); color: var(--text-muted); font-family: var(--font-mono); }
.week-day-body { padding: var(--space-2); display: flex; flex-direction: column; gap: var(--space-2); }
.week-slot {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--brand-soft);
  border-left: 3px solid var(--brand);
  text-decoration: none;
  color: var(--text-primary);
}
.week-slot:hover { background: var(--brand-soft-hover); text-decoration: none; }
.week-slot-time { font-family: var(--font-mono); font-size: var(--text-2xs); color: var(--brand-ink); }
.week-slot-name { font-size: var(--text-sm); font-weight: var(--weight-medium); }
.week-slot-mode { font-size: var(--text-2xs); color: var(--text-muted); }

/* ==========================================================================
   48. RECORD VIEW (rendered from a page layout)
   ========================================================================== */

.record-view { display: flex; flex-direction: column; gap: var(--space-5); }
.record-section {
  background: var(--surface-elevated);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}
.record-section.is-empty { background: transparent; border-style: dashed; }
.record-section-head { margin-bottom: var(--space-4); }
.record-section-head h3 {
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  text-transform: uppercase;
  letter-spacing: var(--tracking-widest);
  color: var(--text-muted);
}
.record-section-head p { font-size: var(--text-sm); color: var(--text-muted); margin-top: var(--space-1); }
.record-section-empty { font-size: var(--text-sm); color: var(--text-faint); margin: 0; }

.record-grid { display: grid; gap: var(--space-4); }
.record-cols-1 { grid-template-columns: minmax(0, 1fr); }
.record-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.record-field { min-width: 0; }
.record-full { grid-column: 1 / -1; }
.record-field dt {
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  color: var(--text-muted);
  margin-bottom: 2px;
}
.record-field dd { font-size: var(--text-base); color: var(--text-primary); margin: 0; }
.value-long { white-space: pre-wrap; line-height: var(--leading-relaxed); }
.bool-yes { display: inline-flex; align-items: center; gap: 3px; color: var(--success-ink); }
.bool-yes .ic { width: 14px; height: 14px; }

@media (max-width: 720px) {
  .record-cols-2 { grid-template-columns: minmax(0, 1fr); }
}

/* ==========================================================================
   49. LAYOUT BUILDER
   ========================================================================== */

.layout-builder {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: var(--space-4);
  align-items: start;
  margin-top: var(--space-4);
}
.layout-canvas .builder-pane-body { background: var(--surface-sunken); display: flex; flex-direction: column; gap: var(--space-4); }
.layout-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-elevated);
  margin-bottom: var(--space-4);
}
.layout-meta strong { margin-right: var(--space-2); }

.layout-section {
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-elevated);
  overflow: hidden;
}
.layout-section-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--divider);
  background: var(--surface-sunken);
}
.layout-section-title { font-size: var(--text-sm); font-weight: var(--weight-semibold); flex: 1; }
.layout-section-cols { font-size: var(--text-2xs); color: var(--text-muted); }
.layout-section-head .btn-icon { opacity: 0; }
.layout-section:hover .btn-icon, .layout-section-head .btn-icon:focus-visible { opacity: 1; }
.layout-section-fields {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-2);
  padding: var(--space-3);
  min-height: 60px;
}

.layout-field {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  background: var(--surface-elevated);
  cursor: pointer;
  min-width: 0;
}
.layout-field.is-full { grid-column: 1 / -1; }
.layout-field:hover { border-color: var(--brand); }
.layout-field:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 2px; }
.layout-grip { color: var(--text-faint); display: inline-flex; cursor: grab; }
.layout-grip .ic { width: 13px; height: 13px; }
.layout-field-icon { color: var(--text-muted); display: inline-flex; }
.layout-field-icon .ic { width: 14px; height: 14px; }
.layout-field-main { flex: 1; min-width: 0; }
.layout-field-label { font-size: var(--text-sm); font-weight: var(--weight-medium); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.layout-field-meta { font-size: var(--text-2xs); color: var(--text-muted); font-family: var(--font-mono); }
.layout-unplaced { justify-content: flex-start; }
.layout-unplaced span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

@media (max-width: 1100px) {
  .layout-builder { grid-template-columns: minmax(0, 1fr); }
  .layout-section-fields { grid-template-columns: minmax(0, 1fr); }
  .layout-field.is-full { grid-column: 1 / -1; }
}

/* ==========================================================================
   50. RECORD PAGE CHROME — strip, stage rail, history, related
   ========================================================================== */

.record-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--space-3);
  padding: var(--space-4);
  margin-bottom: var(--space-4);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  background: var(--surface-elevated);
}
.record-strip-item { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.record-strip-item span {
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  color: var(--text-muted);
}
.record-strip-item strong { font-size: var(--text-base); font-weight: var(--weight-semibold); }

.stage-rail {
  display: flex;
  align-items: center;
  gap: 0;
  overflow-x: auto;
  padding: var(--space-1) 0 var(--space-4);
  margin-bottom: var(--space-2);
}
.stage-step {
  --step-colour: var(--brand);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
  flex: 1 0 auto;
  min-width: 92px;
  padding: 0 var(--space-1);
  background: none;
  border: 0;
  cursor: pointer;
  position: relative;
  color: var(--text-muted);
}
.stage-step::before {
  content: "";
  position: absolute;
  top: 9px; left: -50%; width: 100%;
  height: 2px;
  background: var(--border-subtle);
  z-index: 0;
}
.stage-step:first-child::before { display: none; }
.stage-step.is-done::before, .stage-step.is-current::before { background: var(--step-colour); }
.stage-step-dot {
  width: 20px; height: 20px;
  border-radius: 50%;
  border: 2px solid var(--border-strong);
  background: var(--surface);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  z-index: 1;
  color: #FFFFFF;
}
.stage-step-dot .ic { width: 11px; height: 11px; }
.stage-step.is-done .stage-step-dot { background: var(--step-colour); border-color: var(--step-colour); }
.stage-step.is-current .stage-step-dot {
  border-color: var(--step-colour);
  box-shadow: 0 0 0 4px var(--brand-soft);
}
.stage-step-label { font-size: var(--text-2xs); text-align: center; line-height: 1.2; }
.stage-step.is-current .stage-step-label { color: var(--text-primary); font-weight: var(--weight-semibold); }
.stage-step:hover:not(.is-terminal) .stage-step-label { color: var(--text-primary); }
.stage-step.is-terminal { cursor: default; }
.stage-step.is-terminal::before { display: none; }

.stage-history { display: flex; flex-direction: column; gap: var(--space-3); }
.stage-history li { display: flex; flex-direction: column; gap: 1px; font-size: var(--text-sm); }
.stage-history-when { font-size: var(--text-xs); color: var(--text-muted); }
.stage-history-note { font-size: var(--text-xs); color: var(--text-secondary); font-style: italic; }

.guardian-mini { padding: var(--space-2) 0; border-bottom: 1px solid var(--divider); }
.guardian-mini:last-child { border-bottom: 0; }
.guardian-mini-contact { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-top: 2px; font-size: var(--text-xs); }
.guardian-mini-contact a { display: inline-flex; align-items: center; gap: 3px; }
.guardian-mini-contact .ic { width: 12px; height: 12px; }

.related-list { display: flex; flex-direction: column; gap: var(--space-2); font-size: var(--text-sm); }
.related-list li { display: flex; align-items: center; gap: var(--space-2); }
.related-list .ic { width: 14px; height: 14px; color: var(--text-muted); flex: none; }

/* ==========================================================================
   51. CSV IMPORT WIZARD
   ========================================================================== */

.dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-12) var(--space-6);
  border: 2px dashed var(--border-strong);
  border-radius: var(--radius-lg);
  background: var(--surface-sunken);
  cursor: pointer;
  text-align: center;
  transition: border-color var(--dur-2) var(--ease-out), background var(--dur-2) var(--ease-out);
}
.dropzone:hover, .dropzone.is-over, .dropzone:focus-visible {
  border-color: var(--brand);
  background: var(--brand-soft);
  outline: none;
}
.dropzone .ic { width: 28px; height: 28px; color: var(--text-muted); }
.dropzone:hover .ic, .dropzone.is-over .ic { color: var(--brand); }
.dropzone-title { font-size: var(--text-md); font-weight: var(--weight-medium); }
.dropzone-hint { font-size: var(--text-xs); color: var(--text-muted); max-width: 46ch; }

.import-help { margin-top: var(--space-6); }
.import-help h4 { font-size: var(--text-sm); margin-bottom: var(--space-2); }
.import-help p { font-size: var(--text-sm); color: var(--text-muted); margin-top: var(--space-3); }
.import-sample {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  background: var(--surface-sunken);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  padding: var(--space-3);
  overflow-x: auto;
  white-space: pre;
}

.import-summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--divider);
  margin-bottom: var(--space-4);
}
.import-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}
.import-stat {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-elevated);
}
.import-stat strong { font-size: var(--text-lg); font-family: var(--font-mono); }
.import-stat span { font-size: var(--text-2xs); color: var(--text-muted); line-height: 1.2; }
.import-stat.is-good { border-color: var(--success-border); background: var(--success-soft); }
.import-stat.is-good strong { color: var(--success-ink); }
.import-stat.is-warn { border-color: var(--warning-border); background: var(--warning-soft); }
.import-stat.is-warn strong { color: var(--warning-ink); }

.import-heading {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  color: var(--text-muted);
  margin: var(--space-5) 0 var(--space-3);
}
.mapping-grid { display: flex; flex-direction: column; gap: var(--space-2); }
.mapping-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  gap: var(--space-3);
  align-items: center;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-elevated);
}
.mapping-source { display: flex; flex-direction: column; min-width: 0; }
.mapping-header { font-size: var(--text-sm); font-weight: var(--weight-medium); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mapping-example { font-size: var(--text-2xs); color: var(--text-muted); font-family: var(--font-mono); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mapping-arrow { color: var(--text-faint); display: inline-flex; }
.mapping-arrow .ic { width: 14px; height: 14px; }

@media (max-width: 640px) {
  .mapping-row { grid-template-columns: minmax(0, 1fr); }
  .mapping-arrow { display: none; }
}

/* ==========================================================================
   52. FILE UPLOAD
   ========================================================================== */

.file-chip {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  margin-top: var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-elevated);
  position: relative;
  overflow: hidden;
}
.file-chip .ic { width: 18px; height: 18px; color: var(--text-muted); }
.file-chip-main { flex: 1; min-width: 0; }
.file-chip-name { font-size: var(--text-sm); font-weight: var(--weight-medium); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.file-chip-size { font-size: var(--text-2xs); color: var(--text-muted); font-family: var(--font-mono); }
.file-progress {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 3px;
  background: var(--surface-sunken);
}
.file-progress span {
  display: block;
  height: 100%;
  width: 0;
  background: var(--brand);
  transition: width var(--dur-2) var(--ease-out);
}

/* ==========================================================================
   53. SCORING & ROUTING
   ========================================================================== */

.explainer { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: var(--space-6); }
.explainer-col h4 {
  display: flex; align-items: center; gap: var(--space-2);
  font-size: var(--text-sm); margin-bottom: var(--space-3);
}
.explainer-col h4 .ic { width: 16px; height: 16px; color: var(--brand); }
.explainer-col ol { list-style: decimal; padding-left: var(--space-5); display: flex; flex-direction: column; gap: var(--space-2); }
.explainer-col li { font-size: var(--text-sm); color: var(--text-secondary); line-height: var(--leading-snug); }
.explainer-col p { font-size: var(--text-sm); color: var(--text-muted); margin-top: var(--space-3); }

.rule-code {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  background: var(--surface-sunken);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-xs);
  padding: 1px 5px;
  display: inline-block;
  max-width: 340px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: middle;
}
.table tbody tr.is-muted { opacity: 0.55; }

.sim-total {
  display: flex;
  gap: var(--space-8);
  padding: var(--space-5);
  border-radius: var(--radius-lg);
  border: 1px solid var(--border-subtle);
  background: var(--surface-sunken);
  margin-top: var(--space-4);
}
.sim-total > div { display: flex; flex-direction: column; gap: 2px; }
.sim-total span { font-size: var(--text-2xs); text-transform: uppercase; letter-spacing: var(--tracking-wider); color: var(--text-muted); }
.sim-total strong { font-size: var(--text-2xl); font-family: var(--font-mono); }
.sim-hot { border-color: var(--hot-border); background: var(--hot-soft); }
.sim-hot strong { color: var(--hot-ink); }
.sim-warm { border-color: var(--warm-border); background: var(--warm-soft); }
.sim-warm strong { color: var(--warm-ink); }
.sim-cold { border-color: var(--cold-border); background: var(--cold-soft); }
.sim-cold strong { color: var(--cold-ink); }
.sim-reason { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); color: var(--text-secondary); margin-top: var(--space-3); }
.sim-reason .ic { width: 15px; height: 15px; color: var(--text-muted); }

/* ==========================================================================
   54. CAMPAIGN ENGAGEMENT
   ========================================================================== */

.campaign-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
  gap: var(--space-2);
}
.stat-note {
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin-top: var(--space-3);
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.stat-note .ic { width: 14px; height: 14px; flex: none; }

.ab-arms { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: var(--space-3); }
.ab-arm {
  padding: var(--space-4);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-sunken);
}
.ab-arm.is-winner { border-color: var(--success-border); background: var(--success-soft); }
.ab-arm-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-weight: var(--weight-semibold);
  font-size: var(--text-sm);
  margin-bottom: var(--space-3);
}
.link-cell { max-width: 380px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ==========================================================================
   55. EMAIL BUILDER
   ========================================================================== */

.builder-switch {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4);
  margin-top: var(--space-4);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--surface-sunken);
}
.builder-switch p { font-size: var(--text-sm); color: var(--text-muted); margin-top: 2px; }

.email-builder {
  display: grid;
  grid-template-columns: 160px minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-3);
  margin-top: var(--space-4);
  align-items: start;
}
.email-block {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  background: var(--surface-elevated);
  margin-bottom: var(--space-2);
  cursor: pointer;
}
.email-block:hover { border-color: var(--border-strong); }
.email-block.is-active { border-color: var(--brand); box-shadow: 0 0 0 1px var(--brand); }
.email-block:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 2px; }
.email-block-main { flex: 1; min-width: 0; }
.email-block-type {
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  color: var(--text-muted);
}
.email-block-summary {
  font-size: var(--text-sm);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.email-block .btn-icon { opacity: 0; }
.email-block:hover .btn-icon, .email-block .btn-icon:focus-visible { opacity: 1; }

.email-preview { padding: 0; background: var(--surface-sunken); }
.email-frame {
  width: 100%;
  min-height: 420px;
  border: 0;
  display: block;
  background: #FFFFFF;
}

@media (max-width: 1100px) {
  .email-builder { grid-template-columns: minmax(0, 1fr); }
  .email-frame { min-height: 320px; }
}

/* ─────────────────────────────────────────────────────────────────
   Ledger and preview tables
   ─────────────────────────────────────────────────────────────────
   A compact table for use INSIDE a sheet or modal — the fee ledger, the
   import preview, daycare occupancy. Deliberately not `dataTable`: those
   are full page-level tables with sorting, paging and row actions, and
   none of that belongs in a dialog that is showing you a total.

   Every numeric column is tabular-lined so that figures line up digit
   over digit. A fee clerk comparing ₹50,000 with ₹5,000 in a proportional
   font misreads it, and that is not a hypothetical. */
.mini-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}
.mini-table th,
.mini-table td {
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--border);
  text-align: left;
  vertical-align: top;
}
.mini-table thead th {
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  font-weight: var(--weight-semibold);
  border-bottom: 1px solid var(--border-strong);
  white-space: nowrap;
}
.mini-table tfoot th {
  border-top: 1px solid var(--border-strong);
  border-bottom: none;
  font-weight: var(--weight-semibold);
}
.mini-table tbody tr:last-child td { border-bottom: none; }
.mini-table .ta-right { text-align: right; }
.mini-table .tabular,
.mini-table td.ta-right,
.mini-table th.ta-right { font-variant-numeric: tabular-nums lining-nums; }
.mini-table-scroll { overflow-x: auto; max-width: 100%; }

/* A row the reader must not skim past — a rejected import row, a bounced
   cheque. Tinted rather than merely coloured, because colour alone fails
   for the ~8% of men with a colour-vision deficiency. */
.mini-table tr.row-bad td { background: var(--danger-soft); }
.mini-table tr.row-warn td { background: var(--warning-soft); }

/* ── Small text utilities ────────────────────────────────────── */
.text-danger { color: var(--danger-ink); }
.text-warning { color: var(--warning-ink); }
.text-success { color: var(--success-ink); }
.ta-right { text-align: right; }
.tabular { font-variant-numeric: tabular-nums lining-nums; }
.mt-2 { margin-top: var(--space-2); }
.mt-3 { margin-top: var(--space-3); }
.mt-4 { margin-top: var(--space-4); }
.mb-3 { margin-bottom: var(--space-3); }

/* ── Occupancy meter ─────────────────────────────────────────────
   Used on the daycare slabs. Shows utilisation as a bar because "11 of 10"
   is easy to read past, whereas a bar that has visibly overrun is not. */
.meter {
  height: 6px;
  border-radius: var(--radius-full);
  background: var(--surface-sunken);
  overflow: hidden;
  margin-top: var(--space-1);
}
.meter-fill { height: 100%; background: var(--accent); transition: width 0.3s ease; }
.meter-fill.is-full { background: var(--warning-ink); }
.meter-fill.is-over { background: var(--danger-ink); }

/* ==========================================================================
   EMAIL COMPOSER
   Opened from a record page. The chip row is the part that earns its keep:
   it offers only fields that actually have a value on this record, so a
   counsellor cannot insert {{visit_date}} into a letter to a family with no
   visit booked and mail them a blank line.
   ========================================================================== */
.compose .form-grid { gap: var(--space-3); }
/* .input fixes a single-line height for every control; a composer textarea
   has to override it or the message box is one line tall and the counsellor
   writes the whole email through a letterbox. */
.compose textarea.input {
  height: auto; min-height: 15rem; padding: var(--space-3);
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: var(--text-sm); line-height: 1.6; resize: vertical;
}
.compose-fields { margin-top: var(--space-4); }
.compose-fields > summary {
  cursor: pointer; font-size: var(--text-xs); font-weight: var(--weight-semibold);
  text-transform: uppercase; letter-spacing: var(--tracking-wide);
  color: var(--text-muted); padding: var(--space-2) 0;
}
.compose-chips { display: flex; flex-wrap: wrap; gap: var(--space-2); padding-top: var(--space-2); }
.compose-chips .chip {
  border: 1px solid var(--border-subtle); background: var(--surface-elevated);
  color: var(--text-secondary); border-radius: var(--radius-full);
  padding: 4px 10px; font-size: var(--text-xs); cursor: pointer;
  transition: border-color var(--dur-2) var(--ease-out), color var(--dur-2) var(--ease-out);
}
.compose-chips .chip:hover { border-color: var(--border-strong); color: var(--text-primary); }

/* ==========================================================================
   EMAIL LOG
   The funnel bars are deliberately plain: they exist to make the drop between
   two adjacent numbers visible at a glance, not to be a chart. The row-level
   outcome badge carries the colour, because that is the thing a person scans
   the table for.
   ========================================================================== */
.elog-funnel { display: grid; gap: var(--space-3); }
.elog-step-head { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-3); }
.elog-step-label { font-size: var(--text-xs); font-weight: var(--weight-semibold); text-transform: uppercase; letter-spacing: var(--tracking-wide); color: var(--text-muted); }
.elog-step-value { font-family: var(--font-display); font-size: var(--text-lg); font-weight: var(--weight-semibold); color: var(--text-primary); }
.elog-step-value .text-faint { font-size: var(--text-xs); font-weight: var(--weight-normal); }
.elog-bar { height: 6px; border-radius: var(--radius-full); background: var(--surface-sunken, rgba(127,127,127,.14)); overflow: hidden; margin-top: 4px; }
.elog-bar > span { display: block; height: 100%; border-radius: inherit; background: var(--accent, #6366F1); transition: width var(--dur-3) var(--ease-out); }

.elog-table tbody tr { cursor: pointer; }
.elog-table tbody tr:hover { background: var(--surface-hover, rgba(127,127,127,.06)); }
.elog-table tbody tr:focus-visible { outline: 2px solid var(--accent, #6366F1); outline-offset: -2px; }

.elog-detail-head { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-4); }
.elog-timeline { list-style: none; margin: 0 0 var(--space-5); padding: 0; border-left: 2px solid var(--border-subtle); }
.elog-timeline li { position: relative; padding: var(--space-2) 0 var(--space-2) var(--space-4); font-size: var(--text-sm); }
.elog-timeline li::before { content: ''; position: absolute; left: -5px; top: 14px; width: 8px; height: 8px; border-radius: 50%; background: var(--accent, #6366F1); }
.elog-time { display: inline-block; min-width: 148px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.elog-what { font-weight: var(--weight-medium); }
.elog-src { margin-left: var(--space-2); font-size: var(--text-xs); }
.elog-url { margin-left: 148px; font-size: var(--text-xs); color: var(--text-muted); }

.elog-reply { border: 1px solid var(--border-subtle); border-radius: var(--radius-lg); padding: var(--space-4); margin-bottom: var(--space-5); background: var(--surface-elevated); }
.elog-reply-head { display: flex; justify-content: space-between; gap: var(--space-3); font-size: var(--text-sm); }
.elog-reply-subject { margin: var(--space-2) 0; font-weight: var(--weight-medium); }
.elog-reply-body, .elog-body { white-space: pre-wrap; word-break: break-word; font-size: var(--text-sm); line-height: 1.6; color: var(--text-secondary); background: var(--surface-sunken, rgba(127,127,127,.06)); border-radius: var(--radius-md); padding: var(--space-3); margin: 0; max-height: 420px; overflow: auto; }

/* Template parameter inputs in the composer. WhatsApp only: Meta renders its
   own approved wording, so the counsellor edits values, not prose. */
.compose-params { margin-top: var(--space-4); padding: var(--space-4); border: 1px solid var(--border-subtle); border-radius: var(--radius-lg); background: var(--surface-elevated); }
.compose-params-head { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-xs); font-weight: var(--weight-semibold); text-transform: uppercase; letter-spacing: var(--tracking-wide); color: var(--text-muted); margin-bottom: var(--space-2); }
.compose-params .field { margin-top: var(--space-2); }
.compose textarea.input[readonly] { opacity: .75; cursor: default; }

/* Backup: the two routes to the sheet, side by side. The active one is
   marked rather than the other hidden — a half-finished setup has to stay
   visible or somebody configures the wrong half twice. */
.bk-route { border: 1px solid var(--border-subtle); border-radius: var(--radius-lg); padding: var(--space-4); margin-bottom: var(--space-4); }
.bk-route.is-active { border-color: var(--accent, #6366F1); background: var(--surface-elevated); }
.bk-route-head { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-2); }
.bk-route .kv { margin-top: var(--space-3); }

/* A value the user has to read out or copy — a one-time password, a phone
   number being dictated down a line. Big, monospaced, selectable in one go. */
.copy-field {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-4);
  padding: var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius);
  background: var(--surface-sunken);
}
.copy-field-value {
  flex: 1;
  font-family: var(--font-mono);
  font-size: var(--text-lg);
  letter-spacing: .06em;
  word-break: break-all;
  user-select: all;
}

/* ── Inbox ───────────────────────────────────────────────────────────
   Three columns: folders, conversation list, open conversation. The list
   and pane scroll independently so moving down a long list never scrolls
   the message you are reading out of view. */
.mb-shell {
  display: grid;
  grid-template-columns: 208px minmax(300px, 400px) 1fr;
  gap: var(--space-4);
  align-items: start;
  /* Fill the viewport below the header, so each column scrolls itself
     rather than the whole page growing to the length of the longest one. */
  height: calc(100vh - 190px);
  min-height: 420px;
}
/* Tablet: keep the rail, drop the reading pane below the list. */
@media (max-width: 1100px) {
  .mb-shell { grid-template-columns: 190px 1fr; height: auto; }
  .mb-pane { grid-column: 1 / -1; }
}
.mb-rail { display: flex; flex-direction: column; gap: 2px; }
.mb-search { position: relative; margin-bottom: var(--space-3); }
.mb-search svg {
  position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
  width: 15px; height: 15px; color: var(--text-muted); pointer-events: none;
}
.mb-search .input { padding-left: 32px; }
.mb-folder {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-2); width: 100%;
  padding: var(--space-2) var(--space-3);
  border: 0; border-radius: var(--radius);
  background: transparent; color: var(--text);
  font: inherit; text-align: left; cursor: pointer;
}
.mb-folder:hover { background: var(--surface-hover); }
.mb-folder.is-active { background: var(--surface-selected); font-weight: 600; }
.mb-folder-count { color: var(--text-muted); font-size: var(--text-xs); }
.mb-rail-sep {
  height: 1px; background: var(--border-subtle); margin: var(--space-3) 0;
}
.mb-chan { display: flex; flex-wrap: wrap; gap: 4px; }
.mb-chip {
  padding: 3px 10px; border: 1px solid var(--border-subtle);
  border-radius: 999px; background: transparent; color: var(--text-muted);
  font-size: var(--text-xs); cursor: pointer;
}
.mb-chip.is-active {
  background: var(--surface-selected); color: var(--text);
  border-color: var(--border-strong);
}

.mb-list { overflow-y: auto; padding: 0; }
.mb-row {
  display: flex; align-items: flex-start; gap: var(--space-2);
  padding: var(--space-3);
  border-bottom: 1px solid var(--border-subtle);
  cursor: pointer;
}
.mb-row:hover { background: var(--surface-hover); }
.mb-row.is-active { background: var(--surface-selected); }
/* Unread is carried by weight and a left edge, not colour alone — the
   distinction has to survive a monochrome screen and colour blindness. */
.mb-row.is-unread { box-shadow: inset 3px 0 0 var(--brand); }
.mb-row.is-unread .mb-who,
.mb-row.is-unread .mb-subject { font-weight: 700; }
.mb-row-main { flex: 1; min-width: 0; }
.mb-row-top {
  display: flex; align-items: baseline; gap: var(--space-2);
}
.mb-who { flex: 1 1 auto; min-width: 0; overflow: hidden;
          text-overflow: ellipsis; white-space: nowrap; }
.mb-count, .mb-when { flex: 0 0 auto; }
.mb-count {
  color: var(--text-muted); font-size: var(--text-xs);
  border: 1px solid var(--border-subtle); border-radius: 999px;
  padding: 0 6px;
}
.mb-when { color: var(--text-muted); font-size: var(--text-xs);
           white-space: nowrap; }
.mb-subject, .mb-snippet {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mb-subject { font-size: var(--text-sm); margin-top: 1px; }
.mb-snippet { color: var(--text-muted); font-size: var(--text-xs); }
.mb-row-side {
  display: flex; align-items: center; gap: 4px; color: var(--text-muted);
  /* Without this the icons are allowed to shrink to nothing and then
     overflow their box, drawing on top of the timestamp beside them. */
  flex: 0 0 auto;
}
.mb-row-side svg { width: 15px; height: 15px; }
.mb-star {
  border: 0; background: transparent; padding: 2px; cursor: pointer;
  color: var(--border-strong); line-height: 0;
  flex: 0 0 auto;
}
.mb-star svg { width: 16px; height: 16px; }
.mb-star.on { color: #F59E0B; }
.mb-star.on svg { fill: currentColor; }

.mb-pane { display: flex; flex-direction: column; overflow: hidden; }
.mb-thread-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--space-3); padding: var(--space-4);
  border-bottom: 1px solid var(--border-subtle);
}
.mb-thread-subject { font-size: var(--text-lg); margin: 0; }
.mb-thread-sub {
  color: var(--text-muted); font-size: var(--text-xs); margin-top: 2px;
}
.mb-thread-actions { display: flex; gap: 2px; }
.mb-pane-body { flex: 1; overflow-y: auto; padding: var(--space-4); }
.mb-msg { margin-bottom: var(--space-4); }
.mb-msg-head { display: flex; align-items: center; gap: var(--space-3); }
.mb-msg-who { min-width: 0; }
.mb-msg-meta {
  display: block; color: var(--text-muted); font-size: var(--text-xs);
}
.mb-msg-meta svg { width: 12px; height: 12px; vertical-align: -1px; }
.mb-msg-body {
  margin: var(--space-2) 0 0 44px; padding: var(--space-3);
  border-radius: var(--radius); background: var(--surface-sunken);
  font-size: var(--text-sm); white-space: pre-wrap; word-break: break-word;
}
/* Outbound leans on the brand tint, so a thread reads as a conversation at
   a glance rather than a uniform wall. */
.mb-msg.is-out .mb-msg-body { background: var(--surface-selected); }

.mb-reply {
  border-top: 1px solid var(--border-subtle); padding: var(--space-3);
}
.mb-reply-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-3); margin-top: var(--space-2);
}
.mb-reply-hint { color: var(--text-muted); font-size: var(--text-xs); }

/* Phone: one column.
   Two columns at 375px left the list about 180px wide, which turned every
   row into "ASPAM Sc…" and drew the channel icon on top of the timestamp.
   The rail becomes a horizontal strip of folders instead — the same
   information, along the axis that has room for it. */
@media (max-width: 760px) {
  .mb-shell { grid-template-columns: 1fr; height: auto; }
  .mb-rail {
    flex-direction: row; flex-wrap: wrap;
    gap: var(--space-2);
    padding-bottom: var(--space-2);
  }
  /* The search takes a full line of its own, so the folder chips WRAP onto
     the next one rather than being pushed off the right edge where nobody
     would find them. */
  .mb-search { order: -1; flex: 0 0 100%; margin-bottom: var(--space-2); }
  .mb-folder {
    width: auto; flex: 0 0 auto; white-space: nowrap;
    border: 1px solid var(--border-subtle); border-radius: 999px;
    padding: 4px 12px;
  }
  .mb-rail-sep { display: none; }
  .mb-chan { flex: 0 0 auto; flex-wrap: nowrap; }
  .mb-list { max-height: 60vh; }
}

/* Compose — the field stack inside the new-message dialog. */
.compose-grid { display: flex; flex-direction: column; gap: var(--space-3); }
.compose-grid .field { display: flex; flex-direction: column; gap: 4px; }
/* Cc and Bcc sit on one line as quiet links until they are wanted, the way
   every mail client hides them. Two empty fields at the top of a form make
   it look longer than it is. */
.compose-ccbcc {
  flex-direction: row !important; gap: var(--space-3);
  margin-top: calc(var(--space-2) * -1);
}
.btn-link {
  border: 0; background: transparent; padding: 0; cursor: pointer;
  color: var(--text-muted); font: inherit; font-size: var(--text-xs);
  text-decoration: underline; text-underline-offset: 2px;
}
.btn-link:hover { color: var(--text); }

/* Compose attachments — a quiet button and a list of what is riding along. */
.compose-attach {
  display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap;
}
.compose-files { list-style: none; margin: var(--space-2) 0 0; padding: 0; }
.compose-file {
  display: flex; align-items: center; gap: var(--space-2);
  padding: var(--space-2) var(--space-3); margin-top: 4px;
  border: 1px solid var(--border-subtle); border-radius: var(--radius);
  background: var(--surface-sunken); font-size: var(--text-sm);
}
.compose-file svg { width: 15px; height: 15px; color: var(--text-muted); }
.compose-file-name {
  flex: 1; min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap;
}
.compose-file-size {
  color: var(--text-muted); font-size: var(--text-xs); white-space: nowrap;
}

/* A merge field the current record has no value for. Still insertable — the
   field exists on the object — but it should be obvious it will come out
   blank for THIS family. */
.chip.is-empty { opacity: 0.55; border-style: dashed; }

/* ── Condition builder ───────────────────────────────────────────────
   Field / operator / value on one line, with the compiled formula shown
   underneath so what the server will actually evaluate is never hidden. */
.cond-builder { display: flex; flex-direction: column; gap: var(--space-2); }
.cond-match {
  display: flex; align-items: center; gap: var(--space-2);
  font-size: var(--text-sm); color: var(--text-muted);
}
.cond-match .input-sm { width: auto; padding: 2px 8px; }
.cond-rows { display: flex; flex-direction: column; gap: var(--space-2); }
.cond-row {
  display: grid;
  grid-template-columns: minmax(120px, 1.4fr) minmax(110px, 1fr) minmax(140px, 1.4fr) auto;
  gap: var(--space-2);
  /* start, not center: a multi-value box is taller than a select, and
     centring it drags the field and operator pickers down with it. */
  align-items: start;
}
.cond-row > select, .cond-row > .btn-icon { margin-top: 2px; }
@media (max-width: 700px) {
  .cond-row { grid-template-columns: 1fr 1fr; }
  .cond-row .btn-icon { grid-column: 2; justify-self: end; }
}
.cond-novalue {
  color: var(--text-muted); font-size: var(--text-xs); font-style: italic;
}
.cond-foot {
  display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap;
  margin-top: var(--space-1);
}
.cond-hint { color: var(--text-muted); font-size: var(--text-xs); }
/* The compiled formula. Shown, not hidden: somebody has to be able to check
   what the gate actually says, and it is what a support question will quote. */
.cond-preview {
  flex: 1; min-width: 0; overflow-x: auto; white-space: nowrap;
  font-family: var(--font-mono); font-size: var(--text-xs);
  color: var(--text-muted);
  padding: 2px 8px; border-radius: var(--radius);
  background: var(--surface-sunken);
}
.cond-raw {
  font-family: var(--font-mono); font-size: var(--text-xs); width: 100%;
}
.cond-warn {
  margin-top: var(--space-2); font-size: var(--text-xs);
  color: var(--warning, #F59E0B);
}

/* ── WhatsApp section ────────────────────────────────────────────── */
.wa-issues { list-style: none; margin: 0; padding: 0; }
.wa-issue {
  display: flex; align-items: flex-start; gap: var(--space-3);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--border-subtle);
  font-size: var(--text-sm);
}
.wa-issue:last-child { border-bottom: 0; }
.wa-issue svg { width: 17px; height: 17px; flex: 0 0 auto; margin-top: 1px;
                color: var(--text-muted); }
/* A blocker is the difference between "worth knowing" and "nothing is being
   delivered right now", so it does not share the muted treatment. */
.wa-issue.is-blocker svg { color: var(--danger, #DC2626); }
.wa-fix {
  margin-top: 2px; color: var(--text-muted); font-size: var(--text-xs);
}
.wa-queue { list-style: none; margin: 0; padding: 0; }
.wa-queue li {
  display: grid; grid-template-columns: minmax(120px, 1fr) 2fr auto;
  gap: var(--space-3); align-items: baseline;
  padding: var(--space-2) 0; border-bottom: 1px solid var(--border-subtle);
  font-size: var(--text-sm);
}
.wa-queue li:last-child { border-bottom: 0; }
@media (max-width: 700px) {
  .wa-queue li { grid-template-columns: 1fr; gap: 2px; }
}

/* ── WhatsApp chat ───────────────────────────────────────────────────
   A conversation view, not a table: list on the left, bubbles on the
   right, newest at the bottom — the shape everyone already knows. */
.wa-chat {
  display: grid; grid-template-columns: minmax(260px, 340px) 1fr;
  gap: var(--space-4); align-items: start;
  height: calc(100vh - 260px); min-height: 420px;
}
@media (max-width: 900px) {
  .wa-chat { grid-template-columns: 1fr; height: auto; }
  .wa-list { max-height: 40vh; }
  .wa-pane { min-height: 60vh; }
}
.wa-list { overflow-y: auto; padding: 0; }
.wa-conv {
  display: flex; align-items: center; gap: var(--space-3); width: 100%;
  padding: var(--space-3); border: 0; border-bottom: 1px solid var(--border-subtle);
  background: transparent; color: var(--text); font: inherit;
  text-align: left; cursor: pointer;
}
.wa-conv:hover { background: var(--surface-hover); }
.wa-conv.is-active { background: var(--surface-selected); }
.wa-conv-main { flex: 1; min-width: 0; }
.wa-conv-top { display: flex; justify-content: space-between; gap: var(--space-2); }
.wa-conv-who { font-weight: 600; overflow: hidden;
               text-overflow: ellipsis; white-space: nowrap; }
.wa-conv-when { color: var(--text-muted); font-size: var(--text-xs);
                white-space: nowrap; }
.wa-conv-snip {
  display: block; color: var(--text-muted); font-size: var(--text-xs);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.wa-conv-unread {
  background: var(--brand); color: #fff; border-radius: 999px;
  min-width: 20px; padding: 1px 6px; text-align: center;
  font-size: var(--text-xs); font-weight: 700;
}

.wa-pane { display: flex; flex-direction: column; overflow: hidden; }
.wa-head {
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-subtle);
}
.wa-head-who strong { display: block; }
.wa-head-who span { color: var(--text-muted); font-size: var(--text-xs); }
.wa-msgs {
  flex: 1; overflow-y: auto; padding: var(--space-4);
  display: flex; flex-direction: column; gap: 2px;
  background: var(--surface-sunken);
}
.wa-day { text-align: center; margin: var(--space-3) 0; }
.wa-day span {
  background: var(--surface-elevated); color: var(--text-muted);
  font-size: var(--text-xs); padding: 2px 10px; border-radius: 999px;
}
.wa-bubble-row { display: flex; }
.wa-bubble-row.is-out { justify-content: flex-end; }
.wa-bubble {
  max-width: min(78%, 560px);
  padding: var(--space-2) var(--space-3);
  border-radius: 10px 10px 10px 2px;
  background: var(--surface-elevated);
  border: 1px solid var(--border-subtle);
  margin-bottom: var(--space-2);
}
/* Outbound leans the other way and carries the brand tint — the visual cue
   that says "us" without needing a label on every message. */
.wa-bubble.is-out {
  border-radius: 10px 10px 2px 10px;
  background: var(--surface-selected);
}
.wa-bubble-text {
  font-size: var(--text-sm); white-space: pre-wrap; word-break: break-word;
}
.wa-bubble-meta {
  display: flex; align-items: center; justify-content: flex-end; gap: 4px;
  margin-top: 2px; color: var(--text-muted); font-size: 11px;
}
.wa-tick { letter-spacing: -2px; }
.wa-tick.is-read { color: #53BDEB; }          /* WhatsApp's own blue ticks */
.wa-tick.is-pending { letter-spacing: 0; }
.wa-tick.is-failed { color: var(--danger, #DC2626); letter-spacing: 0; }
.wa-tick.is-failed svg { width: 13px; height: 13px; vertical-align: -2px; }

.wa-compose {
  display: flex; align-items: flex-end; gap: var(--space-2);
  padding: var(--space-3); border-top: 1px solid var(--border-subtle);
}
.wa-compose textarea { flex: 1; resize: none; max-height: 120px; }
.wa-closed {
  display: flex; align-items: flex-start; gap: var(--space-3);
  font-size: var(--text-sm); color: var(--text-muted);
}
.wa-closed svg { width: 17px; height: 17px; flex: 0 0 auto; margin-top: 2px; }
.wa-closed strong { color: var(--text); }
.wa-closed-hint { margin-top: 2px; font-size: var(--text-xs); }

/* "is any of" — tick boxes, because a stage list is short and "hold ctrl to
   pick more than one" is a thing people get wrong. */
.cond-multi {
  display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-3);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border-subtle); border-radius: var(--radius);
  background: var(--surface-sunken);
  /* A stage list is eleven options and the value column is narrow, so the
     boxes stack into a tall column that pushes out of the row and overlaps
     the one above. Cap it and let it scroll. */
  max-height: 132px; overflow-y: auto;
}
.cond-multi-opt {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: var(--text-xs); white-space: nowrap; cursor: pointer;
}
.cond-warn-actions {
  display: flex; gap: var(--space-2); margin-top: var(--space-2);
  flex-wrap: wrap;
}

/* ── One child's document file (student detail → Documents) ──────────
   A checklist, not a table: the row for a certificate nobody has sent is
   the most important row on the screen, and a table of uploaded files
   cannot show a row for a file that does not exist. */
.doc-progress-card {
  border: 1px solid var(--border-subtle); border-radius: var(--radius-lg);
  background: var(--surface-raised); padding: var(--space-4) var(--space-5);
  margin-bottom: var(--space-5);
}
.doc-progress-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--space-4); flex-wrap: wrap;
}
.doc-progress-title { font-weight: 600; font-size: var(--text-md); }
.doc-progress-sub {
  color: var(--text-muted); font-size: var(--text-sm); margin-top: 2px;
}
.doc-progress-bar {
  height: 6px; border-radius: 999px; background: var(--surface-sunken);
  margin-top: var(--space-4); overflow: hidden;
}
.doc-progress-bar > span {
  display: block; height: 100%; border-radius: 999px;
  background: var(--success-fill); transition: width .3s ease;
}
.doc-note {
  display: flex; gap: var(--space-3); align-items: flex-start;
  padding: var(--space-3) var(--space-4); margin-bottom: var(--space-4);
  border: 1px solid var(--border-subtle); border-radius: var(--radius);
  background: var(--surface-sunken); color: var(--text-muted);
  font-size: var(--text-sm);
}
.doc-note svg { flex: none; margin-top: 2px; }

.doc-checklist {
  border: 1px solid var(--border-subtle); border-radius: var(--radius-lg);
  overflow: hidden; background: var(--surface-raised);
}
.doc-row {
  display: flex; align-items: center; gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-subtle);
}
.doc-row:last-child { border-bottom: 0; }
.doc-row-main { flex: 1 1 auto; min-width: 0; }
.doc-row-name {
  display: flex; align-items: center; gap: var(--space-2);
  font-weight: 500;
}
.doc-row-sub, .doc-row-remark {
  color: var(--text-muted); font-size: var(--text-xs); margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.doc-row-remark { color: var(--warning-ink); white-space: normal; }
.doc-row-status { flex: none; }
.doc-row-actions {
  flex: none; display: flex; align-items: center; gap: var(--space-2);
}
.req-pill, .opt-pill {
  font-size: 10px; letter-spacing: .04em; text-transform: uppercase;
  padding: 1px 6px; border-radius: 999px; font-weight: 600;
}
.req-pill { background: var(--danger-soft); color: var(--danger-ink); }
.opt-pill { background: var(--surface-sunken); color: var(--text-faint); }

/* Narrow screens: the status and buttons drop under the name rather than
   squeezing the document name down to three characters. */
@media (max-width: 720px) {
  .doc-row { flex-wrap: wrap; }
  .doc-row-main { flex: 1 1 100%; }
  .doc-row-actions { margin-left: auto; }
}

/* ── "It never left" — failed sends, on the dashboard ────────────────
   Deliberately loud and at the top: this is the one event in the CRM whose
   reader would otherwise never arrive. */
.delivery-alert {
  border: 1px solid var(--danger-border, var(--border-subtle));
  border-radius: var(--radius-lg); background: var(--danger-soft);
  padding: var(--space-4) var(--space-5); margin-bottom: var(--space-5);
}
.delivery-alert.is-held {
  background: var(--surface-sunken); border-color: var(--border-subtle);
}
.delivery-alert-head {
  display: flex; align-items: flex-start; gap: var(--space-3);
}
.delivery-alert-head > svg { flex: none; margin-top: 2px; color: var(--danger-ink); }
.delivery-alert.is-held .delivery-alert-head > svg { color: var(--text-muted); }
.delivery-alert-head > div { flex: 1 1 auto; min-width: 0; }
.delivery-alert-head > a { flex: none; }
.delivery-alert-title { font-weight: 600; color: var(--danger-ink); }
.delivery-alert.is-held .delivery-alert-title { color: var(--text-strong, inherit); }
.delivery-alert-sub {
  color: var(--text-muted); font-size: var(--text-sm); margin-top: 2px;
}
.delivery-alert-list {
  list-style: none; margin: var(--space-4) 0 0; padding: 0;
  border-top: 1px solid var(--danger-border, var(--border-subtle));
}
.delivery-alert-list li {
  display: flex; align-items: baseline; gap: var(--space-3);
  padding: var(--space-2) 0; font-size: var(--text-sm);
  border-bottom: 1px dashed var(--border-subtle);
}
.delivery-alert-list li:last-child { border-bottom: 0; }
.delivery-alert-chan {
  flex: none; font-size: 10px; letter-spacing: .04em; font-weight: 600;
  color: var(--text-faint); min-width: 62px;
}
/* The reason is the point of the row, so it is what gets the space — and it
   wraps rather than being cut off at "SMTP connec…". */
.delivery-alert-reason {
  flex: 1 1 auto; min-width: 0; color: var(--text-muted);
}
.delivery-alert-when { flex: none; color: var(--text-faint); font-size: var(--text-xs); }
@media (max-width: 720px) {
  .delivery-alert-list li { flex-wrap: wrap; }
  .delivery-alert-reason { flex: 1 1 100%; }
}

/* A failed send on a timeline. Same row, unmistakably not the same event. */
.timeline-item.is-failed .timeline-dot {
  background: var(--danger-soft); color: var(--danger-ink);
  border-color: var(--danger-border);
}
.timeline-item.is-failed .timeline-title { color: var(--danger-ink); }

/* Why a campaign's messages did not go out, under its delivery tiles. */
.campaign-failures {
  margin-top: var(--space-4); padding: var(--space-4);
  border: 1px solid var(--danger-border); border-radius: var(--radius);
  background: var(--danger-soft);
}
.campaign-failures-title {
  display: flex; align-items: center; gap: var(--space-2);
  font-weight: 600; color: var(--danger-ink); margin-bottom: var(--space-3);
}
.campaign-failures ul { list-style: none; margin: 0; padding: 0; }
.campaign-failures li {
  display: flex; align-items: baseline; gap: var(--space-3);
  padding: var(--space-1) 0; font-size: var(--text-sm);
}
.campaign-failures-n {
  flex: none; min-width: 2.5em; text-align: right; font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.campaign-failures-reason { flex: 1 1 auto; min-width: 0; }
.campaign-failures-eg { flex: none; color: var(--text-faint); font-size: var(--text-xs); }
@media (max-width: 720px) {
  .campaign-failures li { flex-wrap: wrap; }
  .campaign-failures-reason { flex: 1 1 100%; }
}

/* ── Campaign audience builder ───────────────────────────────────────
   The filter rows and the preview reuse the segment builder's styles; what
   is new here is the reachability warning and the merge-field list, both of
   which exist to answer a question before the send rather than after it. */
.filter-preview-warn {
  display: inline-flex; align-items: center; gap: 4px;
  margin-left: var(--space-3); color: var(--warning-ink);
  font-size: var(--text-sm);
}
.filter-preview-warn svg { width: 14px; height: 14px; }

.checkbox-row {
  display: flex; align-items: center; gap: var(--space-2);
  font-size: var(--text-sm); cursor: pointer;
}

.merge-available {
  margin-top: var(--space-4); padding: var(--space-4);
  border: 1px solid var(--border-subtle); border-radius: var(--radius);
  background: var(--surface-sunken);
}
.merge-available-head {
  display: flex; align-items: center; gap: var(--space-2);
  font-weight: 600; font-size: var(--text-sm); margin-bottom: var(--space-3);
}
.merge-available-chips {
  display: flex; flex-wrap: wrap; gap: 6px;
  /* Sixty field names is a wall of text at full height; cap it and let the
     reader scroll rather than pushing the Save button off the panel. */
  max-height: 148px; overflow-y: auto;
}
.merge-chip {
  font-size: var(--text-xs); padding: 2px 7px; border-radius: var(--radius-sm);
  background: var(--surface-raised); border: 1px solid var(--border-subtle);
  color: var(--text-muted); white-space: nowrap;
}
.merge-available-foot {
  margin-top: var(--space-3); font-size: var(--text-xs); color: var(--text-faint);
}

/* A documented merge field means the same thing on every object, so it is
   worth telling apart from the eighty columns that follow it. */
.chip-action.is-core { border-color: var(--accent-border, var(--border-strong)); }

.segment-sample ul li {
  display: flex; justify-content: space-between; gap: var(--space-3);
}

/* ── Bulk email from a selection ─────────────────────────────────────
   The count is the most important thing on the panel: it is the number the
   operator is agreeing to, and it must not be findable only by counting. */
.bulk-count {
  display: flex; align-items: baseline; gap: var(--space-2);
  padding: var(--space-3) var(--space-4); border-radius: var(--radius);
  background: var(--surface-sunken); border: 1px solid var(--border-subtle);
  font-size: var(--text-sm);
}
.bulk-count strong { font-size: var(--text-lg); }
.bulk-count-warn { margin-left: auto; color: var(--warning-ink); }
.bulk-sample-subject {
  font-weight: 600; padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--border-subtle); margin-bottom: var(--space-3);
}
.bulk-sample-body {
  white-space: pre-wrap; word-break: break-word; margin: 0;
  font-family: inherit; font-size: var(--text-sm); color: var(--text-muted);
  max-height: 260px; overflow-y: auto;
}

/* ── Notification bell ───────────────────────────────────────────────
   The count has to be legible at a glance without shouting: a badge that
   is always red trains people to stop seeing it, so only genuine failures
   get the danger colour. */
.notif-bell { position: relative; }
.notif-badge {
  position: absolute; top: 2px; right: 2px; min-width: 16px; height: 16px;
  padding: 0 4px; border-radius: 999px; font-size: 10px; font-weight: 700;
  line-height: 16px; text-align: center;
  background: var(--warning-fill); color: #1a1205;
  border: 2px solid var(--surface);
}
.notif-badge.is-error { background: var(--danger-ink); color: #fff; }

.notif-list { list-style: none; margin: 0; padding: 0; max-height: 55vh; overflow-y: auto; }
.notif-item {
  display: flex; gap: var(--space-3); align-items: flex-start;
  padding: var(--space-3) 0; border-bottom: 1px solid var(--border-subtle);
}
.notif-item:last-child { border-bottom: 0; }
.notif-item::before {
  content: ''; flex: none; width: 6px; height: 6px; border-radius: 50%;
  margin-top: 7px; background: var(--warning-fill);
}
.notif-item.is-error::before { background: var(--danger-ink); }
.notif-main { flex: 1 1 auto; min-width: 0; }
.notif-title {
  display: block; font-weight: 600; color: inherit; text-decoration: none;
}
.notif-title:hover { text-decoration: underline; }
.notif-detail {
  color: var(--text-muted); font-size: var(--text-sm); margin-top: 2px;
  overflow-wrap: anywhere;
}
.notif-when { color: var(--text-faint); font-size: var(--text-xs); margin-top: 3px; }
.notif-dismiss { flex: none; opacity: .55; }
.notif-dismiss:hover { opacity: 1; }
.notif-empty { text-align: center; padding: var(--space-6) 0; color: var(--text-muted); }
.notif-empty svg { width: 32px; height: 32px; opacity: .5; }

/* ── Which school am I in ────────────────────────────────────────────
   On a multi-branch install this is the most important label on screen:
   two schools' records look identical, and only this says whose. */
.branch-chip {
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: 5px var(--space-3); border-radius: var(--radius);
  border: 1px solid var(--border-subtle); background: var(--surface-sunken);
  color: var(--text-primary); font-size: var(--text-sm); font-weight: 500;
  max-width: 320px; cursor: default;
}
.branch-chip svg { width: 15px; height: 15px; flex: none; opacity: .75; }
.branch-chip-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* A group administrator can change it, so it must look changeable. */
.branch-chip.is-super {
  cursor: pointer; border-color: var(--accent-border, var(--border-strong));
}
.branch-chip.is-super:hover { background: var(--surface-hover); }
.branch-chip-caret { display: inline-flex; opacity: .6; }
.branch-chip-caret svg { width: 13px; height: 13px; }

/* The group account is not a branch account, and should not read like one. */
.user-role.is-super {
  color: var(--accent-ink, var(--brand-ink, inherit));
  font-weight: 600; letter-spacing: .01em;
}

/* ── A wide logo is a wordmark, not a crest ──────────────────────────
   The 32px square suits a round badge. ASPAM's logos are 170x65, and
   squeezing one into that slot renders it about 32x12 — loaded, present,
   and unreadable. A wordmark takes the whole row and replaces the text
   name, which it already contains. */
/* Stacked, not side by side: a 170px-wide wordmark and a text column cannot
   share a 155px sidebar, and squeezing them left the subtitle overlapping
   the artwork. The logo takes the row; the product name sits beneath it. */
.sidebar-brand.is-wordmark {
  flex-direction: column; align-items: flex-start; gap: var(--space-2);
}
.sidebar-brand.is-wordmark .sidebar-logo {
  width: auto; height: auto; max-width: 100%; border-radius: 0;
  background: transparent; padding: 0;
}
.sidebar-brand.is-wordmark .sidebar-logo img {
  width: auto; height: auto;
  max-width: 100%; max-height: 40px; object-fit: contain;
  display: block;
}
.sidebar-brand.is-wordmark .sidebar-logo { max-width: 100%; }
/* The image carries the school's name; showing it twice reads as a mistake.
   The subtitle stays — it says which product this is, not which school. */
.sidebar-brand.is-wordmark .sidebar-brand-name { display: none; }
.sidebar-brand.is-wordmark .sidebar-brand-text { min-width: 0; }

/* Logos sit on the sidebar itself — no plate, no box.
   The artwork's own transparency is respected exactly as supplied. */
}

/* ── The email send switch ───────────────────────────────────────────
   Three exclusive states, laid out as rows rather than a select: an
   administrator reaching for this is usually in a hurry, and the
   consequence of each choice has to be readable without opening a menu. */
.send-modes { display: flex; flex-direction: column; gap: var(--space-2); }
.send-mode {
  display: flex; align-items: flex-start; gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border-subtle); border-radius: var(--radius);
  background: var(--surface-sunken); cursor: pointer;
}
.send-mode:hover { background: var(--surface-hover); }
.send-mode.is-on {
  border-color: var(--brand); background: var(--surface-selected);
}
.send-mode input { margin-top: 3px; flex: none; }
.send-mode-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.send-mode-label { font-weight: 600; }
.send-mode-hint { color: var(--text-muted); font-size: var(--text-sm); }


/* ── WhatsApp template preview ─────────────────────────────────────
   What the family will actually see, while it is being written. A template
   is reviewed by Meta and cannot be edited afterwards — only deleted and
   resubmitted — so seeing it before submitting is worth the space.

   Scoped under .wa-preview: it reuses .wa-bubble so it looks like the chat
   it will appear in, without touching the chat's own layout. */
.wa-preview { background: var(--surface-sunken); border-radius: var(--radius-lg);
              padding: var(--space-4); }
.wa-preview .wa-bubble { max-width: 32rem; padding: var(--space-3) var(--space-4); }
.wa-preview .wa-bubble-head { font-weight: 600; margin-bottom: var(--space-2); }
.wa-preview .wa-bubble-body { white-space: pre-wrap; line-height: 1.5; }
.wa-preview .wa-bubble-foot { color: var(--text-muted);
                              font-size: var(--text-xs);
                              margin-top: var(--space-2); }
.wa-preview .wa-bubble-btn { background: var(--surface-raised);
                             border-radius: var(--radius-md);
                             margin-top: var(--space-2); padding: var(--space-2);
                             text-align: center; color: var(--info-ink);
                             font-weight: 500; max-width: 32rem;
                             box-shadow: var(--shadow-xs); }


/* ── WhatsApp template composer ────────────────────────────────────
   One row per button. Fields appear according to the button type, because
   a link needs an address and a quick reply needs nothing but a label. */
.tc-btn-row { display: grid; gap: var(--space-2);
              grid-template-columns: 1fr; padding: var(--space-3);
              border: 1px solid var(--border); border-radius: var(--radius-md);
              margin-bottom: var(--space-2); background: var(--surface-sunken); }
.tc-btn-row .btn { justify-self: start; }
.wa-preview .wa-bubble-media { background: var(--surface-sunken);
                               border-radius: var(--radius-sm);
                               padding: var(--space-4); text-align: center;
                               color: var(--text-muted);
                               font-size: var(--text-xs);
                               margin-bottom: var(--space-2); }
