/* ============================================================
   EveryChat — components.css
   ------------------------------------------------------------
   Reusable UI components. Page-specific patterns and layout
   wrappers (app shell, sidebars-as-layout, page chrome) live
   in layout.css.

   All values reference tokens from tokens.css. Any value that
   should be a token but isn't yet is listed in the
   "Missing tokens" block at the bottom of this file.

   Token-mapping notes (decisions doc names → tokens.css names):
     --color-accent          → --color-blue
     --color-accent-dark     → --color-blue-dark
     --color-accent-bg       → --color-blue-glow
     --color-fg1 / fg2 / fg3 → --color-text / -secondary / -dim
     --color-backdrop        → --color-overlay-modal
     --radius-md             → --radius-sm (8px)
     --font-size-xs/sm/md/lg → --font-size-caption / small / body / body-lg
     --transition-fast/base  → --duration-fast / --duration-base
     --focus-ring (boxshadow)→ 0 0 0 3px var(--color-focus-ring)

   Cross-cutting rules:
     - BEM: .block, .block__element, .block--modifier
     - State classes use the is- prefix (.is-active, .is-loading…)
     - Modifiers compose: color × shape × size are independent
     - .composer__send / .email-composer__send provide positioning
       only; visual treatment comes from .btn modifiers
   ============================================================ */


/* ===========================================================
   1. BUTTONS — .btn
   Visual reference: Profile Settings pages
   =========================================================== */

.btn {
  /* Base — shared by every variant. Color/size modifiers layer on. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-4); /* 8px */
  padding: 9px var(--space-8); /* 9px / 16px — Profile Settings rhythm */
  height: 36px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm); /* 8px */
  background: transparent;
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--font-size-small); /* 13px — ps-btn baseline */
  font-weight: var(--font-weight-semibold);
  line-height: 1;
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  user-select: none;
  transition:
    background-color var(--duration-base) var(--easing-default),
    border-color var(--duration-base) var(--easing-default),
    color var(--duration-base) var(--easing-default),
    box-shadow var(--duration-base) var(--easing-default),
    transform var(--duration-base) var(--easing-default);
}
.btn:hover {
  color: white; /* block a:hover { color } from base.css overriding btn variant colors */
}

.btn:focus { outline: 0; }
.btn:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}

.btn:disabled,
.btn.is-disabled {
  opacity: 0.5;
  cursor: not-allowed;
  box-shadow: none;
  transform: none;
  pointer-events: none;
}

/* Icons inside buttons inherit currentColor */
.btn > svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  color: currentColor;
}

/* ----- Color variants ----- */

/* Primary — solid blue, the dominant CTA */
.btn--primary {
  background: var(--color-blue);
  color: var(--color-text-on-action);
  border-color: var(--color-blue);
  box-shadow: var(--shadow-button-action-rest);
}
.btn--primary:hover {
  background: var(--color-blue-dark);
  border-color: var(--color-blue-dark);
  box-shadow: var(--shadow-button-action-hover);
  transform: translateY(-1px);
}
.btn--primary:active {
  transform: translateY(0);
  box-shadow: var(--shadow-button-action-active);
}
.btn--primary:focus-visible {
  box-shadow: var(--shadow-button-action-rest), 0 0 0 3px var(--color-focus-ring);
}

/* Secondary — white background, neutral border, dark text */
.btn--secondary {
  background: var(--color-bg);
  color: var(--color-text);
  border-color: var(--color-border);
}
.btn--secondary:hover {
  background: var(--color-bg-off);
  border-color: var(--color-blue);
  color: var(--color-blue);
}
.btn--secondary:hover > svg { color: inherit; }
.btn--secondary:active {
  background: var(--color-bg-hover);
}

/* Ghost — transparent, secondary text color, hover bg */
.btn--ghost {
  background: transparent;
  color: var(--color-text-secondary);
  border-color: transparent;
}
.btn--ghost:hover {
  background: var(--color-bg-off);
  color: var(--color-text);
}
.btn--ghost:active {
  background: var(--color-bg-hover);
}

/* Danger — solid red, destructive confirms */
.btn--danger {
  background: var(--color-red);
  color: var(--color-text-on-action);
  border-color: var(--color-red);
  box-shadow: var(--shadow-button-danger-rest);
}
.btn--danger:hover {
  background: var(--color-red-dark);
  border-color: var(--color-red-dark);
  box-shadow: var(--shadow-button-danger-hover);
  transform: translateY(-1px);
}
.btn--danger:active {
  transform: translateY(0);
  box-shadow: var(--shadow-button-danger-active);
}
.btn--danger:focus-visible {
  box-shadow: var(--shadow-button-danger-rest), 0 0 0 3px var(--color-focus-ring-danger);
}

/* Danger ghost — transparent, no border, red text. Inline destructive. */
.btn--danger-ghost {
  background: transparent;
  color: var(--color-red);
  border-color: transparent;
}
.btn--danger-ghost:hover {
  background: var(--color-red-glow);
  color: var(--color-red);
}
.btn--danger-ghost:active {
  background: var(--color-red-pale);
}
.btn--danger-ghost:focus-visible {
  box-shadow: 0 0 0 3px var(--color-focus-ring-danger);
}

/* Blue ghost — transparent, no border, blue text. Inline primary action. */
.btn--blue-ghost {
  background: transparent;
  color: var(--color-blue);
  border-color: transparent;
}
.btn--blue-ghost:hover {
  background: var(--color-blue-glow);
  color: var(--color-blue);
}
.btn--blue-ghost:active {
  background: var(--color-blue-glow);
}
.btn--blue-ghost:focus-visible {
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}

/* ----- Shape variants ----- */

/* Icon — square, icon-only */
.btn--icon {
  width: 36px;
  padding: 0;
  gap: 0;
}
.btn--icon > svg {
  width: 18px;
  height: 18px;
}

/* Block — full-width */
.btn--block {
  width: 100%;
  display: flex;
}

/* ----- Size variants (compose with color and shape) ----- */

.btn--sm {
  height: 30px;
  padding: 6px var(--space-6); /* 6px / 12px */
  font-size: var(--font-size-caption); /* 12px */
  gap: var(--space-3); /* 6px */
}
.btn--sm.btn--icon {
  width: 30px;
  padding: 0;
}
.btn--sm > svg {
  width: 14px;
  height: 14px;
}

.btn--lg {
  height: 44px;
  padding: 12px var(--space-10); /* 12px / 24px */
  font-size: var(--font-size-body); /* 14px */
  gap: var(--space-4); /* 8px */
}
.btn--lg.btn--icon {
  width: 44px;
  padding: 0;
}
.btn--lg > svg {
  width: 20px;
  height: 20px;
}

/* ----- Surface modifier: --on-rail ----- */
/* Re-skins .btn--secondary and .btn--ghost for dark-rail
   surfaces (Form Builder sidebar, similar contexts). Color
   variants like --primary / --danger don't need this — their
   solid fills already work on any surface. */
.btn--on-rail.btn--secondary {
  background: transparent;
  border-color: var(--color-rail-border);
  color: var(--color-rail-fg);
}
.btn--on-rail.btn--secondary:hover {
  background: var(--color-rail-bg-hover);
  border-color: var(--color-rail-border-hover);
  color: var(--color-text-on-action);
}
.btn--on-rail.btn--secondary:hover > svg { color: var(--color-text-on-action); }
.btn--on-rail.btn--secondary:active {
  background: var(--color-rail-bg-hover);
}

.btn--on-rail.btn--ghost {
  background: transparent;
  color: var(--color-rail-fg);
  border-color: transparent;
}
.btn--on-rail.btn--ghost:hover {
  background: var(--color-rail-bg-hover);
  color: var(--color-text-on-action);
}
.btn--on-rail.btn--ghost:active {
  background: var(--color-rail-bg-hover);
}

/* Danger-ghost on rail: keep red text (it carries on dark),
   tint the hover background to a translucent red rather than
   the bright red-glow which clashes with the rail surface. */
.btn--on-rail.btn--danger-ghost:hover {
  background: rgba(239, 68, 68, 0.12);
}

/* ----- Loading state ----- */
/* Replaces the button label with a spinner; preserves footprint. */
.btn.is-loading {
  position: relative;
  color: transparent !important;
  pointer-events: none;
}
.btn.is-loading > * { visibility: hidden; }
.btn.is-loading::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 16px;
  height: 16px;
  margin: -8px 0 0 -8px;
  border-radius: 50%;
  border: 2px solid currentColor;
  border-top-color: transparent;
  opacity: 0.9;
  animation: ec-spin 0.8s linear infinite;
  /* Bring the spinner color back even though the label is transparent */
  color: var(--color-text-on-action);
}
.btn--secondary.is-loading::after,
.btn--ghost.is-loading::after,
.btn--danger-ghost.is-loading::after {
  color: var(--color-text-secondary);
}


/* ===========================================================
   2. MODAL — .modal
   Visual reference: Profile Settings destructive-confirm modals
   for default; thread-attached note dialogs for .modal--note
   =========================================================== */

.modal__backdrop {
  position: fixed;
  inset: 0;
  background: var(--color-overlay-modal);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  z-index: var(--z-modal);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-9); /* 20px */
}

.modal {
  position: relative;
  background: var(--color-bg);
  border-radius: var(--radius-lg); /* 16px */
  box-shadow: var(--shadow-xl);
  width: 100%;
  max-width: 520px;
  max-height: 90vh;
  overflow: auto;
  z-index: calc(var(--z-modal) + 1);
  display: flex;
  flex-direction: column;
}

.modal__head {
  position: relative;
  padding: var(--space-10) var(--space-12) var(--space-3); /* 24 32 6 */
}

.modal__title {
  font-family: var(--font-display);
  font-size: var(--font-size-h3); /* 22px */
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-h3);
  letter-spacing: var(--letter-spacing-h3);
  color: var(--color-text);
  margin: 0;
}

.modal__head p {
  margin-top: var(--space-3);
}

.modal__meta {
  margin-top: var(--space-2); /* 4px */
  font-family: var(--font-body);
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-small);
  color: var(--color-text-secondary);
}

.modal__close {
  position: absolute;
  top: var(--space-8); /* 16px */
  right: var(--space-8);
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
  color: var(--color-text-dim);
  cursor: pointer;
  transition:
    background-color var(--duration-base) var(--easing-default),
    color var(--duration-base) var(--easing-default);
}
.modal__close:hover {
  background: var(--color-bg-hover);
  color: var(--color-text);
}
.modal__close:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}
.modal__close > svg { width: 18px; height: 18px; }

.modal__body {
  padding: var(--space-7) var(--space-12) var(--space-4); /* 14 32 8 */
  font-family: var(--font-body);
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-text);
}
/* When body follows head directly with no extra body intro, give it some air */
.modal__head + .modal__body { padding-top: var(--space-6); }

.modal__foot {
  padding: var(--space-8) var(--space-12) var(--space-10); /* 16 32 24 */
  display: flex;
  gap: var(--space-5); /* 10px */
  justify-content: flex-end;
  align-items: center;
}

/* ----- Size modifiers ----- */
.modal--sm  { max-width: 420px; }
.modal--lg  { max-width: 720px; }
.modal--full {
  max-width: none;
  width: calc(100vw - 48px);
  height: calc(100vh - 48px);
  max-height: calc(100vh - 48px);
}

/* ----- Alert modifier: headless/footless dialog (empty-state content) ----- */
.modal--alert .modal__body {
  padding: var(--space-14) var(--space-12); /* 40 32 — generous vertical room without head/foot */
}

/* ----- Drawer modifier: slide in from right edge -----
   General slide-in panel. For filter UIs specifically, use
   .filter-drawer (Component #5). */
.modal--drawer {
  margin-left: auto;
  margin-right: 0;
  max-width: 480px;
  width: 100%;
  height: 100vh;
  max-height: 100vh;
  border-radius: var(--radius-lg) 0 0 var(--radius-lg);
  align-self: stretch;
  transform: translateX(100%);
  transition: transform 0.3s ease;
}
.modal__backdrop:has(.modal--drawer) {
  align-items: stretch;
  justify-content: flex-end;
  padding: 0;
}
.modal__backdrop.open .modal--drawer {
  transform: translateX(0);
}

/* ----- Note variant: cream surface for thread-attached notes ----- */
.modal--note {
  background: var(--gradient-note-surface);
  border: 1px solid var(--color-cream-border);
  color: var(--color-cream-text);
}
.modal--note .modal__title {
  color: var(--color-cream-text-strong);
}
.modal--note .modal__meta {
  color: var(--color-cream-text-dim);
}
.modal--note .modal__body {
  color: var(--color-cream-text);
}
.modal--note .modal__head,
.modal--note .modal__foot {
  /* Re-tint head/foot dividers to match the cream surface */
  border-color: var(--color-cream-border);
}
.modal--note .modal__head {
  border-bottom: 1px solid var(--color-cream-border);
}
.modal--note .modal__foot {
  border-top: 1px solid var(--color-cream-border);
}
.modal--note .modal__close {
  color: var(--color-cream-text-dim);
}
.modal--note .modal__close:hover {
  background: rgba(180, 83, 9, 0.12);
  color: var(--color-cream-text-strong);
}
/* Foot actions on a note modal use a cream-tinted secondary button
   so they don't look starkly out of place on the warm surface. */
.modal--note .modal__foot .btn--secondary {
  background: var(--color-yellow-glow);
  border-color: var(--color-cream-border);
  color: var(--color-cream-text-strong);
}
.modal--note .modal__foot .btn--secondary:hover {
  background: var(--color-yellow-pale);
  border-color: var(--color-yellow);
  color: var(--color-cream-text-strong);
}

/* Share modal — status toggle row used in Manage & Share modals */
.modal-status {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-5) var(--space-6);
  background: var(--color-bg-off);
  border-radius: var(--radius-sm);
  margin-bottom: var(--space-8);
}

.modal-status p {
  font-size: var(--font-size-body);
  font-weight: var(--font-weight-medium);
  color: var(--color-text);
  margin: 0;
}

/* Pushes the left-side action (e.g. Scheduling Settings) to the far left
   while the remaining modal footer buttons stay right-aligned */
.modal-foot-start {
  margin-right: auto;
}

/* Sub-panel headings for the text / email share panels */
.appt-share-panel__title {
  font-size: var(--font-size-body-lg);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
  margin: 0 0 var(--space-3);
}

.appt-share-panel__desc {
  font-size: var(--font-size-body);
  color: var(--color-text-secondary);
  margin: 0 0 var(--space-8);
}


/* ===========================================================
   3. SIDEBARS — .inbox-rail, .profile-sidebar,
                 .scheduling-sidebar, .form-builder-sidebar
   Visual reference: Profile Settings sidebar (.profile-sidebar);
   Email Inbox rail (.inbox-rail)
   Note: Layout positioning (width, grid placement) lives in
   layout.css. This file provides the chrome and item styling.
   =========================================================== */

/* ---- Inbox rail (icon-only thin sidebar, dark navy) ----
   Dark surface shared with the Settings sidebars (Profile,
   Scheduling). All four rail tokens live in tokens.css §1c. */
.inbox-rail {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2); /* 4px */
  padding: var(--space-6) 0; /* 12px 0 */
  background: var(--color-rail-bg);
  color: var(--color-rail-fg);
  overflow-y: auto;
}

.inbox-rail__section {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
}
.inbox-rail__section + .inbox-rail__section {
  margin-top: var(--space-3); /* 6px */
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-rail-bg-hover);
}

.inbox-rail__item {
  position: relative;
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  background: transparent;
  color: var(--color-rail-fg-dim);
  border-radius: var(--radius-sm); /* 8px */
  cursor: pointer;
  transition:
    background-color var(--duration-base) var(--easing-default),
    color var(--duration-base) var(--easing-default);
}
.inbox-rail__item:hover {
  background: var(--color-rail-bg-hover);
  color: var(--color-text-on-action);
}
.inbox-rail__item:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}
.inbox-rail__item.is-active {
  background: var(--color-blue);
  color: var(--color-text-on-action);
}

.inbox-rail__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.inbox-rail__icon > svg { width: 20px; height: 20px; }

.inbox-rail__label {
  position: absolute;
  bottom: 4px;
  font-size: 9px;
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0.04em;
}

.inbox-rail__count {
  position: absolute;
  top: 3px;
  right: 3px;
  min-width: 15px;
  height: 15px;
  padding: 0 var(--space-2);
  background: var(--color-red);
  color: var(--color-text-on-action);
  border-radius: var(--radius-pill);
  font-size: 9px;
  font-weight: var(--font-weight-bold);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 2px solid var(--color-rail-bg);
}

/* ---- Profile Settings sidebar (dark navy surface) ----
   Used by all Settings pages. Dark surface lets the user know
   they've left the main app context and are now in a different
   mode. Uses the same rail palette as .inbox-rail. */
.profile-sidebar {
  padding: var(--space-9) var(--space-7) var(--space-10); /* 20 14 24 */
  background: var(--color-rail-bg);
  border-right: 1px solid rgba(255, 255, 255, 0.06);
  overflow-y: auto;
  color: var(--color-rail-fg);
}

.profile-sidebar-format {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

/* Header — eyebrow + display title sitting above the items.
   Source: ps-sb-head pattern in the existing Settings designs. */
.profile-sidebar__header {
  display: flex;
  flex-direction: column;
  gap: var(--space-3); /* 6px between eyebrow and title */
  padding: var(--space-1) var(--space-6) var(--space-7); /* 2 12 14 */
  margin-bottom: var(--space-3);
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.profile-sidebar__eyebrow {
  font-family: var(--font-body);
  font-size: var(--font-size-micro); /* 11px */
  font-weight: var(--font-weight-semibold);
  line-height: 1;
  letter-spacing: var(--letter-spacing-uppercase);
  text-transform: uppercase;
  color: var(--color-rail-fg-dim);
}

.profile-sidebar__title {
  font-family: var(--font-display);
  font-size: 20px; /* between h4 (18px) and h3 (22px) — sized for sidebar context */
  font-weight: var(--font-weight-bold);
  line-height: 1.15;
  letter-spacing: -0.015em;
  color: var(--color-text-on-action);
  margin: 0;
}

.profile-sidebar__section {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.profile-sidebar__section + .profile-sidebar__section {
  margin-top: var(--space-7);
  padding-top: var(--space-7);
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}

.profile-sidebar__item {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-6); /* 12px */
  padding: var(--space-5) var(--space-7); /* 10px 14px */
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
  font-family: var(--font-body);
  font-size: var(--font-size-body);
  font-weight: var(--font-weight-medium);
  line-height: 1.1;
  color: var(--color-rail-fg);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition:
    background-color var(--duration-base) var(--easing-default),
    color var(--duration-base) var(--easing-default);
}
.profile-sidebar__item:hover:not(.is-active) {
  background: var(--color-rail-bg-hover);
  color: var(--color-text-on-action);
}
.profile-sidebar__item:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}
.profile-sidebar__item.is-active {
  background: var(--color-blue);
  color: var(--color-text-on-action);
  font-weight: var(--font-weight-semibold);
  box-shadow: var(--shadow-sm);
}
.profile-sidebar__item.is-active .profile-sidebar__icon { color: var(--color-text-on-action); }

.profile-sidebar__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  color: var(--color-rail-fg-dim);
  transition: color var(--duration-base) var(--easing-default);
}
.profile-sidebar__icon > svg { width: 18px; height: 18px; }
.profile-sidebar__item:hover:not(.is-active) .profile-sidebar__icon {
  color: var(--color-text-on-action);
}

.profile-sidebar__label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.profile-sidebar__count {
  font-size: var(--font-size-micro); /* 11px */
  font-weight: var(--font-weight-semibold);
  padding: 1px var(--space-3); /* 1px 6px */
  border-radius: var(--radius-pill);
  background: rgba(255, 255, 255, 0.08);
  color: var(--color-rail-fg);
  flex-shrink: 0;
}
.profile-sidebar__item.is-active .profile-sidebar__count {
  background: rgba(255, 255, 255, 0.2);
  color: var(--color-text-on-action);
}
.profile-sidebar__item:hover:not(.is-active) .profile-sidebar__count {
  background: rgba(255, 255, 255, 0.12);
  color: var(--color-text-on-action);
}

/* ----- Mobile drawer extras ----- */

/* Close button: tucked in the top-right of the sidebar header.
   Hidden on desktop; surfaced at ≤1000px. */
.profile-sidebar__header {
  position: relative;
}

.profile-sidebar__close {
  display: none;
  position: absolute;
  top: 0;
  right: 0;
  color: var(--color-rail-fg-dim);
}

/* Backdrop: full-screen overlay behind the drawer. */
.profile-sidebar__backdrop {
  display: none;
}

/* Trigger strip: appears at the top of the content area on mobile. */
.profile-sidebar__mobile-trigger {
  display: none;
  align-items: center;
  gap: var(--space-4);
  width: 100%;
  padding: var(--space-5) var(--space-9);
  background: var(--color-bg);
  border: 0;
  border-bottom: 1px solid var(--color-border-light);
  font-family: var(--font-body);
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-secondary);
  cursor: pointer;
  text-align: left;
  transition: background-color var(--duration-fast) var(--easing-default);
}

.profile-sidebar__mobile-trigger > svg:last-child {
  margin-left: auto;
  flex-shrink: 0;
}

.profile-sidebar__mobile-trigger:hover {
  background: var(--color-bg-hover);
  color: var(--color-text);
}

@media (max-width: 1000px) {
  /* Lift the sidebar out of the flow and position it as a left-side
     drawer. It stays rendered (not display:none) so the CSS transition
     on transform can run smoothly. The layout.css display:none is
     overridden here — transform handles visibility instead. */
  .profile-sidebar {
    display: flex;
    flex-direction: column;
    position: fixed;
    top: var(--topbar-height);
    left: 0;
    height: calc(100dvh - var(--topbar-height));
    width: 280px;
    z-index: var(--z-modal);
    transform: translateX(-100%);
    transition: transform 0.3s ease;
    overflow-y: auto;
  }

  .profile-sidebar.is-open {
    transform: translateX(0);
    box-shadow: var(--shadow-lg);
  }

  .profile-sidebar__close {
    display: inline-flex;
  }

  .profile-sidebar__mobile-trigger {
    display: flex;
    flex-shrink: 0;
  }

  /* The trigger is a flex item inside app__main (a flex row).
     Switch app__main to column on profile pages so the trigger
     stacks above the page content instead of sitting beside it. */
  .app__main:has(.profile-sidebar__mobile-trigger) {
    flex-direction: column;
  }
}

/* ---- Scheduling Settings sidebar (white surface) ----
   Used by editor-style flows (the scheduling editor, and any
   other "you're inside a focused editor" page). Different from
   .profile-sidebar in three ways: white surface, an __exit
   button at the top, and a soft blue-tint active state instead
   of the solid blue fill. */
.scheduling-sidebar {
  padding: var(--space-7) var(--space-7) var(--space-10); /* 14 14 24 */
  background: var(--color-bg);
  border-right: 1px solid var(--color-border);
  overflow-y: auto;
  color: var(--color-text);
}

.scheduling-sidebar-format {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

/* Exit slot — sizing only; spacing owned by __header. */

.scheduling-sidebar__section {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.scheduling-sidebar__section + .scheduling-sidebar__section {
  margin-top: var(--space-7);
  padding-top: var(--space-7);
  border-top: 1px solid var(--color-border-light);
}
.scheduling-sidebar__item {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-6);
  padding: var(--space-5) var(--space-7);
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
  font-family: var(--font-body);
  font-size: var(--font-size-body);
  font-weight: var(--font-weight-medium);
  line-height: 1.1;
  color: var(--color-text);
  text-align: left;
  cursor: pointer;
  transition:
    background-color var(--duration-base) var(--easing-default),
    color var(--duration-base) var(--easing-default);
}
.scheduling-sidebar__item:hover:not(.is-active) {
  background: var(--color-bg-off);
  color: var(--color-text);
}
.scheduling-sidebar__item:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}
.scheduling-sidebar__item.is-active {
  background: var(--color-blue-glow);
  color: var(--color-blue);
  font-weight: var(--font-weight-semibold);
}
.scheduling-sidebar__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  color: var(--color-text-dim);
  transition: color var(--duration-base) var(--easing-default);
}
.scheduling-sidebar__icon > svg { width: 18px; height: 18px; }
.scheduling-sidebar__item:hover:not(.is-active) .scheduling-sidebar__icon {
  color: var(--color-text-secondary);
}
.scheduling-sidebar__item.is-active .scheduling-sidebar__icon { color: var(--color-blue); }
.scheduling-sidebar__label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.scheduling-sidebar__count {
  font-size: var(--font-size-rail-label);
  font-weight: var(--font-weight-semibold);
  padding: 2px var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--color-blue-glow);
  color: var(--color-blue);
  flex-shrink: 0;
}
.scheduling-sidebar__item.is-active .scheduling-sidebar__count {
  background: var(--color-blue-pale);
  color: var(--color-blue-dark);
}

/* ----- Scheduling sidebar mobile drawer extras ----- */

/* Header row: exit button + close button side by side. */
.scheduling-sidebar__header {
  display: flex;
  align-items: stretch;
  gap: var(--space-3);
  margin-bottom: var(--space-6);
}

.scheduling-sidebar__exit {
  flex: 1;
  min-width: 0;
}

/* Close button: in normal flow inside the header row; hidden on desktop. */
.scheduling-sidebar__close {
  display: none;
}

/* Backdrop: permanently hidden (no overlay for this sidebar). */
.scheduling-sidebar__backdrop {
  display: none;
}

/* Trigger strip: appears at the top of the content area on mobile. */
.scheduling-sidebar__mobile-trigger {
  display: none;
  align-items: center;
  gap: var(--space-4);
  width: 100%;
  padding: var(--space-5) var(--space-9);
  background: var(--color-bg);
  border: 0;
  border-bottom: 1px solid var(--color-border-light);
  font-family: var(--font-body);
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-secondary);
  cursor: pointer;
  text-align: left;
  transition: background-color var(--duration-fast) var(--easing-default);
}

.scheduling-sidebar__mobile-trigger > svg:last-child {
  margin-left: auto;
  flex-shrink: 0;
}

.scheduling-sidebar__mobile-trigger:hover {
  background: var(--color-bg-hover);
  color: var(--color-text);
}

@media (max-width: 1000px) {
  .scheduling-sidebar {
    display: flex;
    flex-direction: column;
    position: fixed;
    top: var(--topbar-height);
    left: 0;
    height: calc(100dvh - var(--topbar-height));
    width: 280px;
    z-index: var(--z-modal);
    transform: translateX(-100%);
    transition: transform 0.3s ease;
    overflow-y: auto;
  }

  .scheduling-sidebar.is-open {
    transform: translateX(0);
    box-shadow: var(--shadow-lg);
  }

  .scheduling-sidebar__close {
    display: inline-flex;
  }

  .scheduling-sidebar__mobile-trigger {
    display: flex;
    flex-shrink: 0;
  }

  .app__main:has(.scheduling-sidebar__mobile-trigger) {
    flex-direction: column;
  }
}

/* ---- Form Builder sidebar (dark navy settings panel) ----
   Different in kind from the other three sidebars: this one is
   a settings panel (live form controls), not a navigation list.
   Four regions stacked vertically:
     __top    — home button + form switcher
     __title  — section heading + optional status chip
     __body   — scrollable middle, holds __section-label + __row groups
     __foot   — bottom action bar (Save + delete)
   Form controls inside __body use the --on-rail variants of
   .field, .input, .toggle, .checkbox, .radio, .btn so they
   render correctly on the dark surface. */
.form-builder-sidebar {
  display: flex;
  flex-direction: column;
  background: var(--color-rail-bg);
  color: var(--color-rail-fg);
  overflow: hidden; /* foot is sticky-bottom; body scrolls */
  font-family: var(--font-body);
}

/* ----- __top: navigation cluster (home + selector) ----- */
.form-builder-sidebar__top {
  display: flex;
  align-items: center;
  gap: var(--space-5); /* 10px */
  padding: var(--space-7); /* 14px */
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  flex-shrink: 0;
}
/* Positioning slot for the home button. The button itself uses
   .btn .btn--secondary .btn--icon .btn--on-rail — visual treatment
   comes from those modifiers, not from this class. */
.form-builder-sidebar__home {
  flex-shrink: 0;
}
/* Positioning slot for the form-switcher. The control itself
   is a select.input.input--on-rail that fills the remaining
   horizontal space. */
.form-builder-sidebar__selector {
  flex: 1;
  min-width: 0;
}
.form-builder-sidebar__selector .input {
  width: 100%;
}

/* ----- __title: heading + optional status chip ----- */
.form-builder-sidebar__title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
  padding: var(--space-9) var(--space-8) var(--space-7); /* 20 16 14 */
  flex-shrink: 0;
}
.form-builder-sidebar__title > h2,
.form-builder-sidebar__title > h3 {
  margin: 0;
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: var(--font-weight-bold);
  line-height: 1.15;
  letter-spacing: -0.015em;
  color: var(--color-text-on-action);
  flex: 1;
  min-width: 0;
}

/* ----- __body: scrollable settings region ----- */
.form-builder-sidebar__body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 0 var(--space-8) var(--space-8); /* 0 16 16 */
  display: flex;
  flex-direction: column;
  gap: var(--space-7); /* 14px between groups */
}

/* Optional dividers between groups inside __body. */
.form-builder-sidebar__divider {
  height: 1px;
  background: rgba(255, 255, 255, 0.08);
  margin: var(--space-3) 0;
  border: 0;
}

/* Section eyebrow ("FORM NAME", "FORM DESIGN", "INTERNAL NOTIFICATIONS"). */
.form-builder-sidebar__section-label {
  font-family: var(--font-body);
  font-size: var(--font-size-micro); /* 11px */
  font-weight: var(--font-weight-semibold);
  line-height: 1;
  letter-spacing: var(--letter-spacing-uppercase);
  text-transform: uppercase;
  color: var(--color-rail-fg-dim);
  margin: var(--space-3) 0 var(--space-4); /* 6 0 8 */
}

/* A single setting row — label on the left, control on the
   right. Used for the toggle rows and color-swatch rows. */
.form-builder-sidebar__row {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  padding: var(--space-5) 0; /* 10px vertical, no horizontal */
  min-height: 36px;
}
.form-builder-sidebar__row + .form-builder-sidebar__row {
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}

.form-builder-sidebar__row-label {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: var(--space-5);
  font-family: var(--font-body);
  font-size: var(--font-size-body); /* 14px */
  font-weight: var(--font-weight-medium);
  color: var(--color-text-on-action);
}
.form-builder-sidebar__row-label > svg {
  width: 18px;
  height: 18px;
  color: var(--color-rail-fg-dim);
  flex-shrink: 0;
}

.form-builder-sidebar__row-control {
  display: flex;
  align-items: center;
  gap: var(--space-3); /* 6px */
  flex-shrink: 0;
}

/* ----- __foot: bottom action bar ----- */
.form-builder-sidebar__foot {
  display: flex;
  align-items: center;
  gap: var(--space-4); /* 8px */
  padding: var(--space-7) var(--space-8); /* 14 16 */
  background: var(--color-rail-bg);
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  flex-shrink: 0;
}
/* Primary save action stretches to fill remaining space */
.form-builder-sidebar__foot .btn--primary {
  flex: 1;
}


/* ===========================================================
   4. TABS — .tabs
   Visual reference: SMS Inbox tabs (canonical for both
   --underline and --pills variants)
   =========================================================== */

.tabs {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  position: relative;
}

.tabs__item {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-5) var(--space-7); /* 10 14 */
  background: transparent;
  border: 0;
  border-radius: 0;
  font-family: var(--font-body);
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-medium);
  line-height: 1;
  color: var(--color-text-secondary);
  cursor: pointer;
  transition:
    background-color var(--duration-fast) var(--easing-default),
    color var(--duration-fast) var(--easing-default);
}
.tabs__item:hover:not(.is-active) { color: var(--color-text); }
.tabs__item:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}
.tabs__item:disabled,
.tabs__item.is-disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.tabs__count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 18px;
  padding: 0 var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--color-bg-off);
  color: var(--color-text-secondary);
  font-size: var(--font-size-micro);
  font-weight: var(--font-weight-semibold);
  line-height: 1;
}
.tabs__item.is-active .tabs__count {
  background: var(--color-blue-glow);
  color: var(--color-blue);
}

/* ----- Underline (default) ----- */
.tabs--underline {
  border-bottom: 1px solid var(--color-border);
  gap: 0;
}
.tabs--underline .tabs__item {
  padding-bottom: var(--space-6); /* 12px */
  border-bottom: 2px solid transparent;
  margin-bottom: -1px; /* overlap container border */
}
.tabs--underline .tabs__item:hover:not(.is-active) {
  border-bottom-color: var(--color-border-hover);
}
.tabs--underline .tabs__item.is-active {
  color: var(--color-blue);
  border-bottom-color: var(--color-blue);
  font-weight: var(--font-weight-semibold);
}

/* ----- Pills ----- */
.tabs--pills {
  background: var(--color-bg-off);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: var(--space-1); /* 2px */
  gap: var(--space-1);
}
.tabs--pills .tabs__item {
  padding: var(--space-4) var(--space-7); /* 8 14 */
  border-radius: 6px;
}
.tabs--pills .tabs__item:hover:not(.is-active) {
  color: var(--color-text);
}
.tabs--pills .tabs__item.is-active {
  background: var(--color-bg);
  color: var(--color-text);
  font-weight: var(--font-weight-semibold);
  box-shadow: var(--shadow-sm);
}

/* ----- Vertical ----- */
.tabs--vertical {
  flex-direction: column;
  align-items: stretch;
  border-bottom: 0;
  border-right: 1px solid var(--color-border);
  gap: 0;
}
.tabs--vertical .tabs__item {
  justify-content: flex-start;
  padding: var(--space-5) var(--space-7);
  border-bottom: 0;
  border-right: 2px solid transparent;
  margin-bottom: 0;
  margin-right: -1px;
}
.tabs--vertical .tabs__item.is-active {
  color: var(--color-blue);
  border-right-color: var(--color-blue);
  background: var(--color-blue-glow);
}


/* ===========================================================
   5. FILTER DRAWER — .filter-drawer
   Visual reference: Contact Detail / Property Detail / Task
   Detail V2 filter drawer (the cdv-tw implementation)
   =========================================================== */

.filter-drawer {
  position: fixed;
  bottom: var(--space-9); /* 20px */
  right: var(--space-9);
  width: 300px;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius); /* 12px */
  box-shadow: var(--shadow-xl);
  padding: var(--space-8); /* 16px */
  z-index: var(--z-popover);
  font-family: var(--font-body);
  font-size: var(--font-size-small);
  color: var(--color-text);
  display: flex;
  flex-direction: column;
  gap: var(--space-7); /* 14px */
}

.filter-drawer__row {
  display: flex;
  flex-direction: column;
  gap: var(--space-3); /* 6px */
}

.filter-drawer__label {
  font-size: var(--font-size-micro); /* 11px */
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: var(--letter-spacing-micro);
  color: var(--color-text-dim);
}

.filter-drawer__field {
  /* Container slot for inputs / segments / selects per row.
     Provides nothing visual on its own — just a hook. */
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}


/* ===========================================================
   6. CHIP — .chip
   Visual reference: Contact List filter chips (.chip--outline);
   Email inbox row category chips (solid semantic chips)
   =========================================================== */

.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2); /* 4px */
  padding: 2px var(--space-4); /* 2px 8px */
  border-radius: var(--radius-pill);
  font-family: var(--font-body);
  font-size: var(--font-size-micro); /* 11px */
  font-weight: var(--font-weight-semibold);
  line-height: 1.4;
  white-space: nowrap;
  border: 1px solid transparent;
  /* Intentionally no default background — see decisions doc:
     bare .chip is a base layer for runtime color override via
     inline style (custom task statuses). */
}

.chip__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}

.chip__label {
  display: inline-block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.chip__clear {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px;
  height: 14px;
  margin-left: var(--space-1);
  margin-right: -2px;
  padding: 0;
  background: transparent;
  border: 0;
  border-radius: 50%;
  color: currentColor;
  opacity: 0.6;
  cursor: pointer;
  transition: opacity var(--duration-fast) var(--easing-default), background-color var(--duration-fast) var(--easing-default);
}
.chip__clear:hover {
  opacity: 1;
  background: rgba(0, 0, 0, 0.06);
}
.chip__clear:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 2px var(--color-focus-ring);
  opacity: 1;
}
.chip__clear > svg { width: 10px; height: 10px; }

/* ----- Outline modifier (filter chips with __clear) ----- */
.chip--outline {
  background: var(--color-bg);
  border-color: var(--color-border);
  color: var(--color-text-secondary);
  padding: var(--space-2) var(--space-5); /* 4 10 */
}
.chip--outline:hover {
  border-color: var(--color-border-hover);
  color: var(--color-text);
}

/* ----- Semantic color modifiers ----- */
/* Each modifier defines its own background + text combination.
   tokens.css does not split chip background and chip text into
   separate aliases; the pale-color tokens already supply the
   bg, and we choose a darker matching token for the text. */

/* Contact lifecycle */
.chip--lead {
  background: var(--color-blue-pale);
  color: var(--color-blue-dark);
}
.chip--customer {
  background: var(--color-green-pale);
  color: var(--color-green-dark);
}
.chip--vip {
  background: var(--color-purple-pale);
  color: var(--color-purple);
}
.chip--prospect {
  background: var(--color-yellow-pale);
  color: var(--color-yellow);
}
.chip--former-customer {
  background: var(--color-red-pale);
  color: var(--color-red-dark);
}

/* Task status — 7 system statuses */
.chip--new-unassigned {
  background: var(--color-green-glow);
  color: var(--color-green-dark);
}
.chip--need-to-respond-sms {
  background: var(--color-yellow-pale);
  color: var(--color-yellow);
}
.chip--need-to-respond-email {
  background: var(--color-yellow-pale);
  color: var(--color-yellow);
}
.chip--internal-update {
  background: var(--color-purple-pale);
  color: var(--color-purple);
}
.chip--waiting-on-customer {
  background: var(--color-blue-glow);
  color: var(--color-blue-dark);
}
.chip--snoozed {
  background: var(--color-bg-hover);
  color: var(--color-text-secondary);
}
.chip--complete {
  background: var(--color-green-pale);
  color: var(--color-green-dark);
}

/* Content type */
.chip--note {
  background: var(--color-yellow-pale);
  color: var(--color-yellow);
}
.chip--attachment {
  background: var(--color-bg-off);
  color: var(--color-text-secondary);
}
.chip--mention {
  background: var(--color-purple-pale);
  color: var(--color-purple);
}
.chip--team {
  background: var(--color-blue-pale);
  color: var(--color-blue-dark);
}

/* Appointment status — used on attendee-facing scheduling pages */
.chip--confirmed {
  background: var(--color-green-pale);
  color: var(--color-green-dark);
}
.chip--cancelled {
  background: var(--color-red-pale);
  color: var(--color-red-dark);
}
.chip--awaiting {
  background: var(--color-yellow-pale);
  color: var(--color-yellow);
}

/* General status */
.chip--scheduled {
  background: var(--color-blue-pale);
  color: var(--color-blue-dark);
}
.chip--neutral {
  background: var(--color-bg-hover);
  color: var(--color-text-secondary);
}


/* ===========================================================
   7. FORM FIELD — .field, .input
   Visual reference: Profile Settings form fields
   (e.g., Settings - Basic Information)
   =========================================================== */

.field {
  display: flex;
  flex-direction: column;
  gap: var(--space-3); /* 6px label→input */
  margin-bottom: var(--space-8); /* 16px between consecutive fields */
}

.field:last-child {
  margin-bottom: 0;
}

.field__label {
  font-family: var(--font-body);
  font-size: var(--font-size-small); /* 13px */
  font-weight: var(--font-weight-medium);
  line-height: 1.2;
  color: var(--color-text);
}

.field__hint {
  font-family: var(--font-body);
  font-size: var(--font-size-caption); /* 12px */
  font-weight: var(--font-weight-regular);
  line-height: 1.4;
  color: var(--color-text-dim);
  margin-top: var(--space-1);
}

.field__error {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-family: var(--font-body);
  font-size: var(--font-size-caption);
  font-weight: var(--font-weight-medium);
  line-height: 1.4;
  color: var(--color-red);
  margin-top: var(--space-1);
}
.field__error > svg { width: 14px; height: 14px; flex-shrink: 0; }

.field__success {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-family: var(--font-body);
  font-size: var(--font-size-caption);
  font-weight: var(--font-weight-medium);
  line-height: 1.4;
  color: var(--color-green-dark);
  margin-top: var(--space-1);
}
.field__success > svg { width: 14px; height: 14px; flex-shrink: 0; }

/* ---- Input / textarea / select ---- */
.input {
  width: 100%;
  padding: var(--space-5) var(--space-7); /* 10px 14px */
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm); /* 8px */
  font-family: var(--font-body);
  font-size: var(--font-size-body); /* 14px */
  font-weight: var(--font-weight-regular);
  line-height: 1.4;
  color: var(--color-text);
  transition:
    border-color var(--duration-base) var(--easing-default),
    box-shadow var(--duration-base) var(--easing-default),
    background-color var(--duration-base) var(--easing-default);
  -webkit-appearance: none;
  appearance: none;
}
.input::placeholder {
  color: var(--color-text-dim);
}
.input:hover {
  border-color: var(--color-border-hover);
}
.input:focus,
.input:focus-visible {
  outline: 0;
  border-color: var(--color-blue);
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}
.input:disabled {
  background: var(--color-bg-off);
  color: var(--color-text-dim);
  cursor: not-allowed;
}

/* Textarea-specific tuning */
textarea.input {
  resize: vertical;
  min-height: 88px;
  line-height: var(--line-height-body);
}

/* Select chevron */
select.input {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%239CA3AF' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat;
  background-position: right 12px center;
  padding-right: 36px;
  cursor: pointer;
}

/* ---- Error / success states ---- */
.field--error .field__label { /* label keeps its color but sits with red error message below */ }
.field--error .input,
.input.is-invalid {
  border-color: var(--color-red);
}
.field--error .input:focus,
.input.is-invalid:focus {
  border-color: var(--color-red);
  box-shadow: 0 0 0 3px var(--color-focus-ring-danger);
}

.field--success .input {
  border-color: var(--color-green);
}
.field--success .input:focus {
  border-color: var(--color-green);
  box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.12);
  /* TODO: tokens.css does not define a green focus ring rgba —
     using inline rgba to match input contract. Flagged. */
}

/* ----- Surface modifier: --on-rail ----- */
/* Re-skins .field, its label/hint, and child .input for dark
   surfaces. Apply to BOTH the wrapper and the input:
     <label class="field field--on-rail">
       <span class="field__label">…</span>
       <input class="input input--on-rail">
     </label>
   The wrapper modifier handles label/hint colors. The input
   modifier handles the input's own surface treatment.        */
.field--on-rail .field__label {
  color: var(--color-text-on-action);
}
.field--on-rail .field__hint {
  color: var(--color-rail-fg-dim);
}
.field--on-rail .field__error {
  /* Red still reads on dark; keep the token. Lighten via
     pale-red if you find it too saturated in practice. */
  color: var(--color-red);
}
.field--on-rail .field__success {
  color: var(--color-green);
}

.input--on-rail {
  background: var(--color-rail-input-bg);
  border-color: var(--color-rail-border);
  color: var(--color-text-on-action);
}
.input--on-rail::placeholder {
  color: var(--color-rail-fg-dim);
}
.input--on-rail:hover {
  border-color: var(--color-rail-border-hover);
}
.input--on-rail:focus,
.input--on-rail:focus-visible {
  border-color: var(--color-blue);
  box-shadow: 0 0 0 3px var(--color-focus-ring);
  /* Focus ring stays brand-blue — it pops on the dark surface. */
}
.input--on-rail:disabled {
  background: var(--color-rail-input-bg-disabled);
  color: var(--color-rail-fg-dim);
}
/* Select chevron — light slate version of the data URL */
select.input--on-rail {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2394A3B8' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
}
/* Error / invalid state on rail — keep the red border but
   account for the rail-input-bg fill. */
.field--on-rail.field--error .input,
.input--on-rail.is-invalid {
  border-color: var(--color-red);
}
.field--on-rail.field--error .input:focus,
.input--on-rail.is-invalid:focus {
  border-color: var(--color-red);
  box-shadow: 0 0 0 3px var(--color-focus-ring-danger);
}


/* ===========================================================
   8. AVATAR — .avatar
   Visual reference: tb-avatar (the topbar avatar)
   =========================================================== */

.avatar {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  border-radius: var(--radius-pill); /* circular */
  background: var(--gradient-message-incoming);
  color: var(--color-text-on-action);
  font-family: var(--font-body);
  font-weight: var(--font-weight-semibold);
  overflow: hidden;
  /* Default size = md */
  width: 32px;
  height: 32px;
  font-size: var(--font-size-caption); /* 12px */
}

.avatar__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.avatar__initials {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  user-select: none;
}

.avatar__status {
  position: absolute;
  right: -2px;
  bottom: -2px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--color-text-dim); /* offline default */
  border: 2px solid var(--color-bg);
  box-sizing: content-box;
}
.avatar__status.is-online { background: var(--color-green); }
.avatar__status.is-offline { background: var(--color-text-dim); }

/* ----- Size modifiers ----- */
.avatar--xs {
  width: 20px;
  height: 20px;
  font-size: 9px;
}
.avatar--xs .avatar__status { width: 6px; height: 6px; right: -1px; bottom: -1px; border-width: 1.5px; }

.avatar--sm {
  width: 26px;
  height: 26px;
  font-size: var(--font-size-micro); /* 11px */
}
.avatar--sm .avatar__status { width: 8px; height: 8px; }

.avatar--md {
  width: 32px;
  height: 32px;
  font-size: var(--font-size-caption);
}

.avatar--lg {
  width: 44px;
  height: 44px;
  font-size: var(--font-size-h5); /* 15px */
}
.avatar--lg .avatar__status { width: 12px; height: 12px; }

.avatar--xl {
  width: 80px;
  height: 80px;
  font-size: 26px;
}
.avatar--xl .avatar__status {
  width: 16px;
  height: 16px;
  right: 2px;
  bottom: 2px;
}

/* ----- Square (rare — company / property avatars) ----- */
.avatar--square {
  border-radius: var(--radius-sm);
}


/* ===========================================================
   9. TOOLTIP — .tooltip
   Visual reference: Property Detail attachment filename tooltip
   Show on parent's :hover and :focus-within. CSS-only, with
   a 250ms transition-delay on show to prevent flicker.
   =========================================================== */

.tooltip {
  position: absolute;
  z-index: var(--z-popover);
  background: var(--color-text); /* dark bg */
  color: var(--color-text-on-action);
  padding: var(--space-3) var(--space-5); /* 6 10 */
  border-radius: 6px;
  font-family: var(--font-body);
  font-size: var(--font-size-micro); /* 11px */
  font-weight: var(--font-weight-medium);
  line-height: 1.4;
  white-space: nowrap;
  max-width: 280px;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
  box-shadow: var(--shadow-md);
  opacity: 0;
  transform: translateY(2px);
  transition:
    opacity var(--duration-base) var(--easing-default),
    transform var(--duration-base) var(--easing-default);
  transition-delay: 0ms;
}

/* Parent must have position: relative for these to anchor */
*:hover > .tooltip,
*:focus-within > .tooltip {
  opacity: 1;
  transform: translateY(0);
  transition-delay: 250ms; /* prevents flicker */
}

.tooltip__arrow {
  position: absolute;
  width: 8px;
  height: 8px;
  background: var(--color-text);
  transform: rotate(45deg);
}

/* ----- Position modifiers ----- */
.tooltip--top {
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translate(-50%, 2px);
}
*:hover > .tooltip--top,
*:focus-within > .tooltip--top {
  transform: translate(-50%, 0);
}
.tooltip--top .tooltip__arrow {
  bottom: -3px;
  left: 50%;
  margin-left: -4px;
}

.tooltip--bottom {
  top: calc(100% + 8px);
  left: 50%;
  transform: translate(-50%, -2px);
}
*:hover > .tooltip--bottom,
*:focus-within > .tooltip--bottom {
  transform: translate(-50%, 0);
}
.tooltip--bottom .tooltip__arrow {
  top: -3px;
  left: 50%;
  margin-left: -4px;
}

.tooltip--left {
  right: calc(100% + 8px);
  top: 50%;
  transform: translate(2px, -50%);
}
*:hover > .tooltip--left,
*:focus-within > .tooltip--left {
  transform: translate(0, -50%);
}
.tooltip--left .tooltip__arrow {
  right: -3px;
  top: 50%;
  margin-top: -4px;
}

.tooltip--right {
  left: calc(100% + 8px);
  top: 50%;
  transform: translate(-2px, -50%);
}
*:hover > .tooltip--right,
*:focus-within > .tooltip--right {
  transform: translate(0, -50%);
}
.tooltip--right .tooltip__arrow {
  left: -3px;
  top: 50%;
  margin-top: -4px;
}

/* ----- Mono modifier (for filenames / code) ----- */
.tooltip--mono {
  font-family: var(--font-mono);
  font-size: var(--font-size-caption);
}


/* ===========================================================
   10. SPINNER + LOADING OVERLAY — .spinner, .loading-overlay
   New components — fill a system gap (no existing reference).
   =========================================================== */

@keyframes ec-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

.spinner {
  display: inline-block;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 2.5px solid var(--color-border);
  border-top-color: var(--color-blue);
  animation: ec-spin 0.8s linear infinite;
  vertical-align: middle;
  flex-shrink: 0;
}

.spinner--sm {
  width: 16px;
  height: 16px;
  border-width: 2px;
}
.spinner--lg {
  width: 40px;
  height: 40px;
  border-width: 3px;
}
.spinner--xl {
  width: 64px;
  height: 64px;
  border-width: 4px;
}

/* ----- Loading overlay ----- */
.loading-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-6); /* 12px */
  background: var(--color-overlay-modal);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  z-index: var(--z-popover);
}

.loading-overlay--solid {
  background: var(--color-bg);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

.loading-overlay__spinner {
  /* Compose with a .spinner--lg element inside; this slot just
     gives spacing reliability if needed. */
}

.loading-overlay__label {
  font-family: var(--font-body);
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-secondary);
}
.loading-overlay--solid .loading-overlay__label {
  color: var(--color-text);
}


/* ===========================================================
   11. LOAD MORE — .load-more
   Replaces traditional pagination.
   =========================================================== */

.load-more {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-6); /* 12px */
  padding: var(--space-9) var(--space-8) var(--space-12); /* 20 16 32 */
}

.load-more__btn {
  /* Markup uses .btn .btn--secondary on this element — this
     class adds nothing visual. Reserved for hooks (e.g. tests). */
}

.load-more__count {
  font-family: var(--font-body);
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-dim);
}

.load-more__spinner {
  /* Markup uses a .spinner.spinner--sm inside; this class is a
     positioning hook. */
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
}


/* ===========================================================
   12. SEARCH INPUT — .search-input
   Visual reference: Contact List search (cl-search)
   =========================================================== */

.search-input {
  position: relative;
  display: flex;
  align-items: center;
  width: 100%;
  max-width: 360px;
}

.search-input__icon {
  position: absolute;
  left: var(--space-6); /* 12px */
  top: 50%;
  transform: translateY(-50%);
  color: var(--color-text-dim);
  pointer-events: none;
  display: inline-flex;
}
.search-input__icon > svg {
  width: 16px;
  height: 16px;
}

.search-input__field {
  width: 100%;
  height: 36px;
  padding: 0 var(--space-7) 0 38px; /* leave room for icon */
  background: var(--color-bg-off);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font-family: var(--font-body);
  font-size: var(--font-size-small); /* 13px */
  font-weight: var(--font-weight-regular);
  color: var(--color-text);
  outline: 0;
  transition:
    background-color var(--duration-base) var(--easing-default),
    border-color var(--duration-base) var(--easing-default),
    box-shadow var(--duration-base) var(--easing-default);
}
.search-input__field::placeholder {
  color: var(--color-text-dim);
}
.search-input__field:hover {
  border-color: var(--color-border-hover);
}
.search-input__field:focus,
.search-input__field:focus-visible {
  background: var(--color-bg);
  border-color: var(--color-blue);
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}
.search-input:focus-within .search-input__icon {
  color: var(--color-blue);
}

.search-input__field:disabled {
  background: var(--color-bg-off);
  color: var(--color-text-dim);
  cursor: not-allowed;
}

.search-input__clear {
  position: absolute;
  right: var(--space-3);
  top: 50%;
  transform: translateY(-50%);
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  background: transparent;
  color: var(--color-text-dim);
  border-radius: 50%;
  cursor: pointer;
  transition:
    background-color var(--duration-fast) var(--easing-default),
    color var(--duration-fast) var(--easing-default);
}
.search-input__clear:hover {
  background: var(--color-bg-hover);
  color: var(--color-text);
}
.search-input__clear:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 2px var(--color-focus-ring);
}
.search-input__clear > svg { width: 12px; height: 12px; }

/* ----- Size modifiers ----- */
.search-input--sm .search-input__field {
  height: 30px;
  font-size: var(--font-size-caption);
  padding-left: 32px;
}
.search-input--sm .search-input__icon { left: var(--space-5); }
.search-input--sm .search-input__icon > svg { width: 14px; height: 14px; }

.search-input--lg .search-input__field {
  height: 44px;
  font-size: var(--font-size-body);
  padding-left: 44px;
}
.search-input--lg .search-input__icon { left: var(--space-7); }
.search-input--lg .search-input__icon > svg { width: 18px; height: 18px; }


/* ===========================================================
   13. EMPTY STATE — .empty-state
       NOTICE      — .notice  (alert / informational popups)
   Both share the same centered-column visual pattern.
   .empty-state = no-data / zero-content states.
   .notice      = alert dialogs, prerequisite warnings, confirmations.
   Visual reference: Contact List empty (--page);
   Contact Detail empty states (--inline); Twilio prerequisites modal.
   =========================================================== */

.empty-state,
.notice {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-7); /* 14px */
  font-family: var(--font-body);
  color: var(--color-text);
}

.empty-state__icon,
.notice__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: var(--radius);
  background: var(--color-bg-off);
  color: var(--color-text-dim);
  flex-shrink: 0;
}
.empty-state__icon > svg,
.notice__icon > svg { width: 28px; height: 28px; }

/* Decorative tone modifiers on the icon — designer's choice */
.empty-state__icon--tone-blue,
.notice__icon--tone-blue {
  background: var(--color-blue-glow);
  color: var(--color-blue);
}
.empty-state__icon--tone-yellow,
.notice__icon--tone-yellow {
  background: var(--color-yellow-glow);
  color: var(--color-yellow);
}
.empty-state__icon--tone-purple,
.notice__icon--tone-purple {
  background: var(--color-purple-pale);
  color: var(--color-purple);
}

.empty-state__title,
.notice__title {
  font-family: var(--font-display);
  font-size: var(--font-size-h4); /* 18px */
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-h4);
  letter-spacing: var(--letter-spacing-display);
  color: var(--color-text);
  margin: 0;
}

.empty-state__body,
.notice__body {
  font-family: var(--font-body);
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-small);
  color: var(--color-text-secondary);
  max-width: 480px;
  margin: 0;
}

.empty-state__actions,
.notice__actions {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-top: var(--space-2);
}

/* ----- Card grid (for secondary action cards) ----- */
.empty-state__cards {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-6);
  width: 100%;
  margin-top: var(--space-4);
}

.empty-state__card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-7);
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  text-align: left;
  cursor: pointer;
  transition:
    border-color var(--duration-base) var(--easing-default),
    box-shadow var(--duration-base) var(--easing-default),
    transform var(--duration-base) var(--easing-default);
  position: relative;
}
.empty-state__card:hover {
  border-color: var(--color-border-hover);
  box-shadow: var(--shadow-sm);
  transform: translateY(-1px);
}
.empty-state__card:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}

.empty-state__card-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: var(--radius-sm);
  background: var(--color-blue-glow);
  color: var(--color-blue);
  flex-shrink: 0;
}
.empty-state__card-icon > svg { width: 18px; height: 18px; }

.empty-state__card-title {
  font-family: var(--font-body);
  font-size: var(--font-size-body);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
  margin: 0;
}

.empty-state__card-description {
  font-family: var(--font-body);
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-small);
  color: var(--color-text-secondary);
  margin: 0;
}

.empty-state__card-arrow {
  position: absolute;
  top: var(--space-7);
  right: var(--space-7);
  color: var(--color-text-dim);
  transition: color var(--duration-base) var(--easing-default), transform var(--duration-base) var(--easing-default);
}
.empty-state__card:hover .empty-state__card-arrow {
  color: var(--color-blue);
  transform: translateX(2px);
}
.empty-state__card-arrow > svg { width: 14px; height: 14px; }

/* ----- Bottom tip strip ----- */
.empty-state__tip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-7);
  background: var(--color-bg-off);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-pill);
  font-family: var(--font-body);
  font-size: var(--font-size-caption);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-secondary);
  margin-top: var(--space-3);
}
.empty-state__tip > svg {
  width: 14px;
  height: 14px;
  color: var(--color-yellow);
  flex-shrink: 0;
}

/* ----- Page modifier (full-page empty) ----- */
.empty-state--page {
  padding: var(--space-16) var(--space-12); /* 48 32 */
  gap: var(--space-9);
}
.empty-state--page .empty-state__icon {
  width: 80px;
  height: 80px;
  border-radius: var(--radius-lg);
}
.empty-state--page .empty-state__icon > svg { width: 40px; height: 40px; }
.empty-state--page .empty-state__title {
  font-size: var(--font-size-h2); /* 30px */
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-h2);
  letter-spacing: var(--letter-spacing-h2);
}
.empty-state--page .empty-state__body {
  font-size: var(--font-size-body-lg);
  line-height: var(--line-height-body-lg);
}

/* ----- Inline modifier (section-level, dashed + striped) -----
   tokens.css does not currently provide a stripe-pattern color
   variable — using the same border color as a soft fallback.
   Flagged in Missing Tokens. */
.empty-state--inline {
  padding: var(--space-16) var(--space-12);
  border: 1px dashed var(--color-border);
  border-radius: var(--radius);
  background-color: var(--color-bg-off);
  background-image: repeating-linear-gradient(
    -45deg,
    transparent 0,
    transparent 6px,
    rgba(229, 231, 235, 0.3) 6px,
    rgba(229, 231, 235, 0.3) 7px
  );
}
.empty-state--inline .empty-state__cards {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.empty-state--inline .empty-state__icon {
  width: 48px;
  height: 48px;
  background: var(--color-action-bg-subtle);
  color: var(--color-action);
}
.empty-state--inline .empty-state__icon > svg { width: 24px; height: 24px; }
.empty-state--inline .empty-state__body {
  margin-top: calc(var(--space-2) - var(--space-7)); /* tightens gap after title */
}

/* ----- Page-level is-empty: applied to the page wrapper -----
   Behavior implemented at the wrapper level (analogous to
   legacy .cl-zero): fades toolbar, hides column headers. The
   wrapper class names live in page CSS; here we provide the
   generic targets. */
.is-empty .toolbar { opacity: 0.5; pointer-events: none; }
.is-empty .list-head { display: none; }


/* ===========================================================
   14. ONBOARDING BANNER — .onboarding-banner
   Visual reference: Contact Detail empty state design
   (where the pattern originated)
   =========================================================== */

.onboarding-banner {
  display: flex;
  align-items: center;
  gap: var(--space-7); /* 14px */
  padding: var(--space-7) var(--space-8); /* 14 16 */
  background: var(--color-blue-glow);
  border: 1px solid var(--color-blue-pale);
  border-radius: var(--radius);
  font-family: var(--font-body);
  color: var(--color-text);
}

.onboarding-banner__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: var(--radius-sm);
  background: var(--color-bg);
  color: var(--color-blue);
  flex-shrink: 0;
  border: 1px solid var(--color-blue-pale);
}
.onboarding-banner__icon > svg { width: 18px; height: 18px; }

.onboarding-banner__body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.onboarding-banner__label {
  font-size: var(--font-size-micro);
  font-weight: var(--font-weight-semibold);
  letter-spacing: var(--letter-spacing-micro);
  text-transform: uppercase;
  color: var(--color-blue);
}

.onboarding-banner__text {
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-medium);
  line-height: 1.4;
  color: var(--color-text);
}

.onboarding-banner__progress {
  display: flex;
  align-items: center;
  gap: var(--space-2); /* 4px */
  flex-shrink: 0;
}

.onboarding-banner__progress-segment {
  width: 24px;
  height: 6px;
  border-radius: var(--radius-pill);
  background: var(--color-bg);
  border: 1px solid var(--color-blue-pale);
  transition: background-color var(--duration-base) var(--easing-default);
}
.onboarding-banner__progress-segment.is-done {
  background: var(--color-blue);
  border-color: var(--color-blue);
}

.onboarding-banner__meta {
  font-size: var(--font-size-micro);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-dim);
  flex-shrink: 0;
}


/* ===========================================================
   15. COMPOSER — .composer
   Inline reply composer.
   Visual reference: SMS Inbox composer
   =========================================================== */

.composer {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-6); /* 12px */
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  transition:
    border-color var(--duration-base) var(--easing-default),
    box-shadow var(--duration-base) var(--easing-default);
}
.composer:focus-within {
  border-color: var(--color-blue);
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}

.composer__textarea {
  width: 100%;
  min-height: 64px;
  padding: var(--space-3) var(--space-4);
  background: transparent;
  border: 0;
  outline: 0;
  resize: none;
  font-family: var(--font-body);
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-text);
}
.composer__textarea::placeholder {
  color: var(--color-text-dim);
}

.composer__tools {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border-light);
}

/* Send button is a positioning class only.
   Markup: <button class="btn btn--primary btn--icon composer__send"> */
.composer__send {
  margin-left: auto;
}

/* ----- Sm modifier (TeamChat thread reply) ----- */
.composer--sm {
  padding: var(--space-4);
  gap: var(--space-2);
}
.composer--sm .composer__textarea {
  min-height: 40px;
  font-size: var(--font-size-small);
}
.composer--sm .composer__tools {
  padding-top: var(--space-2);
}

/* ----- Inline modifier (compact, no card chrome) ----- */
.composer--inline {
  padding: 0;
  border: 0;
  background: transparent;
}
.composer--inline:focus-within {
  border: 0;
  box-shadow: none;
}
.composer--inline .composer__textarea {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: var(--space-5) var(--space-7);
  background: var(--color-bg);
  transition:
    border-color var(--duration-base) var(--easing-default),
    box-shadow var(--duration-base) var(--easing-default);
}
.composer--inline .composer__textarea:focus {
  border-color: var(--color-blue);
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}


/* ===========================================================
   16. EMAIL COMPOSER — REMOVED
   The original .email-composer was an awkward middle state —
   it had body anatomy (recipients, subject, formatting toolbar,
   body, attachments) but no popup chrome (no head with title +
   close, no foot with Send/Schedule cluster). It didn't fit
   the popup use case OR the inline use case cleanly.

   It has been split into two purpose-built components:
     - .email-composer-popup (Component #35) — full standalone
       popup, like .sms-composer. Self-contained, mounts inside
       .modal__backdrop if dimming is needed.
     - .email-composer-inline (TBD) — inline variant that lives
       in a thread/page, no popup chrome. Will be built when
       designs are confirmed.

   Slot #16 is intentionally left empty. The component count
   skips this number.
   =========================================================== */


/* ===========================================================
   17. STATUS DOT — .status-dot
   Visual reference: Task List status dot (default);
   WebChat Settings status dot (color variants)
   =========================================================== */

.status-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--color-text-dim); /* neutral default */
  flex-shrink: 0;
  vertical-align: middle;
}

.status-dot--sm { width: 6px; height: 6px; }
.status-dot--lg { width: 10px; height: 10px; }

.status-dot--success { background: var(--color-green); }
.status-dot--warning { background: var(--color-yellow); }
.status-dot--danger  { background: var(--color-red); }
.status-dot--info    { background: var(--color-blue); }
.status-dot--neutral { background: var(--color-text-dim); }


/* ===========================================================
   18. TOGGLE — .toggle
   Visual reference: Settings - Linked Phone Numbers toggle
   (the ps-switch implementation)
   =========================================================== */

.toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--space-5); /* 10px */
  font-family: var(--font-body);
  cursor: pointer;
  user-select: none;
}

.toggle__track {
  position: relative;
  width: 40px;
  height: 22px;
  background: var(--color-border-hover);
  border: 0;
  border-radius: var(--radius-pill);
  cursor: pointer;
  flex-shrink: 0;
  transition: background-color var(--duration-slow) var(--easing-default);
}

.toggle__thumb {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--color-bg);
  box-shadow: var(--shadow-sm);
  transition: transform var(--duration-slow) var(--easing-default);
}

.toggle__label {
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-medium);
  color: var(--color-text);
}

/* On state */
.toggle.is-on .toggle__track {
  background: var(--color-blue);
}
.toggle.is-on .toggle__thumb {
  transform: translateX(18px);
}

/* Focus */
.toggle__track:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}

/* Disabled */
.toggle.is-disabled,
.toggle:has(input:disabled) {
  opacity: 0.5;
  cursor: not-allowed;
}
.toggle.is-disabled .toggle__track {
  cursor: not-allowed;
}

/* ----- Size modifiers ----- */
.toggle--sm .toggle__track {
  width: 32px;
  height: 18px;
}
.toggle--sm .toggle__thumb {
  width: 14px;
  height: 14px;
  top: 2px;
  left: 2px;
}
.toggle--sm.is-on .toggle__thumb {
  transform: translateX(14px);
}

.toggle--lg .toggle__track {
  width: 48px;
  height: 28px;
}
.toggle--lg .toggle__thumb {
  width: 22px;
  height: 22px;
  top: 3px;
  left: 3px;
}
.toggle--lg.is-on .toggle__thumb {
  transform: translateX(20px);
}

/* ----- Surface modifier: --on-rail ----- */
.toggle--on-rail .toggle__track {
  background: var(--color-rail-track);
}
.toggle--on-rail .toggle__label {
  color: var(--color-text-on-action);
}
/* On-state stays brand-blue. The white thumb still reads on
   either track color, so no thumb override is needed. */


/* ===========================================================
   19. CHECKBOX — .checkbox
   Visual reference: Contact List row checkbox
   =========================================================== */

.checkbox {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4); /* 8px */
  font-family: var(--font-body);
  cursor: pointer;
  user-select: none;
  position: relative;
}

.checkbox__box {
  position: relative;
  width: 18px;
  height: 18px;
  background: var(--color-bg);
  border: 1.5px solid var(--color-border-hover);
  border-radius: var(--radius-xs);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--color-text-on-action);
  flex-shrink: 0;
  transition:
    background-color var(--duration-base) var(--easing-default),
    border-color var(--duration-base) var(--easing-default);
}
.checkbox:hover .checkbox__box {
  border-color: var(--color-blue);
}

.checkbox__box::after {
  /* Checkmark, hidden until is-checked */
  content: '';
  width: 10px;
  height: 10px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='white' stroke-width='3' viewBox='0 0 24 24'><path stroke-linecap='round' stroke-linejoin='round' d='M5 13l4 4L19 7'/></svg>");
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
  display: none;
}

.checkbox__label {
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-medium);
  color: var(--color-text);
}

/* Checked */
.checkbox.is-checked .checkbox__box {
  background: var(--color-blue);
  border-color: var(--color-blue);
}
.checkbox.is-checked .checkbox__box::after {
  display: block;
}

/* Indeterminate */
.checkbox.is-indeterminate .checkbox__box {
  background: var(--color-blue);
  border-color: var(--color-blue);
}
.checkbox.is-indeterminate .checkbox__box::after {
  content: '';
  width: 8px;
  height: 2px;
  background-image: none;
  background-color: var(--color-text-on-action);
  border-radius: 1px;
  display: block;
}

/* Disabled */
.checkbox.is-disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.checkbox.is-disabled:hover .checkbox__box {
  border-color: var(--color-border-hover);
}

/* Focus */
.checkbox__box:focus-visible,
.checkbox:focus-within .checkbox__box {
  outline: 0;
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}

/* ----- Surface modifier: --on-rail ----- */
.checkbox--on-rail .checkbox__box {
  background: var(--color-rail-input-bg);
  border-color: var(--color-rail-border);
}
.checkbox--on-rail:hover .checkbox__box {
  border-color: var(--color-rail-border-hover);
}
.checkbox--on-rail .checkbox__label {
  color: var(--color-text-on-action);
}
/* Checked / indeterminate stay solid blue — no override needed. */
.checkbox--on-rail.is-checked .checkbox__box,
.checkbox--on-rail.is-indeterminate .checkbox__box {
  background: var(--color-blue);
  border-color: var(--color-blue);
}


/* ===========================================================
   20. RADIO — .radio
   Visual reference: Settings - Linked Phone Numbers radio group
   =========================================================== */

.radio {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  font-family: var(--font-body);
  cursor: pointer;
  user-select: none;
  position: relative;
}

.radio__circle {
  position: relative;
  width: 18px;
  height: 18px;
  background: var(--color-bg);
  border: 1.5px solid var(--color-border-hover);
  border-radius: 50%;
  flex-shrink: 0;
  transition:
    border-color var(--duration-base) var(--easing-default),
    background-color var(--duration-base) var(--easing-default);
}
.radio:hover .radio__circle {
  border-color: var(--color-blue);
}

.radio__circle::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 8px;
  height: 8px;
  margin: -4px 0 0 -4px;
  border-radius: 50%;
  background: var(--color-bg);
  transform: scale(0);
  transition: transform var(--duration-base) var(--easing-default);
}

.radio__label {
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-medium);
  color: var(--color-text);
}

/* Checked */
.radio.is-checked .radio__circle {
  background: var(--color-blue);
  border-color: var(--color-blue);
}
.radio.is-checked .radio__circle::after {
  transform: scale(1);
}

/* Disabled */
.radio.is-disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.radio.is-disabled:hover .radio__circle {
  border-color: var(--color-border-hover);
}

/* Focus */
.radio__circle:focus-visible,
.radio:focus-within .radio__circle {
  outline: 0;
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}

/* ----- Surface modifier: --on-rail ----- */
.radio--on-rail .radio__circle {
  background: var(--color-rail-input-bg);
  border-color: var(--color-rail-border);
}
.radio--on-rail:hover .radio__circle {
  border-color: var(--color-rail-border-hover);
}
.radio--on-rail .radio__label {
  color: var(--color-text-on-action);
}
.radio--on-rail.is-checked .radio__circle {
  background: var(--color-blue);
  border-color: var(--color-blue);
}


/* ===========================================================
   21. CARD — .card
   Visual reference: Profile Settings card (ps-card)
   =========================================================== */

.card {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg); /* 16px */
  padding: var(--space-10) var(--space-12); /* 24 32 — Profile Settings rhythm */
  box-shadow: var(--shadow-sm);
  font-family: var(--font-body);
  color: var(--color-text);
  transition:
    border-color var(--duration-base) var(--easing-default),
    box-shadow var(--duration-base) var(--easing-default),
    transform var(--duration-base) var(--easing-default);
  margin-bottom: var(--space-8); /* 16px between consecutive cards */
}

.card:last-child {
  margin-bottom: 0;
}

.card__head {
  margin-bottom: var(--space-9); /* 20px */
  padding-bottom: var(--space-8); /* 16px — slightly tighter than margin */
  border-bottom: 1px solid var(--color-border-light);
}
.card__head:has(+ .card__body) { /* keeps natural rhythm */ }

.card__title {
  font-family: var(--font-display);
  font-size: var(--font-size-body-lg); /* 16px */
  font-weight: var(--font-weight-semibold);
  line-height: 1.2;
  letter-spacing: -0.005em;
  color: var(--color-text);
  margin: 0 0 var(--space-2) 0;
}

.card__subtitle {
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  line-height: 1.4;
  margin: 0;
}

.card__body {
  /* Content area; no enforced constraints. */
}

.card__foot {
  margin-top: var(--space-9);
  padding-top: var(--space-8);
  border-top: 1px solid var(--color-border-light);
  display: flex;
  align-items: center;
  gap: var(--space-4);
}

.card__actions {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin-left: auto;
}

/* ----- Modifiers (compose) ----- */

/* Padded is the default; no extra rule needed. Class exists
   so it can be applied explicitly when paired with --flush
   children for clarity. */
.card--padded { /* default — see base rule */ }

/* Flush — no internal padding (for tables / lists inside) */
.card--flush {
  padding: 0;
}
.card--flush .card__head {
  padding: var(--space-9) var(--space-10) var(--space-7);
  margin-bottom: 0;
  border-bottom: 1px solid var(--color-border);
}
.card--flush .card__foot {
  padding: var(--space-7) var(--space-10) var(--space-9);
  margin-top: 0;
  border-top: 1px solid var(--color-border);
}

/* Bordered is the default; explicit class for composition clarity. */
.card--bordered { /* default — see base rule */ }

/* Elevated — no border, has shadow */
.card--elevated {
  border-color: transparent;
  box-shadow: var(--shadow-md);
}

/* Interactive — hover state for clickable cards */
.card--interactive {
  cursor: pointer;
}
.card--interactive:hover {
  border-color: var(--color-border-hover);
  box-shadow: var(--shadow);
  transform: translateY(-1px);
}
.card--interactive:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}
.card--interactive.card--elevated:hover {
  box-shadow: var(--shadow-lg);
}


/* ===========================================================
   22. BANNER — .banner
   Inline, appears at the top of a section or page.
   Visual reference: Contact Detail banner (cdv-banner);
   Settings - API Key warning note (ap-key-note) for --warning
   =========================================================== */

.banner {
  display: flex;
  align-items: center;
  gap: var(--space-6);
  padding: var(--space-7) var(--space-8);
  border: 1px solid transparent;
  border-radius: var(--radius);
  font-family: var(--font-body);
  font-size: var(--font-size-small);
  line-height: 1.5;
  color: var(--color-text);
}

.banner__icon {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  margin-top: 2px;
  color: currentColor;
}
.banner__icon > svg { width: 18px; height: 18px; }

.banner__body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.banner__title {
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
  margin: 0;
}

.banner__message {
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-regular);
  color: var(--color-text-secondary);
  margin: 0;
}

.banner__actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-shrink: 0;
  margin-left: var(--space-5);
}

.banner__close {
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-left: auto;
  background: transparent;
  border: 0;
  border-radius: 6px;
  color: var(--color-text-dim);
  cursor: pointer;
  transition:
    background-color var(--duration-fast) var(--easing-default),
    color var(--duration-fast) var(--easing-default);
}
.banner__close:hover {
  background: var(--color-bg-hover);
  color: var(--color-text);
}
.banner__close:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}
.banner__close > svg { width: 14px; height: 14px; }

/* ----- Tone modifiers ----- */
.banner--info {
  background: var(--color-blue-glow);
  border-color: var(--color-blue-pale);
}
.banner--info .banner__icon { color: var(--color-blue); }

.banner--success {
  background: var(--color-green-glow);
  border-color: var(--color-green-pale);
}
.banner--success .banner__icon { color: var(--color-green-dark); }

.banner--warning {
  background: var(--color-yellow-glow);
  border-color: var(--color-yellow-pale);
}
.banner--warning .banner__icon { color: var(--color-yellow); }

.banner--danger {
  background: var(--color-red-glow);
  border-color: var(--color-red-pale);
}
.banner--danger .banner__icon { color: var(--color-red); }


/* ===========================================================
   23. TOAST — .toast
   Floating, typically bottom-right or top-right.
   Visual reference: Settings - Connected Calendars / Contact
   Cards / Email Inboxes toast notifications
   =========================================================== */

.toast {
  display: flex;
  align-items: flex-start;
  gap: var(--space-5); /* 10px */
  min-width: 300px;
  max-width: 420px;
  padding: var(--space-6) var(--space-7); /* 12 14 */
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
  font-family: var(--font-body);
  font-size: var(--font-size-small);
  color: var(--color-text);
  z-index: var(--z-toast);
  /* Default state at rest (after entering, before leaving) */
  opacity: 1;
  transform: translateY(0);
  transition:
    opacity var(--duration-slow) var(--easing-default),
    transform var(--duration-slow) var(--easing-default);
}

.toast__icon {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  margin-top: 1px;
  color: var(--color-blue);
}
.toast__icon > svg { width: 18px; height: 18px; }

.toast__message {
  flex: 1;
  min-width: 0;
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-medium);
  line-height: 1.4;
  color: var(--color-text);
}

.toast__action {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  background: transparent;
  border: 0;
  padding: 0 var(--space-3);
  font: inherit;
  font-weight: var(--font-weight-semibold);
  color: var(--color-blue);
  cursor: pointer;
  border-radius: 4px;
  transition: color var(--duration-fast) var(--easing-default), background-color var(--duration-fast) var(--easing-default);
}
.toast__action:hover {
  background: var(--color-blue-glow);
}
.toast__action:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 2px var(--color-focus-ring);
}

.toast__close {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-left: var(--space-2);
  background: transparent;
  border: 0;
  border-radius: 4px;
  color: var(--color-text-dim);
  cursor: pointer;
  transition:
    background-color var(--duration-fast) var(--easing-default),
    color var(--duration-fast) var(--easing-default);
}
.toast__close:hover {
  background: var(--color-bg-hover);
  color: var(--color-text);
}
.toast__close:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 2px var(--color-focus-ring);
}
.toast__close > svg { width: 12px; height: 12px; }

/* ----- Tone modifiers ----- */
.toast--info {
  border-left: 3px solid var(--color-blue);
}
.toast--info .toast__icon { color: var(--color-blue); }

.toast--success {
  border-left: 3px solid var(--color-green);
}
.toast--success .toast__icon { color: var(--color-green-dark); }

.toast--warning {
  border-left: 3px solid var(--color-yellow);
}
.toast--warning .toast__icon { color: var(--color-yellow); }

.toast--danger {
  border-left: 3px solid var(--color-red);
}
.toast--danger .toast__icon { color: var(--color-red); }

/* ----- Animation states (toggled by JS) ----- */
.toast.is-entering {
  opacity: 0;
  transform: translateY(8px);
}
.toast.is-leaving {
  opacity: 0;
  transform: translateY(-4px);
}


/* ===========================================================
   24. SEGMENT — .segment
   Visual reference: tweak segments in Contact Detail / Property
   Detail / Task Detail filter drawers (tweak-segment / cdv-tw-seg)
   Use anywhere you need a 2–4 option selector with a single
   active state. Distinct from .tabs--pills: tabs change page
   content; segments change a setting/filter/display preference.
   =========================================================== */

.segment {
  display: inline-flex;
  align-items: center;
  background: var(--color-bg-off);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: var(--space-1); /* 2px */
  gap: 0;
  width: 100%;
}

.segment__item {
  flex: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  padding: var(--space-5) var(--space-6);
  background: transparent;
  border: 0;
  border-radius: 6px;
  font-family: var(--font-body);
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-medium);
  line-height: 1.2;
  color: var(--color-text-secondary);
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--easing-default), color var(--duration-fast) var(--easing-default), box-shadow var(--duration-fast) var(--easing-default);
}
.segment__item:hover:not(.is-active) {
  background: var(--color-bg-hover);
  color: var(--color-text);
}
.segment__item:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}
.segment__item:disabled,
.segment__item.is-disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.segment__item.is-active {
  background: var(--color-bg);
  color: var(--color-text);
  font-weight: var(--font-weight-semibold);
  box-shadow: var(--shadow-sm);
}

/* ----- Size modifiers ----- */
.segment--sm .segment__item {
  padding: var(--space-2) var(--space-5);
  font-size: var(--font-size-micro);
}

.segment--lg .segment__item {
  padding: var(--space-5) var(--space-7);
  font-size: var(--font-size-small);
}


/* ===========================================================
   25. SIDE PANEL — .side-panel
   Persistent right-side panel adjacent to main content. Not a
   modal — no backdrop, content behind stays interactive.
   Visual reference: Inbox right-side context panel
   (contact info, tasks, helpful videos — content is page-
   specific and not part of the component).

   This component is chrome only: surface, left border,
   padding, height modifiers, and slide-in/out animation
   states. Content inside is composed from existing primitives
   in page CSS, the same way .card and .modal work.

   Distinct from .modal--drawer: that's a centered modal that
   slides in (with a backdrop, modal-blocking). This is a
   layout region (no backdrop, persistent).
   =========================================================== */

.side-panel {
  display: flex;
  flex-direction: column;
  background: var(--color-bg);
  border-left: 1px solid var(--color-border);
  /* No top, right, or bottom border — top is handled by the
     navigation bar above; right is the page edge; bottom flows
     with content or container. */
  overflow: hidden; /* __body is the scrolling region */
  font-family: var(--font-body);
  color: var(--color-text);
  /* Default state at rest, ready for JS to toggle .is-entering /
     .is-leaving on mount/unmount. */
  transform: translateX(0);
  opacity: 1;
  transition:
    transform var(--duration-slow) var(--easing-default),
    opacity var(--duration-slow) var(--easing-default);
}

/* ----- Optional sub-elements -----
   Pages may use any subset of these. Body is the only one
   that's typically present in every panel. */

.side-panel__head {
  display: flex;
  align-items: center;
  gap: var(--space-5); /* 10px */
  padding: var(--space-7) var(--space-9); /* 14 20 */
  border-bottom: 1px solid var(--color-border-light);
  flex-shrink: 0;
  position: relative; /* anchors __close */
}

.side-panel__title {
  font-family: var(--font-display);
  font-size: var(--font-size-h4); /* 18px */
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-h4);
  letter-spacing: var(--letter-spacing-display);
  color: var(--color-text);
  margin: 0;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.side-panel__close {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
  color: var(--color-text-dim);
  cursor: pointer;
  transition:
    background-color var(--duration-base) var(--easing-default),
    color var(--duration-base) var(--easing-default);
}
.side-panel__close:hover {
  background: var(--color-bg-hover);
  color: var(--color-text);
}
.side-panel__close:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}
.side-panel__close > svg { width: 18px; height: 18px; }

.side-panel__body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: var(--space-9); /* 20px — generous, content sits inside */
}

.side-panel__foot {
  display: flex;
  align-items: center;
  gap: var(--space-4); /* 8px */
  padding: var(--space-7) var(--space-9); /* 14 20 */
  border-top: 1px solid var(--color-border-light);
  flex-shrink: 0;
  background: var(--color-bg);
}

/* ----- Height modifiers ----- */

/* Default (no modifier): contained — height inherited from
   container. Sits within the bounds of whatever parent grid
   or flex row it's placed in. */

/* Full — spans full viewport height. Use when the panel is a
   top-level page region rather than nested inside a card. */
.side-panel--full {
  height: 100vh;
  position: sticky;
  top: 0;
}

/* ----- Animation states (JS toggles these on mount/unmount) -----
   Same contract as .toast: JS adds .is-entering on mount,
   removes it after animation completes; adds .is-leaving
   before unmount, then removes the element after the
   transition. */
.side-panel.is-entering {
  transform: translateX(100%);
  opacity: 0;
}
.side-panel.is-leaving {
  transform: translateX(100%);
  opacity: 0;
}


/* ===========================================================
   26. MESSAGE — .message
   Visual reference: SMS Inbox conversation thread.
   Used in SMS Inbox, Contact Detail, Property Detail, and
   Task Detail wherever a chronological message thread renders.

   Anatomy:
     __avatar          — positioning slot for an .avatar
     __bubble          — the text-holding shape
     __meta            — timestamp + sender footer
     __actions         — hover-only floating action toolbar
     __task-indicator  — cream badge shown when the message
                         has been converted to a task

   Modifiers:
     --inbound (default) — grey bubble, avatar left
     --outbound          — blue bubble, avatar right

   States:
     .is-converted-to-task — shows __task-indicator
   =========================================================== */

.message {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-5); /* 10px between avatar and bubble */
  align-items: flex-start;
  position: relative;
  font-family: var(--font-body);
}

/* The bubble + meta column. A wrapper inside the grid so the
   meta sits flush under the bubble, not under the avatar. */
.message__bubble-wrap {
  display: flex;
  flex-direction: column;
  gap: var(--space-3); /* 6px between bubble and meta */
  min-width: 0;
  max-width: 70%;
  position: relative; /* anchors __actions and __task-indicator */
}

.message__avatar {
  flex-shrink: 0;
  /* Avatar size is whatever the .avatar inside this slot
     specifies — typically .avatar (32px). */
}

.message__bubble {
  padding: var(--space-6) var(--space-7); /* 12 14 */
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: 4px var(--radius-lg) var(--radius-lg) var(--radius-lg);
  /* 4px top-left (tucks against avatar), 16px elsewhere — matches
     SMS Inbox source design (.msg-bub). Outbound flips the corners. */
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-text);
  word-wrap: break-word;
  overflow-wrap: break-word;
}

.message__meta {
  font-size: var(--font-size-caption); /* 12px */
  color: var(--color-text-dim);
  line-height: 1.3;
}

/* ----- Hover action toolbar -----
   Floating cluster of icon buttons that appears above the
   bubble on hover. Hidden by default; shown when the parent
   .message is hovered or focused-within.

   Sizes match the SMS Inbox source design (.msg-hover-actions):
   26×26 buttons with 14×14 SVG icons, 2px container padding,
   8px radius. Buttons are NOT .btn instances — sized too small
   for the standard btn system. Use the __action sub-element. */
.message__actions {
  position: absolute;
  top: -14px;
  right: 10px;
  display: inline-flex;
  align-items: center;
  padding: 2px;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm); /* 8px */
  box-shadow: 0 2px 8px rgba(15, 23, 42, 0.08);
  opacity: 0;
  transform: translateY(4px);
  transition:
    opacity var(--duration-fast) var(--easing-default),
    transform var(--duration-fast) var(--easing-default);
  pointer-events: none;
  z-index: 1;
}
.message:hover .message__actions,
.message:focus-within .message__actions,
.message__actions:hover {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

/* Action button — sized to fit the compact hover toolbar.
   Distinct from .btn because .btn--icon's smallest size (.btn--sm
   at 28px) is too tall for the 14px-tall floating toolbar. */
.message__action {
  width: 26px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  border-radius: 5px;
  color: var(--color-text-secondary);
  cursor: pointer;
  padding: 0;
  transition:
    background-color var(--duration-fast) var(--easing-default),
    color var(--duration-fast) var(--easing-default);
}
.message__action:hover {
  background: var(--color-bg-hover);
  color: var(--color-text);
}
.message__action:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 2px var(--color-focus-ring);
}
.message__action > svg {
  width: 14px;
  height: 14px;
}

/* TeamChat action — purple hover state (matches source). */
.message__action--teamchat:hover {
  background: #F5F3FF;
  color: #6D28D9;
}
.message__action--teamchat.is-active {
  background: #F5F3FF;
  color: #6D28D9;
}

/* ----- Task indicator -----
   Peach circular badge in the top-right of the bubble.
   Persistent (not hover-only) when the parent has
   .is-converted-to-task. Matches SMS Inbox source design
   (.msg-bub-pin). */
.message__task-indicator {
  position: absolute;
  top: -8px;
  right: -10px;
  width: 28px;
  height: 28px;
  display: none; /* hidden until .is-converted-to-task on parent */
  align-items: center;
  justify-content: center;
  background: #FFEDD5;
  color: #C2410C;
  border: 2px solid var(--color-bg);
  border-radius: 50%;
  box-shadow:
    0 2px 4px rgba(154, 52, 18, 0.18),
    0 0 0 1px rgba(194, 65, 12, 0.08);
  cursor: pointer;
  padding: 0;
  z-index: 2; /* above __actions */
  transition: transform var(--duration-fast) var(--easing-default);
}
.message__task-indicator:hover {
  transform: scale(1.05);
}
.message__task-indicator > svg {
  width: 13px;
  height: 13px;
}
.message.is-converted-to-task .message__task-indicator {
  display: inline-flex;
}

/* ----- Inbound (default) -----
   Avatar left, grey bubble, meta left-aligned. */
.message,
.message--inbound {
  /* Default grid: avatar | bubble. Already set above. */
}
.message--inbound .message__bubble {
  background: var(--color-bg);
  border-color: var(--color-border);
  color: var(--color-text);
  /* Inherits the inbound 4px-top-left bubble shape from the
     base __bubble rule. */
}
.message--inbound .message__actions {
  /* Default position is right: 10px (set on .message__actions
     above). Inbound bubbles inherit it as-is. */
}
/* When a task is attached, the indicator sits at right: -10px
   and overlaps the actions cluster. Slide actions further left
   to clear it. Matches source .has-task .msg-hover-actions. */
.message--inbound.is-converted-to-task .message__actions {
  right: 36px;
}
.message--inbound .message__task-indicator {
  /* Stays at top-right of the bubble (default position). */
}

/* ----- Outbound -----
   Avatar right, blue bubble, meta right-aligned. Reverses
   the grid columns so the bubble comes before the avatar. */
.message--outbound {
  grid-template-columns: 1fr auto;
}
.message--outbound .message__avatar {
  grid-column: 2;
  grid-row: 1;
}
.message--outbound .message__bubble-wrap {
  grid-column: 1;
  grid-row: 1;
  margin-left: auto; /* pushes the bubble to the right within its column */
  align-items: flex-end;
}
.message--outbound .message__bubble {
  background: var(--color-blue);
  border-color: var(--color-blue);
  color: var(--color-text-on-action);
  /* Flip the small corner from top-left to top-right since
     outbound messages have the avatar on the right. */
  border-radius: var(--radius-lg) 4px var(--radius-lg) var(--radius-lg);
}
.message--outbound .message__meta {
  text-align: right;
}
.message--outbound .message__actions {
  right: auto;
  left: 10px;
}
/* When converted to task on outbound, slide actions further
   right to clear the (top-left) task indicator. */
.message--outbound.is-converted-to-task .message__actions {
  left: 36px;
}
/* On outbound messages, the task indicator (when present)
   sits top-LEFT of the bubble so it doesn't collide with the
   avatar on the right. Not commonly used since outbound
   messages aren't typically converted to tasks, but supported
   for completeness. */
.message--outbound .message__task-indicator {
  right: auto;
  left: -10px;
}


/* ===========================================================
   27. MESSAGE DAY SEPARATOR — .message-day-separator
   Centered uppercase label between groups of messages
   ("MONDAY, APR 13"). Sits in the message thread flow as a
   sibling of .message instances, not nested inside one.
   =========================================================== */

.message-day-separator {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-7) 0; /* 14px vertical breathing room */
  font-family: var(--font-body);
  font-size: var(--font-size-micro); /* 11px */
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: var(--letter-spacing-uppercase);
  color: var(--color-text-dim);
  text-align: center;
}


/* ===========================================================
   28. EMAIL MESSAGE — .email-message
   Visual reference: Email Thread View. Used in Email Inbox
   thread view and any detail-page email thread (Contact,
   Property, Task) wherever an email renders as a message
   in a chronological thread.

   Rendering model: pages render the FULL anatomy at all times.
   The --collapsed modifier hides the sub-elements that don't
   belong on a collapsed row (display: none) and restructures
   the head into a single-row layout. This means switching
   between modes is a single class flip — no re-render needed.

   Two visual modes (modifiers):
     --expanded (default) — full anatomy visible
     --collapsed          — single-row preview (avatar + sender
                            + truncated body + timestamp)

   Anatomy:
     __avatar              — slot for an .avatar
     __task-indicator      — cream task badge, child of __avatar;
                              visibility driven by .is-converted-to-task
     __head                — top row: sender (left) + meta (right)
     __sender              — sender info column (or row in collapsed)
     __sender-name         — name (always visible)
     __unread-dot          — blue dot, shown when .is-unread
     __sender-line         — wrapper for __sender-email + __recipients
                              (hidden in collapsed)
     __sender-email        — "<email@domain.com>"
     __recipients          — "to X · cc Y" line
     __preview             — single-line truncated preview
                              (visible only in collapsed mode)
     __meta                — right side of head: timestamp + actions
     __timestamp
     __head-actions        — cluster of icon buttons (reply, info)
                              (hidden in collapsed)
     __body                — paragraphs of email content
                              (hidden in collapsed)
     __linked-task         — cream task strip (email-specific design;
                              hidden in collapsed). Has its own anatomy:
                              __linked-task-icon, __linked-task-body,
                              __linked-task-eyebrow, __linked-task-title,
                              __linked-task-meta, __linked-task-status,
                              __linked-task-due, __linked-task-open
     __attachments         — wrapper for Attachment Box components
                              (hidden in collapsed)
     __action-bar          — Reply / Reply all / Forward / Send TeamChat
                              row. Latest message in a thread only.
                              (hidden in collapsed). Sub-elements:
                              __action (positioning slot), with
                              __action--teamchat color modifier
     __info-popover        — floating panel with TO/FROM/DATE/etc.
                              (hidden in collapsed). Sub-elements:
                              __info-row, __info-label, __info-value,
                              __info-sender, __info-sender-name,
                              __info-sender-role

   States:
     .is-unread            — shows __unread-dot
     .is-converted-to-task — shows __task-indicator on __avatar
     .is-info-open         — shows __info-popover
   =========================================================== */

.email-message {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg); /* 16px */
  font-family: var(--font-body);
  color: var(--color-text);
  overflow: hidden; /* keeps __action-bar's bottom edge inside the radius */
  transition:
    border-color var(--duration-base) var(--easing-default),
    box-shadow var(--duration-base) var(--easing-default);
}

/* --latest modifier — blue-tinted border + soft glow. Indicates
   the latest message in a thread (typically the most-recently-
   received email, often shown expanded with the action bar
   visible). Matches source .msg-unread treatment. */
.email-message--latest {
  border-color: var(--color-blue-pale);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.06);
}

/* ----- __head: top bar with avatar, sender info, meta ----- */
.email-message__head {
  display: flex;
  align-items: center;
  gap: var(--space-7); /* 14px */
  padding: var(--space-7) var(--space-9) var(--space-5); /* 14 20 10 */
  border-bottom: 1px solid var(--color-border-light);
  position: relative; /* anchors __info-popover */
}

.email-message__avatar {
  flex-shrink: 0;
  display: inline-flex; /* wraps tightly around .avatar */
  position: relative; /* anchors task indicator overlay */
}
/* Task indicator overlay on the avatar — peach circle, same
   visual language as .message__task-indicator. Hidden until
   parent has .is-converted-to-task. Matches source .msg-av-pin. */
.email-message__avatar .email-message__task-indicator {
  position: absolute;
  top: -3px;
  right: -3px;
  width: 18px;
  height: 18px;
  display: none;
  align-items: center;
  justify-content: center;
  background: #FFEDD5;
  color: #C2410C;
  border: 1.5px solid var(--color-bg);
  border-radius: 50%;
  box-shadow: 0 1px 3px rgba(154, 52, 18, 0.25);
  z-index: 1;
}
.email-message__avatar .email-message__task-indicator > svg {
  width: 10px;
  height: 10px;
  color: inherit;
}
.email-message.is-converted-to-task .email-message__task-indicator {
  display: inline-flex;
}

.email-message__sender {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2); /* 4px between name line and email/recipients line */
}

/* First line: name + unread dot */
.email-message__sender-name {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3); /* 6px */
  font-family: var(--font-body);
  font-size: var(--font-size-body);
  font-weight: var(--font-weight-semibold);
  line-height: 1.2;
  color: var(--color-text);
}

.email-message__unread-dot {
  display: none; /* hidden until .is-unread on parent */
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--color-blue);
  flex-shrink: 0;
}
.email-message.is-unread .email-message__unread-dot {
  display: inline-block;
}

/* Second line: <email> · to X · cc Y. Each piece is its own
   sub-element so pages can render only what's relevant. */
.email-message__sender-email,
.email-message__recipients {
  font-family: var(--font-body);
  font-size: var(--font-size-small); /* 13px */
  font-weight: var(--font-weight-regular);
  color: var(--color-text-dim);
  line-height: 1.3;
}

/* Inline these on the same line. The middle-dot separator is a
   ::before on __recipients so the markup stays clean. */
.email-message__sender-email {
  display: inline;
}
.email-message__recipients {
  display: inline;
  margin-left: var(--space-3);
}
.email-message__recipients::before {
  content: "·";
  margin-right: var(--space-3);
  color: var(--color-text-dim);
}
/* Wrap email + recipients so they share one flex/text line */
.email-message__sender-line {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0;
}

/* ----- __meta: right side of head ----- */
.email-message__meta {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: var(--space-5); /* 10px */
  margin-left: auto;
}

.email-message__timestamp {
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-regular);
  color: var(--color-text-dim);
  white-space: nowrap;
}

.email-message__head-actions {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1); /* 2px */
}
/* Active state for buttons in __head-actions — used when the
   info toggle is open (parent has .is-info-open). Mirrors hover
   state. .btn does not yet have a generic .is-active treatment;
   when it does, this can be removed. */
.email-message__head-actions .btn.is-active {
  background: var(--color-bg-hover);
  color: var(--color-text);
}
/* Action icon buttons inside __head-actions are .btn instances:
   <button class="btn btn--ghost btn--icon btn--sm"> for each.
   When the info button is in the active state, page CSS toggles
   .is-info-open on the parent .email-message, which surfaces
   __info-popover (rule below). */

/* ----- __body: paragraphs (expanded only) ----- */
.email-message__body {
  padding: var(--space-6) var(--space-9) var(--space-7); /* 12 20 14 */
  font-size: var(--font-size-body);
  line-height: var(--line-height-body-lg);
  color: var(--color-text);
}
.email-message__body > p + p {
  margin-top: var(--space-6); /* 12px between paragraphs */
}

/* ----- __preview: single-line truncated body, collapsed-mode only -----
   Hidden by default (expanded mode shows __body instead).
   The --collapsed modifier flips both --body and --preview. */
.email-message__preview {
  display: none; /* shown when parent has --collapsed */
  flex: 1;
  min-width: 0;
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-regular);
  line-height: 1.4;
  color: var(--color-text-dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.email-message__preview::before {
  content: "—";
  margin-right: var(--space-3);
  color: var(--color-text-dim);
}

/* ----- __linked-task: cream task strip with its own anatomy -----
   Email-specific design. Distinct from the future Task Row
   component (which appears in detail-page sidebars). The strip
   communicates "this email created/linked a task" with full
   task context inline.

   Anatomy:
     __linked-task-icon     — small cream-bordered icon box
     __linked-task-body     — left wrapper (eyebrow + title)
     __linked-task-eyebrow  — "LINKED TASK" warm uppercase label
     __linked-task-title    — the task name
     __linked-task-meta     — right wrapper (status + due + open)
     __linked-task-status   — slot for a .chip showing task status
     __linked-task-due      — due date text
     __linked-task-open     — external-link icon button (slot for .btn) */
.email-message__linked-task {
  display: flex;
  align-items: center;
  gap: var(--space-6); /* 12px between icon, body, and meta */
  margin: 0 var(--space-9) var(--space-7); /* 0 20 14 */
  padding: var(--space-6) var(--space-7); /* 12 14 */
  background: #FFF7ED;
  border: 1px solid #FED7AA;
  border-left: 4px solid #C2410C;
  border-radius: var(--radius-sm);
  color: #9A3412;
}

.email-message__linked-task-icon {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: #FFEDD5;
  border-radius: 6px;
  color: #C2410C;
}
.email-message__linked-task-icon > svg {
  width: 16px;
  height: 16px;
}

.email-message__linked-task-body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2); /* 4px between eyebrow and title */
}

.email-message__linked-task-eyebrow {
  font-size: var(--font-size-micro); /* 11px */
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: var(--letter-spacing-uppercase);
  color: #C2410C;
  line-height: 1;
}

.email-message__linked-task-title {
  font-size: var(--font-size-body);
  font-weight: var(--font-weight-semibold);
  line-height: 1.2;
  color: var(--color-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.email-message__linked-task-meta {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: var(--space-5); /* 10px */
}

/* The status chip slot composes .chip — page CSS picks the
   right semantic chip modifier (e.g. .chip--waiting-on-customer
   for "Waiting"). No additional styling needed here. */
.email-message__linked-task-status {
  /* Positioning hook only — visual treatment from .chip */
}

.email-message__linked-task-due {
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-regular);
  color: var(--color-text-dim);
  white-space: nowrap;
}

/* External-link button. Markup uses .btn composition with this
   positioning class:
     <button class="btn btn--ghost btn--icon btn--sm
                    email-message__linked-task-open"> */
.email-message__linked-task-open {
  color: var(--color-cream-text-dim);
}
.email-message__linked-task-open:hover {
  background: rgba(180, 83, 9, 0.12);
  color: var(--color-cream-text-strong);
}

/* ----- __attachments: wrapper for one or more .email-attachment ----- */
/* Flex-wrapped so multiple attachments flow horizontally and
   wrap to a new line when the row is full. */
.email-message__attachments {
  margin: 0 var(--space-9) var(--space-7);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4); /* 8px between attachments */
}

/* ----- __action-bar: Reply / Reply all / Forward / Send TeamChat ----- */
/* Latest message in a thread only — page CSS decides which
   message gets this rendered. */
.email-message__action-bar {
  display: flex;
  align-items: center;
  gap: var(--space-4); /* 8px */
  padding: var(--space-6) var(--space-9) var(--space-7); /* 12 20 14 */
  border-top: 1px solid var(--color-border-light);
}

/* Each action is a pill-shaped button. Self-contained — does
   NOT compose .btn. Renders correctly with just the local
   class, since the visual treatment is specific to this
   action bar (pill shape, this exact padding, this exact
   font weight). */
.email-message__action {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3); /* 6px between icon and label */
  padding: var(--space-4) var(--space-6); /* 8 12 */
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-pill);
  font-family: var(--font-body);
  font-size: var(--font-size-small); /* 13px */
  font-weight: var(--font-weight-medium);
  line-height: 1;
  color: var(--color-text-secondary);
  cursor: pointer;
  white-space: nowrap;
  transition:
    background-color var(--duration-fast) var(--easing-default),
    border-color var(--duration-fast) var(--easing-default),
    color var(--duration-fast) var(--easing-default);
}
.email-message__action:hover {
  background: var(--color-bg-off);
  border-color: var(--color-border-hover);
  color: var(--color-text);
}
.email-message__action:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}
.email-message__action > svg {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}

/* Divider — vertical line between bordered actions and the
   Send TeamChat button. Real sub-element (not a pseudo) so
   spacing/alignment is predictable. Sits as a sibling between
   the last bordered action and __action--teamchat. */
.email-message__action-divider {
  width: 1px;
  align-self: stretch;
  margin: var(--space-2) 0; /* 4px top/bottom — matches source .msg-quick-sep */
  background: var(--color-border);
  flex-shrink: 0;
}

/* Send TeamChat — same chrome as other actions, only the
   text/icon color differ. On hover: purple-tinted bg with
   purple text/icon. Border behaves identically to siblings. */
.email-message__action--teamchat {
  color: var(--color-purple);
}
.email-message__action--teamchat:hover {
  background: #F5F3FF;
  border-color: var(--color-border-hover);
  color: #5B21B6;
}
.email-message__action--teamchat > svg {
  color: var(--color-purple);
}
.email-message__action--teamchat:hover > svg {
  color: #5B21B6;
}

/* ----- __info-popover: floating TO/FROM/DATE/SENT-WITH/SENT-BY panel -----
   Anchored to the info button in __head-actions. The button toggles
   .is-info-open on the parent .email-message to surface the popover.
   Has a small arrow at the top-right pointing back at the trigger.

   Vertical position: calc(100% - 12px) overlaps into the head's
   bottom padding so the popover sits right below the info icon
   (rather than below the entire head — which would leave a
   large dead gap between the trigger and the panel). */
.email-message__info-popover {
  position: absolute;
  top: calc(100% - 12px);
  right: var(--space-9); /* aligns with the head's right padding (20px) */
  z-index: var(--z-popover);
  width: 340px;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius); /* 12px */
  box-shadow:
    0 16px 40px -8px rgba(15, 23, 42, 0.18),
    0 4px 12px -2px rgba(15, 23, 42, 0.08);
  padding: var(--space-7) var(--space-8); /* 14 16 */
  display: none; /* shown only when .is-info-open on parent */
  flex-direction: column;
  gap: var(--space-4); /* 8px between rows */
  font-size: var(--font-size-small);
  cursor: default;
}
/* Arrow tip pointing up at the info button trigger. */
.email-message__info-popover::before {
  content: "";
  position: absolute;
  top: -5px;
  right: 18px;
  width: 10px;
  height: 10px;
  background: var(--color-bg);
  border-top: 1px solid var(--color-border);
  border-left: 1px solid var(--color-border);
  transform: rotate(45deg);
}
.email-message.is-info-open .email-message__info-popover {
  display: flex;
}

.email-message__info-row {
  display: flex;
  align-items: flex-start;
  gap: var(--space-5); /* 10px */
  font-size: var(--font-size-caption); /* 12px */
  line-height: 1.45;
}
/* No row dividers — source design keeps them as a clean stack. */

.email-message__info-label {
  flex-shrink: 0;
  min-width: 112px;
  padding-top: 1px; /* visual baseline alignment with value */
  font-size: 10.5px;
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-dim);
}

.email-message__info-value {
  flex: 1;
  min-width: 0;
  font-size: var(--font-size-caption);
  font-weight: var(--font-weight-medium);
  color: var(--color-text);
  word-break: break-word;
}
.email-message__info-value--muted {
  color: var(--color-text-dim);
  font-style: italic;
}

/* The "SENT BY" row offsets its label slightly to align with
   the avatar (which is taller than a normal text line). */
.email-message__info-row--sender .email-message__info-label {
  padding-top: 5px;
}
.email-message__info-sender {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4); /* 8px */
}
.email-message__info-sender-name {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.email-message__info-sender-name-line {
  font-size: 12.5px;
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
  line-height: 1.2;
}
.email-message__info-sender-role {
  font-size: var(--font-size-micro);
  color: var(--color-text-dim);
  line-height: 1.25;
}

/* ----- --collapsed: single-row dense layout -----
   Same markup as expanded; the modifier hides everything that
   doesn't belong on a collapsed row, restructures __head into
   a flat row, and reveals __preview.

   What the modifier does:
     - Hides __sender-line (email + recipients), __head-actions,
       __body, __linked-task, __attachments, __action-bar,
       and __info-popover.
     - Reveals __preview.
     - Restructures __head and __sender for a single-row layout.
     - Tightens padding and changes border radius. */
.email-message--collapsed {
  border-radius: var(--radius);
}
.email-message--collapsed .email-message__head {
  align-items: center;
  padding: var(--space-5) var(--space-7); /* 10 14 */
  border-bottom: 0;
  gap: var(--space-5);
}
.email-message--collapsed .email-message__sender {
  flex-direction: row;
  align-items: center;
  gap: 0; /* preview's ::before "—" handles the spacing */
  flex: 1;
  min-width: 0;
}
.email-message--collapsed .email-message__sender-name {
  flex-shrink: 0;
}

/* Reveal __preview only in collapsed mode */
.email-message--collapsed .email-message__preview {
  display: block;
}

/* Hide everything that doesn't belong on a collapsed row */
.email-message--collapsed .email-message__sender-line,
.email-message--collapsed .email-message__head-actions,
.email-message--collapsed .email-message__body,
.email-message--collapsed .email-message__linked-task,
.email-message--collapsed .email-message__attachments,
.email-message--collapsed .email-message__action-bar {
  display: none;
}

/* Info popover suppression — even if .is-info-open is somehow
   set on a collapsed row, the popover stays hidden because
   collapsed rows don't have an info button visible. */
.email-message--collapsed.is-info-open .email-message__info-popover {
  display: none;
}


/* ===========================================================
   29. ACTION BAR — .action-bar
   Visual reference: Property/Contact/Task Detail header pill.
   The blue rounded-pill bar with primary actions
   (Text / Email / Call / More).

   The bar appears on Contact, Task, and Property detail pages.
   Visual treatment is identical across all three; only the
   menu items inside the More dropdown vary per page. The
   component is chrome only — pages provide the action markup.

   Anatomy:
     __action          — each action button (Text / Email / Call / More)
     __action-label    — label text inside an action
     __divider         — thin vertical translucent-white line
                          between adjacent actions
     __menu            — dropdown panel (typically anchored to More)
     __menu-item       — each option inside the menu
     __menu-icon       — icon slot inside a menu item
     __menu-label      — label slot inside a menu item
     __menu-divider    — horizontal divider between menu groups

   Modifiers:
     __menu-item--danger — red text for destructive options
                            (e.g., "Archive contact")

   States:
     __action.is-active — pressed/highlighted (translucent-white bg)
     .is-menu-open      — shows __menu
   =========================================================== */

.action-bar {
  position: relative; /* anchors __menu */
  display: inline-flex;
  align-items: center;
  background: var(--color-blue);
  border-radius: var(--radius-pill);
  padding: 3px;
  box-shadow: var(--shadow-button-action-rest);
  font-family: var(--font-body);
}

.action-bar__action {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3); /* 6px */
  padding: 9px 18px;
  background: transparent;
  border: 0;
  border-radius: var(--radius-pill);
  font-family: var(--font-body);
  font-size: var(--font-size-small); /* 13px */
  font-weight: var(--font-weight-medium);
  line-height: 1;
  color: rgba(255, 255, 255, 0.92);
  cursor: pointer;
  white-space: nowrap;
  transition:
    background-color var(--duration-fast) var(--easing-default),
    color var(--duration-fast) var(--easing-default);
}
.action-bar__action:hover {
  background: rgba(255, 255, 255, 0.14);
  color: var(--color-text-on-action);
}
.action-bar__action:focus-visible {
  outline: 0;
  background: rgba(255, 255, 255, 0.14);
  color: var(--color-text-on-action);
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.5);
}
.action-bar__action.is-active {
  background: rgba(255, 255, 255, 0.22);
  color: var(--color-text-on-action);
}
.action-bar__action:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  background: transparent;
}
.action-bar__action > svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  color: currentColor;
}

.action-bar__action-label {
  /* Hook only; styled inline by parent. */
}

/* Vertical divider between actions. Sits as a sibling of
   __action elements directly inside .action-bar. */
.action-bar__divider {
  width: 1px;
  height: 16px;
  background: rgba(255, 255, 255, 0.22);
  align-self: center;
  flex-shrink: 0;
}

/* ----- Menu (dropdown anchored to a __action) -----
   Hidden by default; revealed by .is-menu-open on the parent
   .action-bar. Page CSS / JS positions it relative to the
   triggering action (typically More). */
.action-bar__menu {
  position: absolute;
  top: calc(100% + var(--space-3)); /* 6px below the bar */
  right: 0;
  min-width: 240px;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  padding: var(--space-3); /* 6px */
  display: none;
  z-index: var(--z-popover);
  font-family: var(--font-body);
  font-size: var(--font-size-small);
  color: var(--color-text);
}
.action-bar.is-menu-open .action-bar__menu {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.action-bar__menu-item {
  display: flex;
  align-items: center;
  gap: var(--space-5); /* 10px */
  width: 100%;
  padding: var(--space-4) var(--space-5); /* 8 10 */
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
  font-family: var(--font-body);
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-medium);
  line-height: 1.2;
  color: var(--color-text);
  text-align: left;
  cursor: pointer;
  transition:
    background-color var(--duration-fast) var(--easing-default),
    color var(--duration-fast) var(--easing-default);
}
.action-bar__menu-item:hover {
  background: var(--color-bg-hover);
  color: var(--color-text);
}
.action-bar__menu-item:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}
.action-bar__menu-item:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.action-bar__menu-icon {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--color-text-secondary);
}
.action-bar__menu-icon > svg {
  width: 18px;
  height: 18px;
}
.action-bar__menu-item:hover .action-bar__menu-icon {
  color: var(--color-text);
}

.action-bar__menu-label {
  flex: 1;
  min-width: 0;
}

.action-bar__menu-divider {
  height: 1px;
  background: var(--color-border-light);
  margin: var(--space-3) 0; /* 6px vertical breathing room */
  border: 0;
}

/* Danger menu item — for destructive options (e.g., Archive). */
.action-bar__menu-item--danger {
  color: var(--color-red);
}
.action-bar__menu-item--danger .action-bar__menu-icon {
  color: var(--color-red);
}
.action-bar__menu-item--danger:hover {
  background: var(--color-red-glow);
  color: var(--color-red);
}
.action-bar__menu-item--danger:hover .action-bar__menu-icon {
  color: var(--color-red);
}


/* ===========================================================
   30. ATTACHMENT — .attachment
   Visual reference: Task Detail / Property Detail attachments
   grid (the td-att / pd-att pattern).

   Card-style file preview with a colored thumbnail block on top
   and filename + meta below. Used in attachment grids on
   detail pages. For email-attached files, use .email-attachment
   (Component #31) — the visual is meaningfully different.

   Thumb color is driven by file-type modifier on __thumb. For
   custom file types not covered, pages can apply inline style
   overrides on __thumb (same pattern as custom chip colors).

   Anatomy:
     __thumb   — colored thumbnail block
     __icon    — icon inside thumb (e.g., image-placeholder for
                  png/jpg/gif)
     __type    — text label inside thumb (e.g., "PDF", "DOC")
     __body    — wrapper for filename + meta
     __name    — filename (truncates with ellipsis)
     __meta    — size + uploader line
     __remove  — X close button (top-right of thumb)

   Modifiers on __thumb:
     --doc     blue
     --pdf     red
     --image   green
     --video   purple
     --audio   yellow
     --archive neutral
     (no modifier — neutral fallback for unknown file types)

   States:
     none — interaction is hover/click on the X button only.

   Wrapper:
     Use .attachments for the responsive grid wrapper.
   =========================================================== */

/* ----- Grid wrapper for attachment cards ----- */
.attachments {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: var(--space-5); /* 10px */
}

/* ----- Base attachment ----- */
.attachment {
  position: relative;
  display: flex;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font-family: var(--font-body);
  color: var(--color-text);
  min-width: 0;
  transition:
    border-color var(--duration-base) var(--easing-default),
    box-shadow var(--duration-base) var(--easing-default);
}
.attachment:hover {
  border-color: var(--color-border-hover);
}

/* ----- __thumb: colored thumbnail block (base — color comes from modifier) ----- */
.attachment__thumb {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
  background: var(--color-bg-off); /* default fallback */
  color: var(--color-text-secondary);
  font-size: var(--font-size-caption); /* 12px */
  font-weight: var(--font-weight-bold);
  letter-spacing: 0.04em;
  flex-shrink: 0;
}

.attachment__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.attachment__icon > svg {
  width: 24px;
  height: 24px;
  color: currentColor;
}

.attachment__type {
  /* Hook only; styling comes from __thumb. */
}

.attachment__body {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.attachment__name {
  font-size: var(--font-size-small); /* 13px */
  font-weight: var(--font-weight-medium);
  color: var(--color-text);
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.attachment__meta {
  font-size: var(--font-size-micro); /* 11px */
  font-weight: var(--font-weight-regular);
  color: var(--color-text-dim);
  line-height: 1.3;
  margin-top: 2px;
}

.attachment__remove {
  position: absolute;
  top: var(--space-2); /* 4px */
  right: var(--space-2);
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.55);
  color: var(--color-text-on-action);
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  z-index: 2;
  transition: background-color var(--duration-fast) var(--easing-default);
}
.attachment__remove:hover {
  background: rgba(0, 0, 0, 0.85);
}
.attachment__remove:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 2px var(--color-text-on-action),
              0 0 0 4px var(--color-focus-ring);
}
.attachment__remove > svg {
  width: 12px;
  height: 12px;
}

/* ----- Layout: thumb on top, body below (the only layout) ----- */
.attachment {
  flex-direction: column;
  padding: var(--space-5); /* 10px */
  gap: var(--space-5);
}
.attachment .attachment__thumb {
  width: 100%;
  height: 80px;
}

/* ----- Thumb color modifiers by file type ----- */
.attachment__thumb--doc {
  background: var(--color-blue-pale);
  color: var(--color-blue-dark);
}
.attachment__thumb--pdf {
  background: var(--color-red-pale);
  color: var(--color-red-dark);
}
.attachment__thumb--image {
  background: var(--color-green-pale);
  color: var(--color-green-dark);
}
.attachment__thumb--video {
  background: var(--color-purple-pale);
  color: var(--color-purple);
}
.attachment__thumb--audio {
  background: var(--color-yellow-pale);
  color: var(--color-yellow);
}
.attachment__thumb--archive {
  background: var(--color-bg-off);
  color: var(--color-text-secondary);
}
/* --other / default: no modifier needed; the base __thumb rule
   already provides the neutral fallback. */


/* ===========================================================
   31. EMAIL ATTACHMENT — .email-attachment
   Visual reference: Email Thread View — attached files in
   the email body (e.g., "Quote-RT-2026-0412.pdf · 184 KB").

   Compact row-style attachment for files attached to emails.
   Distinct from .attachment (Component #30) — the email
   variant is denser, has a paperclip indicator, and is
   non-removable (you can't un-attach a sent email).

   Lives inside .email-message__attachments, which flex-wraps
   so multiple attachments flow horizontally and wrap when
   the row is full.

   Anatomy:
     __icon       — colored file-icon box (left)
     __body       — wrapper for filename + size
     __name       — filename text
     __size       — file size text
     __indicator  — paperclip icon (right)

   Modifiers on __icon (same color contract as .attachment__thumb):
     --doc     blue
     --pdf     red
     --image   green
     --video   purple
     --audio   yellow
     --archive neutral
     (no modifier — neutral fallback for unknown file types)

   States:
     none — interaction is hover/click on the whole row
     (download/open).
   =========================================================== */

.email-attachment {
  display: inline-flex;
  align-items: center;
  gap: var(--space-5); /* 10px */
  padding: var(--space-4) var(--space-5); /* 8 10 */
  max-width: 320px;
  background: var(--color-bg-off);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-sm);
  font-family: var(--font-body);
  color: var(--color-text);
  cursor: pointer;
  text-decoration: none;
  transition:
    background-color var(--duration-base) var(--easing-default),
    border-color var(--duration-base) var(--easing-default);
}
.email-attachment:hover {
  background: var(--color-bg);
  border-color: var(--color-border-hover);
}
.email-attachment:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px var(--color-focus-ring);
  border-color: var(--color-blue);
}

/* ----- __icon: file-icon box (left) ----- */
.email-attachment__icon {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--color-bg-off); /* default neutral fallback */
  color: var(--color-text-secondary);
  border-radius: 6px;
}
.email-attachment__icon > svg {
  width: 18px;
  height: 18px;
  color: currentColor;
}

/* ----- __body: filename + size stack ----- */
.email-attachment__body {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1;
}

.email-attachment__name {
  font-size: var(--font-size-small); /* 13px */
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.email-attachment__size {
  font-size: var(--font-size-micro); /* 11px */
  font-weight: var(--font-weight-regular);
  color: var(--color-text-dim);
  line-height: 1.3;
  margin-top: 1px;
}

/* ----- __indicator: paperclip icon (right) ----- */
.email-attachment__indicator {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-left: var(--space-5); /* 10px — extra breathing room between
                                  the filename and the paperclip beyond
                                  the parent's flex gap */
  color: var(--color-text-dim);
}
.email-attachment__indicator > svg {
  width: 16px;
  height: 16px;
}

/* ----- File-type icon color modifiers ----- */
.email-attachment__icon--doc {
  background: var(--color-blue-pale);
  color: var(--color-blue-dark);
}
.email-attachment__icon--pdf {
  background: var(--color-red-pale);
  color: var(--color-red-dark);
}
.email-attachment__icon--image {
  background: var(--color-green-pale);
  color: var(--color-green-dark);
}
.email-attachment__icon--video {
  background: var(--color-purple-pale);
  color: var(--color-purple);
}
.email-attachment__icon--audio {
  background: var(--color-yellow-pale);
  color: var(--color-yellow);
}
.email-attachment__icon--archive {
  background: var(--color-bg-off);
  color: var(--color-text-secondary);
}


/* ===========================================================
   32. TASK TABLE — .task-table
   Visual reference: Task Detail subtasks list; Contact Detail
   and Property Detail related-tasks lists (the cdv-tasktbl
   pattern in the source designs).

   NOT to be used on the main Task List screen — that page
   uses a different, denser visual treatment.

   Tabular layout with sortable column headers and rows of
   task data. Built on a real <table> element for semantic
   correctness and screen-reader compatibility.

   Anatomy:
     .task-table              — the <table> root
     .task-table thead        — header row container
     .task-table tbody        — body row container
     .task-table__header-cell — sortable column header (a <th>)
     .task-table__header-label — text label inside header cell
     .task-table__sort-icon   — sort direction arrow (SVG)
     .task-table__row         — body <tr>
     .task-table__cell        — body <td>

   Cell modifiers (apply per column to control width / alignment
   / typography):
     --checkbox  — narrow column, checkbox-only
     --name      — task name, primary-weight text, flex-grows
     --status    — composes .status-dot + label text
     --time      — duration estimate (e.g., "10 wks")
     --assignee  — assignee name or "Unassigned"
     --due       — due date with calendar icon, or em-dash if none

   Row states:
     .is-done     — task completed (strikethrough name, dim text)
     .is-selected — subtle blue tint background

   Header cell states:
     .is-sorted      — column is the current sort key (shows arrow)
     .is-sorted-desc — sort is descending (rotates arrow)

   Cell states:
     .task-table__cell--due.is-overdue — red text, semibold

   Status pattern:
     The status cell composes .status-dot:
       <td class="task-table__cell task-table__cell--status">
         <span class="status-dot status-dot--success"></span>
         Completed
       </td>
     No new status classes needed — uses existing primitive.
   =========================================================== */

.task-table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-body);
  font-size: var(--font-size-small); /* 13px */
  color: var(--color-text);
}

/* ----- Header row ----- */
.task-table thead th {
  padding: var(--space-3) var(--space-6) var(--space-4); /* 6 12 8 */
  border-bottom: 1px solid var(--color-border-light);
  text-align: left;
  white-space: nowrap;
  font-size: var(--font-size-micro); /* 11px */
  font-weight: var(--font-weight-medium);
  color: var(--color-text-dim);
  vertical-align: middle;
}

.task-table__header-cell {
  /* Inherits from `thead th` above; this class is here as a
     hook so pages can target sortable cells specifically. */
}

/* When a header is sortable, wrap its content in a button so
   keyboard users can activate the sort. The button strips its
   own visual treatment to inherit the th styling. */
.task-table__header-cell button {
  background: transparent;
  border: 0;
  padding: 0;
  font: inherit;
  color: inherit;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2); /* 4px */
  text-transform: inherit;
  letter-spacing: inherit;
}
.task-table__header-cell button:hover {
  color: var(--color-text);
}
.task-table__header-cell button:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px var(--color-focus-ring);
  border-radius: var(--radius-xs);
}

.task-table__header-label {
  /* Hook only; styled by parent button. */
}

.task-table__sort-icon {
  display: none; /* shown only when .is-sorted is on the parent header cell */
  width: 12px;
  height: 12px;
  flex-shrink: 0;
  transition: transform var(--duration-fast) var(--easing-default);
}
.task-table__header-cell.is-sorted {
  color: var(--color-text);
}
.task-table__header-cell.is-sorted .task-table__sort-icon {
  display: inline-block;
}
.task-table__header-cell.is-sorted-desc .task-table__sort-icon {
  transform: rotate(180deg);
}

/* ----- Body rows ----- */
.task-table tbody tr {
  border-bottom: 1px solid var(--color-border-light);
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--easing-default);
}
.task-table tbody tr:last-child {
  border-bottom: 0;
}
.task-table tbody tr:hover {
  background: var(--color-bg-hover);
}

.task-table__row.is-selected {
  background: var(--color-blue-glow);
}
.task-table__row.is-selected:hover {
  background: var(--color-blue-glow); /* keep on hover */
}

/* Done state — strikes through the task name and dims the row. */
.task-table__row.is-done .task-table__cell--name {
  text-decoration: line-through;
  color: var(--color-text-dim);
  font-weight: var(--font-weight-regular);
}
.task-table__row.is-done .task-table__cell {
  color: var(--color-text-dim);
}

/* ----- Body cells ----- */
.task-table__cell {
  padding: var(--space-5) var(--space-6); /* 10 12 */
  vertical-align: middle;
}

/* Cell modifiers by column ---------------------------------- */

/* Checkbox cell — narrow, just holds the checkbox. */
.task-table__cell--checkbox {
  width: 40px;
  padding-right: 0;
}

/* Name cell — primary text, semibold, flex-grows by default. */
.task-table__cell--name {
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
  /* Pages can add max-width if needed; default lets it grow. */
}

/* Status cell — composes .status-dot. Cell itself just lays out. */
.task-table__cell--status {
  white-space: nowrap;
  color: var(--color-text-secondary);
}
.task-table__cell--status .status-dot {
  margin-right: var(--space-3); /* 6px between dot and label */
  vertical-align: -1px;
}

/* Time cell (duration estimate) — secondary text, no wrap. */
.task-table__cell--time {
  white-space: nowrap;
  color: var(--color-text-secondary);
}

/* Assignee cell — primary text by default; pages can render
   "Unassigned" with __cell--assignee.is-unassigned to dim it. */
.task-table__cell--assignee {
  white-space: nowrap;
  color: var(--color-text);
}
.task-table__cell--assignee.is-unassigned {
  color: var(--color-text-secondary);
  font-weight: var(--font-weight-regular);
}

/* Due cell — calendar icon + date. Default is dim (no due
   set). Has-value adds normal text color; overdue is red. */
.task-table__cell--due {
  white-space: nowrap;
  color: var(--color-text-dim);
  font-weight: var(--font-weight-regular);
}
.task-table__cell--due svg {
  width: 14px;
  height: 14px;
  margin-right: var(--space-2); /* 4px */
  vertical-align: -2px;
  color: var(--color-text-dim);
}
.task-table__cell--due.has-value {
  color: var(--color-text);
  font-weight: var(--font-weight-medium);
}
.task-table__cell--due.has-value svg {
  color: var(--color-text-dim);
}
.task-table__cell--due.is-overdue {
  color: var(--color-red);
  font-weight: var(--font-weight-semibold);
}
.task-table__cell--due.is-overdue svg {
  color: var(--color-red);
}


/* ===========================================================
   33. COLLAPSIBLE SECTION — .collapsible-section
   Visual reference: Task Detail "Subtasks" header strip
   (the cdv-sec / cdv-sec-h pattern). Generic clickable header
   strip that sits above page content groups — subtask lists,
   notes lists, files lists, activity lists, etc. The same
   chrome will appear in many places across the product.

   IMPORTANT — scope of this component:
     This component is *only the header strip*. It does NOT
     wrap or render the content below it. The header itself
     does not change visually when its content is collapsed —
     only the chevron rotates as a visual cue.

     Pages are responsible for:
       - Rendering the content below the header
       - Show/hiding that content when the user clicks the head

     The component provides a single state flag (.is-collapsed)
     on the wrapper that rotates the chevron. Pages should
     reuse the same flag to drive their content show/hide,
     so chevron and content stay in sync from one source of
     truth.

   Distinct from:
     .card    — content surface, not header chrome
     .banner  — inline callout, not a section divider
     .tabs    — switches between content; section organizes one

   Anatomy:
     __head     — clickable header strip (the visible chrome)
     __title    — section title text (display font)
     __count    — count pill next to title (e.g., "4")
     __actions  — right-side action cluster (add button + chevron)
     __add      — positioning slot for the add button
                  (composes .btn, e.g., .btn .btn--ghost
                  .btn--icon .btn--sm .collapsible-section__add)
     __chevron  — collapse/expand chevron (a <button>)

   Modifiers:
     --outlined — white background head with visible border
                  (vs default bg-off fill)

   States:
     .is-collapsed — rotates __chevron 90° to indicate the
                     content below (owned by the page) is hidden.
                     Pages key off this same class to hide
                     their own content.

   Accessibility note:
     The __head is intentionally NOT a <button> because it
     contains other buttons (__add, __chevron). Keyboard users
     activate the section by tabbing to __chevron and pressing
     Enter/Space. The whole __head still has cursor: pointer
     and can be clicked to collapse for mouse users.
   =========================================================== */

.collapsible-section {
  width: 100%;
  margin-bottom: var(--space-9); /* 20px between sections */
  font-family: var(--font-body);
}

/* ----- __head: clickable header strip ----- */
.collapsible-section__head {
  display: flex;
  align-items: center;
  gap: var(--space-4); /* 8px */
  padding: var(--space-5) var(--space-7); /* 10 14 */
  background: var(--color-bg-off);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-sm);
  cursor: pointer;
  user-select: none;
  transition: background-color var(--duration-fast) var(--easing-default);
}
.collapsible-section__head:hover {
  background: var(--color-bg-hover);
}

/* ----- __title: section name ----- */
.collapsible-section__title {
  font-family: var(--font-display);
  font-size: var(--font-size-small); /* 13px */
  font-weight: var(--font-weight-semibold);
  line-height: 1.2;
  color: var(--color-text);
  margin: 0;
}

/* ----- __count: count pill next to title ----- */
.collapsible-section__count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  padding: 1px var(--space-3); /* 1px 6px */
  background: var(--color-blue-pale);
  color: var(--color-blue-dark);
  font-size: var(--font-size-micro); /* 11px */
  font-weight: var(--font-weight-bold);
  line-height: 1.4;
  border-radius: var(--radius-pill);
  flex-shrink: 0;
}

/* ----- __actions: right-side action cluster ----- */
.collapsible-section__actions {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: var(--space-1); /* 2px */
  flex-shrink: 0;
}

/* Add button slot — composes .btn. The class adds nothing to
   the styling; it's a hook for selection / future tweaks. */
.collapsible-section__add {
  /* Hook only; visual treatment from .btn modifiers. */
}

/* Chevron toggle button. Rotates when section is collapsed. */
.collapsible-section__chevron {
  width: 26px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  border-radius: var(--radius-xs);
  color: var(--color-text-dim);
  cursor: pointer;
  transition:
    transform var(--duration-fast) var(--easing-default),
    background-color var(--duration-fast) var(--easing-default),
    color var(--duration-fast) var(--easing-default);
}
.collapsible-section__chevron:hover {
  background: var(--color-bg);
  color: var(--color-text);
}
.collapsible-section__chevron:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}
.collapsible-section__chevron > svg {
  width: 14px;
  height: 14px;
}

/* ----- States ----- */
/* .is-collapsed lives on the wrapper. It rotates the chevron
   to indicate the page-owned content below is hidden. The
   component does NOT hide any content itself — pages key off
   this same class to hide their own markup. */
.collapsible-section.is-collapsed .collapsible-section__chevron {
  transform: rotate(-90deg);
}

/* ----- --outlined: white head with visible border ----- */
.collapsible-section--outlined .collapsible-section__head {
  background: var(--color-bg);
  border-color: var(--color-border);
}
.collapsible-section--outlined .collapsible-section__head:hover {
  background: var(--color-bg-hover);
}


/* ===========================================================
   34. SMS COMPOSER POPUP — .sms-composer
   Visual reference: SMS Inbox new-message popup.

   Modal-mounted composer for sending new SMS messages. Used
   on Inbox, Contact Detail, Property Detail, and anywhere
   else the product offers a "send a new SMS" affordance.

   Distinct from .composer (Component #15), which is the
   inline reply composer — no head, no recipient fields, no
   modal frame. The two are separate components because the
   anatomy and surrounding context differ substantially.

   Mounting:
     The component sits inside a .modal__backdrop:
       <div class="modal__backdrop">
         <section class="sms-composer">…</section>
       </div>
     The backdrop handles dim-the-page behavior; the composer
     handles its own surface, chrome, and content.

   Anatomy:
     __head            — header strip (icon + title + close)
     __head-icon       — blue-pale rounded square w/ chat-bubble icon
     __title           — "New Message" display-font heading
     __close           — X close button
     __body            — fields + textarea + counter
     __field           — horizontal row (label left, value right)
     __field-label     — uppercase eyebrow ("FROM" / "TO")
     __field-value     — right side of a field, holds the control
     __field-input     — borderless inline input for To field
     __from-display    — styled From button (icon + text + chevron)
     __from-icon       — phone-icon box inside __from-display
     __from-text       — number + line description stack
     __from-number     — the phone number
     __from-line       — the line label ("Main Line")
     __from-chevron    — dropdown chevron
     __textarea-wrap   — wrapper that gets the focus ring
     __textarea        — the message textarea
     __counter         — char/segment count below textarea
     __foot            — footer strip
     __tools           — left cluster of tool icons (slot)
     __schedule        — Schedule button (composes .btn)
     __send            — Send button (composes .btn)

   States:
     none — focus state on __textarea-wrap is CSS-driven via
     :focus-within. No JS-driven class flips needed.
   =========================================================== */

.sms-composer {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 560px;
  background: var(--color-bg);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xl);
  overflow: hidden;
  font-family: var(--font-body);
  color: var(--color-text);
}

/* ----- __head: header strip ----- */
.sms-composer__head {
  display: flex;
  align-items: center;
  gap: var(--space-5); /* 10px */
  padding: var(--space-7) var(--space-9); /* 14 20 */
  border-bottom: 1px solid var(--color-border-light);
}

.sms-composer__head-icon {
  width: 28px;
  height: 28px;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--color-blue-glow);
  color: var(--color-blue);
  border-radius: var(--radius-sm);
}
.sms-composer__head-icon > svg {
  width: 14px;
  height: 14px;
}

.sms-composer__title {
  flex: 1;
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--font-size-h5); /* 15px — popup-chrome title size */
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-h5);
  letter-spacing: var(--letter-spacing-display);
  color: var(--color-text);
}

.sms-composer__close {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
  color: var(--color-text-dim);
  cursor: pointer;
  transition:
    background-color var(--duration-fast) var(--easing-default),
    color var(--duration-fast) var(--easing-default);
}
.sms-composer__close:hover {
  background: var(--color-bg-hover);
  color: var(--color-text);
}
.sms-composer__close:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}
.sms-composer__close > svg {
  width: 18px;
  height: 18px;
}

/* ----- __body: fields + textarea + counter ----- */
.sms-composer__body {
  display: flex;
  flex-direction: column;
  padding: 0 var(--space-9) var(--space-7); /* 0 20 14 */
}

/* ----- __field: horizontal row (FROM, TO) ----- */
.sms-composer__field {
  display: flex;
  align-items: center;
  gap: var(--space-7); /* 14px between label and value */
  padding: var(--space-7) 0; /* 14px vertical */
  border-bottom: 1px solid var(--color-border-light);
}

.sms-composer__field-label {
  flex-shrink: 0;
  width: 64px;
  font-size: var(--font-size-micro); /* 11px */
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: var(--letter-spacing-uppercase);
  color: var(--color-text-dim);
  line-height: 1;
}

.sms-composer__field-value {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
}

/* Borderless inline input — used for the To field. Styled
   minimally because the field already provides padding and
   the bottom-border row treatment handles separation. */
.sms-composer__field-input {
  flex: 1;
  min-width: 0;
  height: 24px;
  padding: 0;
  background: transparent;
  border: 0;
  outline: 0;
  font-family: var(--font-body);
  font-size: var(--font-size-body);
  font-weight: var(--font-weight-regular);
  color: var(--color-text);
}
.sms-composer__field-input::placeholder {
  color: var(--color-text-dim);
}

/* ----- __from-display: styled From button ----- */
.sms-composer__from-display {
  flex: 1;
  min-width: 0;
  display: inline-flex;
  align-items: center;
  gap: var(--space-5); /* 10px */
  padding: 0;
  background: transparent;
  border: 0;
  cursor: pointer;
  text-align: left;
  color: var(--color-text);
}

.sms-composer__from-icon {
  width: 28px;
  height: 28px;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--color-bg-off);
  color: var(--color-text-secondary);
  border-radius: var(--radius-sm);
}
.sms-composer__from-icon > svg {
  width: 14px;
  height: 14px;
}

.sms-composer__from-text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.sms-composer__from-number {
  font-size: var(--font-size-body); /* 14px */
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sms-composer__from-line {
  font-size: var(--font-size-caption); /* 12px */
  font-weight: var(--font-weight-regular);
  color: var(--color-text-dim);
  line-height: 1.2;
}

.sms-composer__from-chevron {
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  color: var(--color-text-dim);
}

/* ----- __textarea-wrap: focus-ring container ----- */
.sms-composer__textarea-wrap {
  position: relative;
  margin-top: var(--space-7); /* 14px gap below the To field */
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  transition:
    border-color var(--duration-base) var(--easing-default),
    box-shadow var(--duration-base) var(--easing-default);
}
.sms-composer__textarea-wrap:focus-within {
  border-color: var(--color-blue);
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}

.sms-composer__textarea {
  width: 100%;
  min-height: 140px;
  padding: var(--space-6) var(--space-7); /* 12 14 */
  background: transparent;
  border: 0;
  outline: 0;
  resize: vertical;
  font-family: var(--font-body);
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-text);
}
.sms-composer__textarea::placeholder {
  color: var(--color-text-dim);
}

/* ----- __counter: char + segment count ----- */
.sms-composer__counter {
  margin-top: var(--space-3); /* 6px gap above */
  text-align: right;
  font-size: var(--font-size-caption); /* 12px */
  font-weight: var(--font-weight-regular);
  color: var(--color-text-dim);
}

/* ----- __foot: footer strip with tools, schedule, send ----- */
.sms-composer__foot {
  display: flex;
  align-items: center;
  gap: var(--space-5); /* 10px */
  padding: var(--space-6) var(--space-9); /* 12 20 */
  border-top: 1px solid var(--color-border-light);
}

/* Tool cluster — slot for icon buttons. Pages render
   .btn--ghost.btn--icon.btn--sm instances inside. */
.sms-composer__tools {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2); /* 4px */
  flex: 1;
}

/* Schedule button — positioning slot. Composes .btn (typically
   .btn--secondary or .btn--ghost). */
.sms-composer__schedule {
  flex-shrink: 0;
}

/* Send button — positioning slot. Composes .btn--primary. */
.sms-composer__send {
  flex-shrink: 0;
}


/* ===========================================================
   35. EMAIL COMPOSER POPUP — .email-composer-popup
   Visual reference: Email Inbox new-email popup.

   Modal-mounted composer for sending new emails. Sibling of
   .sms-composer (#34) and .email-composer-inline (TBD); same
   structural family, different anatomy specific to email
   (subject line, Cc/Bcc fields, formatting toolbar, send-with-
   dropdown for Schedule/Send-and-compose-another).

   Mounting: same as .sms-composer — sits inside
   .modal__backdrop if dimming is needed:
     <div class="modal__backdrop">
       <section class="email-composer-popup">…</section>
     </div>
   The backdrop dims the page; the popup handles its own
   surface and chrome.

   Anatomy:
     __head            — header strip (icon + title + actions)
     __head-icon       — blue-pale rounded square w/ edit icon
     __title           — "New message" display-font heading
     __head-actions    — right-side cluster (currently just close)
     __close           — X close button

     __body            — fields + textarea
     __field           — horizontal row (From / To / Cc / Bcc / Subject)
     __field-label     — left-side label ("From" / "To" / etc.)
     __field-value     — right side of field, holds control(s)
     __field-input     — borderless inline input (To/Cc/Bcc/Subject)
     __from-display    — styled From row (avatar + name/email + chevron)
     __from-avatar     — slot for an .avatar
     __from-name       — display name
     __from-email      — "<email@domain.com>" dim text
     __from-chevron    — From dropdown chevron
     __cc-link         — "Cc" expand link
     __bcc-link        — "Bcc" expand link
     __textarea        — message body textarea (borderless)

     __foot            — footer area (toolbar + send bar)
     __toolbar         — formatting toolbar strip
     __toolbar-group   — visual group of related buttons
     __word-count      — word count text on the right
     __send-bar        — bottom strip with Send button
     __send            — main Send button (slot, composes .btn--primary)
     __send-toggle     — chevron sub-button to open send menu
     __send-menu       — dropdown panel (Schedule, Send & compose...)
     __send-menu-item  — each item in the menu
     __send-menu-icon  — icon slot inside a menu item

   States:
     .is-send-menu-open — shows __send-menu
   =========================================================== */

.email-composer-popup {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 720px;
  min-height: 600px;
  background: var(--color-bg);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xl);
  overflow: hidden;
  font-family: var(--font-body);
  color: var(--color-text);
}

/* ----- __head: header strip ----- */
.email-composer-popup__head {
  display: flex;
  align-items: center;
  gap: var(--space-5); /* 10px */
  padding: var(--space-7) var(--space-9); /* 14 20 */
  background: var(--color-bg-off);
  border-bottom: 1px solid var(--color-border-light);
}

.email-composer-popup__head-icon {
  width: 28px;
  height: 28px;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--color-blue-glow);
  color: var(--color-blue);
  border-radius: var(--radius-sm);
}
.email-composer-popup__head-icon > svg {
  width: 14px;
  height: 14px;
}

.email-composer-popup__title {
  flex: 1;
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--font-size-h5); /* 15px — popup-chrome title size */
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-h5);
  letter-spacing: var(--letter-spacing-display);
  color: var(--color-text);
}

.email-composer-popup__head-actions {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}

.email-composer-popup__close {
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
  color: var(--color-text-dim);
  cursor: pointer;
  transition:
    background-color var(--duration-fast) var(--easing-default),
    color var(--duration-fast) var(--easing-default);
}
.email-composer-popup__close:hover {
  background: var(--color-bg-hover);
  color: var(--color-text);
}
.email-composer-popup__close:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}
.email-composer-popup__close > svg {
  width: 18px;
  height: 18px;
}

/* ----- __body: fields + textarea ----- */
.email-composer-popup__body {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

/* ----- __field: horizontal row ----- */
.email-composer-popup__field {
  display: flex;
  align-items: center;
  gap: var(--space-7); /* 14px between label and value */
  padding: var(--space-6) var(--space-9); /* 12 20 */
  border-bottom: 1px solid var(--color-border-light);
}

.email-composer-popup__field-label {
  flex-shrink: 0;
  width: 64px;
  font-size: var(--font-size-small); /* 13px */
  font-weight: var(--font-weight-regular);
  color: var(--color-text-dim);
  line-height: 1;
}

.email-composer-popup__field-value {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: var(--space-5); /* 10px between input and trailing icons/links */
}

.email-composer-popup__field-input {
  flex: 1;
  min-width: 0;
  height: 24px;
  padding: 0;
  background: transparent;
  border: 0;
  outline: 0;
  font-family: var(--font-body);
  font-size: var(--font-size-body);
  font-weight: var(--font-weight-regular);
  color: var(--color-text);
}
.email-composer-popup__field-input::placeholder {
  color: var(--color-text-dim);
}

/* ----- __from-display: From row ----- */
.email-composer-popup__from-display {
  flex: 1;
  min-width: 0;
  display: inline-flex;
  align-items: center;
  gap: var(--space-5); /* 10px */
  padding: 0;
  background: transparent;
  border: 0;
  cursor: pointer;
  text-align: left;
  color: var(--color-text);
}

.email-composer-popup__from-avatar {
  flex-shrink: 0;
}

.email-composer-popup__from-name {
  font-size: var(--font-size-body);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
  line-height: 1.2;
  flex-shrink: 0;
}

.email-composer-popup__from-email {
  font-size: var(--font-size-body);
  font-weight: var(--font-weight-regular);
  color: var(--color-text-dim);
  line-height: 1.2;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.email-composer-popup__from-chevron {
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  color: var(--color-text-dim);
  margin-left: auto;
}

/* ----- __cc-link / __bcc-link: expand affordances ----- */
.email-composer-popup__cc-link,
.email-composer-popup__bcc-link {
  flex-shrink: 0;
  padding: 0 var(--space-2);
  background: transparent;
  border: 0;
  font-family: var(--font-body);
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-regular);
  color: var(--color-text-dim);
  cursor: pointer;
  transition: color var(--duration-fast) var(--easing-default);
}
.email-composer-popup__cc-link:hover,
.email-composer-popup__bcc-link:hover {
  color: var(--color-blue);
}

/* ----- __textarea: message body ----- */
.email-composer-popup__textarea {
  flex: 1;
  width: 100%;
  min-height: 240px;
  padding: var(--space-7) var(--space-9); /* 14 20 */
  background: transparent;
  border: 0;
  outline: 0;
  resize: none;
  font-family: var(--font-body);
  font-size: var(--font-size-body);
  line-height: var(--line-height-body-lg);
  color: var(--color-text);
}
.email-composer-popup__textarea::placeholder {
  color: var(--color-text-dim);
}

/* ----- __foot: footer area ----- */
.email-composer-popup__foot {
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--color-border-light);
}

/* ----- __toolbar: formatting strip ----- */
.email-composer-popup__toolbar {
  display: flex;
  align-items: center;
  gap: var(--space-5); /* 10px between groups */
  padding: var(--space-5) var(--space-9); /* 10 20 */
  border-bottom: 1px solid var(--color-border-light);
}

.email-composer-popup__toolbar-group {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1); /* 2px between buttons within a group */
}

.email-composer-popup__word-count {
  margin-left: auto;
  font-size: var(--font-size-caption);
  font-weight: var(--font-weight-regular);
  color: var(--color-text-dim);
  flex-shrink: 0;
}

/* ----- __send-bar: bottom strip with Send button ----- */
.email-composer-popup__send-bar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding: var(--space-6) var(--space-9); /* 12 20 */
  position: relative; /* anchors __send-menu */
}

/* ----- Split Send button (Send + chevron) -----
   Two adjacent buttons styled to merge visually. The main
   __send button uses .btn .btn--primary; __send-toggle is
   a chevron sub-button right next to it. Markup:
     <button class="btn btn--primary email-composer-popup__send">
       <svg/> Send
     </button>
     <button class="btn btn--primary email-composer-popup__send-toggle">
       <svg/>
     </button>
*/
.email-composer-popup__send {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
  /* Provides the rounded-left, flat-right pill shape that
     joins with __send-toggle visually. */
}

.email-composer-popup__send-toggle {
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
  border-left: 1px solid rgba(255, 255, 255, 0.22);
  padding-left: var(--space-4);
  padding-right: var(--space-4);
  /* Flat-left pill, joins with __send via the divider line. */
}

/* ----- __send-menu: dropdown panel ----- */
.email-composer-popup__send-menu {
  position: absolute;
  bottom: calc(100% + var(--space-3)); /* 6px above the bar */
  right: var(--space-9);
  min-width: 240px;
  padding: var(--space-3); /* 6px */
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  display: none;
  z-index: var(--z-popover);
  font-family: var(--font-body);
  font-size: var(--font-size-small);
}
.email-composer-popup.is-send-menu-open .email-composer-popup__send-menu {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.email-composer-popup__send-menu-item {
  display: flex;
  align-items: center;
  gap: var(--space-5); /* 10px */
  width: 100%;
  padding: var(--space-4) var(--space-5); /* 8 10 */
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
  font-family: var(--font-body);
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-medium);
  line-height: 1.2;
  color: var(--color-text);
  text-align: left;
  cursor: pointer;
  transition:
    background-color var(--duration-fast) var(--easing-default),
    color var(--duration-fast) var(--easing-default);
}
.email-composer-popup__send-menu-item:hover {
  background: var(--color-bg-hover);
}
.email-composer-popup__send-menu-item:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}

.email-composer-popup__send-menu-icon {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--color-text-secondary);
}
.email-composer-popup__send-menu-icon > svg {
  width: 16px;
  height: 16px;
}


/* ===========================================================
   36. EMAIL COMPOSER INLINE — .email-composer-inline
   Visual reference: Email Thread View — inline reply
   composer at the bottom of an email thread.

   Inline reply composer that lives at the bottom of an email
   thread (Inbox thread view, Contact / Property / Task detail
   timelines). Sibling of .email-composer-popup (#35) — same
   purpose (composing emails) but different mounting context
   (inline-in-page vs full popup overlay).

   Two visual states (modifier):
     default (no modifier) — full expanded composer
     --collapsed           — single-row strip with avatar +
                             "Reply to X..." placeholder + three
                             mode buttons (Reply / Reply all /
                             Forward); clicking a mode button
                             expands the composer

   Rendering model (display-none, same as .email-message):
     Pages render the full anatomy at all times. The
     --collapsed modifier hides the sub-elements that don't
     belong on the collapsed strip and restructures __modes
     to render as outlined pill buttons on the right.

   Anatomy:
     __avatar          — slot for .avatar (sender avatar)
     __placeholder     — "Reply to X..." text (collapsed only)

     __modes           — top strip: Reply / Reply all / Forward
     __mode            — each mode button
     __collapse        — X button on top-right (expanded only)

     __field           — horizontal row (To, Cc, Bcc)
     __field-label     — "To" / "Cc" / "Bcc" label
     __field-value     — right side of field, holds chip(s) /
                          input + Cc/Bcc links
     __recipient-chip  — recipient pill (avatar + name + X)
     __recipient-avatar — slot for .avatar inside chip
     __recipient-name  — display name
     __recipient-email — email address (dim)
     __recipient-remove — X to remove recipient
     __cc-link         — "Cc" expand link
     __bcc-link        — "Bcc" expand link

     __textarea-wrap   — wrapper for textarea
     __textarea        — the reply textarea

     __foot            — footer strip
     __send-group      — wraps __send + __send-toggle as a single split button
     __send            — main Send button (slot, .btn--primary)
     __send-toggle     — chevron sub-button next to Send
     __send-menu       — dropdown panel
     __send-menu-item  — item inside menu
     __send-menu-icon  — icon slot inside menu item
     __tools           — slot for attachment/format icons
                          (paperclip, image, link, emoji)
     __schedule        — clock icon button (schedule send)
     __discard         — trash icon button (discard draft)

   States:
     __mode.is-active   — soft-blue active reply mode
     .is-send-menu-open — shows __send-menu

   Tokens used: existing tokens only. No new tokens.
   =========================================================== */

.email-composer-inline {
  display: flex;
  flex-direction: column;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  font-family: var(--font-body);
  color: var(--color-text);
}

/* ----- __avatar (visible in collapsed mode only) ----- */
.email-composer-inline__avatar {
  flex-shrink: 0;
}

/* ----- __placeholder (collapsed mode only) ----- */
.email-composer-inline__placeholder {
  flex: 1;
  min-width: 0;
  font-size: var(--font-size-body);
  color: var(--color-text-dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  display: none; /* shown by --collapsed */
}

/* ----- __modes: top strip with mode buttons ----- */
/* In expanded state: a strip across the top with the three
   mode buttons + a close X on the right.
   In collapsed state: outlined pill buttons sitting next to
   the placeholder text. */
.email-composer-inline__modes {
  display: flex;
  align-items: center;
  gap: var(--space-2); /* 4px */
  padding: var(--space-5) var(--space-7); /* 10 14 */
  background: var(--color-bg-off);
  border-bottom: 1px solid var(--color-border-light);
}

.email-composer-inline__mode {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3); /* 6px */
  padding: var(--space-4) var(--space-6); /* 8 12 */
  background: transparent;
  border: 0;
  border-radius: var(--radius-pill);
  font-family: var(--font-body);
  font-size: var(--font-size-small); /* 13px */
  font-weight: var(--font-weight-medium);
  line-height: 1;
  color: var(--color-text-secondary);
  cursor: pointer;
  transition:
    background-color var(--duration-fast) var(--easing-default),
    color var(--duration-fast) var(--easing-default);
}
.email-composer-inline__mode:hover {
  color: var(--color-text);
}
.email-composer-inline__mode:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}
.email-composer-inline__mode > svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}
/* Active mode (expanded state) — soft-blue tint */
.email-composer-inline__mode.is-active {
  background: var(--color-blue-glow);
  color: var(--color-blue);
  font-weight: var(--font-weight-semibold);
}

/* ----- __collapse: top-right close X (expanded only) ----- */
.email-composer-inline__collapse {
  margin-left: auto;
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
  color: var(--color-text-dim);
  cursor: pointer;
  flex-shrink: 0;
  transition:
    background-color var(--duration-fast) var(--easing-default),
    color var(--duration-fast) var(--easing-default);
}
.email-composer-inline__collapse:hover {
  background: var(--color-bg-hover);
  color: var(--color-text);
}
.email-composer-inline__collapse:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}
.email-composer-inline__collapse > svg {
  width: 16px;
  height: 16px;
}

/* ----- __field: horizontal row (To/Cc/Bcc) ----- */
.email-composer-inline__field {
  display: flex;
  align-items: center;
  gap: var(--space-7); /* 14px */
  padding: var(--space-6) var(--space-9); /* 12 20 */
  border-bottom: 1px solid var(--color-border-light);
}

.email-composer-inline__field-label {
  flex-shrink: 0;
  width: 40px;
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-regular);
  color: var(--color-text-dim);
  line-height: 1;
}

.email-composer-inline__field-value {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3); /* 6px between chips and trailing controls */
}

/* ----- __recipient-chip: pill with avatar + name + remove X ----- */
.email-composer-inline__recipient-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3); /* 6px */
  padding: 2px var(--space-2) 2px 2px; /* 2 4 2 2 — tight on left for avatar */
  background: var(--color-bg-off);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-pill);
  max-width: 100%;
  min-width: 0;
}

.email-composer-inline__recipient-avatar {
  flex-shrink: 0;
}

.email-composer-inline__recipient-name {
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
  line-height: 1.2;
  flex-shrink: 0;
}

.email-composer-inline__recipient-email {
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-regular);
  color: var(--color-text-dim);
  line-height: 1.2;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.email-composer-inline__recipient-remove {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  border-radius: 50%;
  color: var(--color-text-dim);
  cursor: pointer;
  margin-left: var(--space-2); /* 4px gap from email */
  transition:
    background-color var(--duration-fast) var(--easing-default),
    color var(--duration-fast) var(--easing-default);
}
.email-composer-inline__recipient-remove:hover {
  background: var(--color-bg-hover);
  color: var(--color-text);
}
.email-composer-inline__recipient-remove > svg {
  width: 11px;
  height: 11px;
}

/* ----- __cc-link / __bcc-link ----- */
.email-composer-inline__cc-link,
.email-composer-inline__bcc-link {
  margin-left: auto;
  flex-shrink: 0;
  padding: 0 var(--space-2);
  background: transparent;
  border: 0;
  font-family: var(--font-body);
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-regular);
  color: var(--color-text-dim);
  cursor: pointer;
  transition: color var(--duration-fast) var(--easing-default);
}
.email-composer-inline__cc-link:hover,
.email-composer-inline__bcc-link:hover {
  color: var(--color-blue);
}
/* When both Cc and Bcc are present, only the first one needs
   the auto-margin push. Subsequent links sit next to it. */
.email-composer-inline__cc-link + .email-composer-inline__bcc-link {
  margin-left: 0;
}

/* ----- __textarea-wrap: container for textarea + quote toggle ----- */
.email-composer-inline__textarea-wrap {
  position: relative;
  display: flex;
  flex-direction: column;
}

.email-composer-inline__textarea {
  width: 100%;
  min-height: 200px;
  padding: var(--space-7) var(--space-9) var(--space-6); /* 14 20 12 */
  background: transparent;
  border: 0;
  outline: 0;
  resize: vertical;
  font-family: var(--font-body);
  font-size: var(--font-size-body);
  line-height: var(--line-height-body-lg);
  color: var(--color-text);
}
.email-composer-inline__textarea::placeholder {
  color: var(--color-text-dim);
}

/* ----- __foot: footer strip ----- */
.email-composer-inline__foot {
  display: flex;
  align-items: center;
  gap: var(--space-5); /* 10px */
  padding: var(--space-6) var(--space-9); /* 12 20 */
  background: var(--color-bg-off);
  border-top: 1px solid var(--color-border-light);
  position: relative; /* anchors __send-menu */
}

/* ----- Split Send button -----
   The Send button and its chevron toggle need to touch (no gap)
   to read as a single split button. The parent __foot uses
   flex `gap` for spacing between unrelated controls — wrapping
   the two halves in __send-group isolates them from that gap. */
.email-composer-inline__send-group {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
}

.email-composer-inline__send {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}

.email-composer-inline__send-toggle {
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
  border-left: 1px solid rgba(255, 255, 255, 0.22);
  padding-left: var(--space-4);
  padding-right: var(--space-4);
}

/* ----- __send-menu: dropdown panel above send button ----- */
.email-composer-inline__send-menu {
  position: absolute;
  bottom: calc(100% + var(--space-3));
  left: var(--space-9); /* aligns with Send button on the left */
  min-width: 240px;
  padding: var(--space-3);
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  display: none;
  z-index: var(--z-popover);
  font-family: var(--font-body);
  font-size: var(--font-size-small);
}
.email-composer-inline.is-send-menu-open .email-composer-inline__send-menu {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.email-composer-inline__send-menu-item {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  width: 100%;
  padding: var(--space-4) var(--space-5);
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
  font-family: var(--font-body);
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-medium);
  line-height: 1.2;
  color: var(--color-text);
  text-align: left;
  cursor: pointer;
  transition:
    background-color var(--duration-fast) var(--easing-default),
    color var(--duration-fast) var(--easing-default);
}
.email-composer-inline__send-menu-item:hover {
  background: var(--color-bg-hover);
}
.email-composer-inline__send-menu-item:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}

.email-composer-inline__send-menu-icon {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--color-text-secondary);
}
.email-composer-inline__send-menu-icon > svg {
  width: 16px;
  height: 16px;
}

/* ----- __tools: cluster of attachment/format icons ----- */
.email-composer-inline__tools {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1); /* 2px */
}

/* ----- __schedule / __discard: right-side icon buttons ----- */
.email-composer-inline__schedule,
.email-composer-inline__discard {
  flex-shrink: 0;
}
/* Push schedule and discard to the right */
.email-composer-inline__tools + .email-composer-inline__schedule {
  margin-left: auto;
}


/* ===========================================================
   --collapsed: single-row strip layout
   ===========================================================
   Pages render full anatomy; this modifier hides everything
   that doesn't belong on a collapsed strip and restructures
   __modes to render as outlined pills next to the placeholder.

   What the modifier does:
     - Hides __collapse, __field, __textarea-wrap, __foot.
     - Reveals __placeholder.
     - Restructures __modes: removes background, removes border,
       drops out of strip layout, lets pills sit inline.
     - Modes get an outlined-pill treatment (border) since they
       no longer have a tinted strip background to set them off.
     - Wraps __avatar + __placeholder + __modes in a single row.
   =========================================================== */
.email-composer-inline--collapsed {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: var(--space-5); /* 10px */
  padding: var(--space-5) var(--space-7); /* 10 14 */
}

.email-composer-inline--collapsed .email-composer-inline__placeholder {
  display: block;
}

/* In collapsed mode, the modes strip becomes an inline cluster
   of outlined pills. */
.email-composer-inline--collapsed .email-composer-inline__modes {
  background: transparent;
  border: 0;
  padding: 0;
  gap: var(--space-3); /* 6px between mode pills */
  flex-shrink: 0;
}
.email-composer-inline--collapsed .email-composer-inline__mode {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  padding: var(--space-3) var(--space-5); /* 6 10 */
}
.email-composer-inline--collapsed .email-composer-inline__mode:hover {
  border-color: var(--color-border-hover);
  color: var(--color-text);
}

/* Hide everything not used in collapsed mode */
.email-composer-inline--collapsed .email-composer-inline__collapse,
.email-composer-inline--collapsed .email-composer-inline__field,
.email-composer-inline--collapsed .email-composer-inline__textarea-wrap,
.email-composer-inline--collapsed .email-composer-inline__foot {
  display: none;
}

/* Suppress send-menu in collapsed mode even if state class
   somehow lingers */
.email-composer-inline--collapsed.is-send-menu-open .email-composer-inline__send-menu {
  display: none;
}


/* ===========================================================
   37. TASK ITEM — .task-item
   Visual reference: Email Thread View / SMS Inbox right
   sidebar — "Open Tasks" cards.

   Card-style task representation that lives in vertical
   stacks inside collapsible sections on right sidebars.
   Used for related tasks, open tasks, etc.

   Distinct from .task-table (Component #32). They serve
   different layout needs — the table for dense tabular
   review (detail page subtasks), the item for sparse
   sidebar context. Do NOT combine them.

   Note: this component does NOT include a checkbox. Tasks
   in sidebars are read-references to tasks elsewhere; the
   sidebar isn't where you mark them done.

   Anatomy:
     __title  — task title text (top)
     __meta   — status + due row (bottom)
     __status — status (.status-dot + label text)
     __due    — due date text

   Modifiers on __status (label color matches the dot):
     --success  — green ("New")
     --info     — blue ("Working")
     --warning  — yellow
     --danger   — red
     --neutral  — grey (default)

   States:
     __due.is-overdue — red, semibold
   =========================================================== */

.task-item {
  display: flex;
  flex-direction: column;
  gap: var(--space-3); /* 6px between title and meta */
  padding: var(--space-6) var(--space-7); /* 12 14 */
  background: var(--color-bg-off);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-family: var(--font-body);
  color: var(--color-text);
  transition:
    background-color var(--duration-fast) var(--easing-default),
    border-color var(--duration-fast) var(--easing-default);
}
.task-item:hover {
  background: var(--color-bg-hover);
  border-color: var(--color-border);
}
.task-item:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}

/* Stacking: provides spacing between adjacent task items.
   Pages don't need a flex-gap parent — items handle their
   own bottom spacing. Last item drops the margin. */
.task-item + .task-item {
  margin-top: var(--space-4); /* 8px */
}

/* ----- __title: task title ----- */
.task-item__title {
  font-size: var(--font-size-body); /* 14px */
  font-weight: var(--font-weight-semibold);
  line-height: 1.3;
  color: var(--color-text);
}

/* ----- __meta: status + due row ----- */
.task-item__meta {
  display: flex;
  align-items: center;
  font-size: var(--font-size-caption); /* 12px */
  font-weight: var(--font-weight-medium);
  line-height: 1.3;
}

/* ----- __status: dot + colored label ----- */
.task-item__status {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2); /* 4px between dot and label */
  color: var(--color-text-secondary); /* default neutral */
  flex-shrink: 0;
}
.task-item__status .status-dot {
  /* Dot color comes from .status-dot's own modifier. */
}

/* Status color modifiers — color the label text to match
   the dot. The dot itself gets its color from its own
   .status-dot--* modifier. Pages should keep these in sync. */
.task-item__status--success {
  color: var(--color-green);
}
.task-item__status--info {
  color: var(--color-blue);
}
.task-item__status--warning {
  color: var(--color-yellow);
}
.task-item__status--danger {
  color: var(--color-red);
}
.task-item__status--neutral {
  color: var(--color-text-secondary);
}

/* ----- __due: due date text ----- */
.task-item__due {
  color: var(--color-text-dim);
  flex-shrink: 0;
}
/* Middle-dot separator between status and due. Generated
   by ::before so the markup stays clean. */
.task-item__due::before {
  content: "·";
  margin: 0 var(--space-3); /* 0 6px */
  color: var(--color-text-dim);
}

/* Overdue state — red, semibold to draw attention. */
.task-item__due.is-overdue {
  color: var(--color-red);
  font-weight: var(--font-weight-semibold);
}


/* ===========================================================
   38. NOTE ITEM — .note-item
   Visual reference: Email Thread View / SMS Inbox right
   sidebar — "Notes" cards.

   Card-style note representation that lives in vertical
   stacks inside collapsible sections on right sidebars.
   Used for contact notes, property notes, task notes — any
   place where notes attached to an entity render as a list.

   Mirrors .task-item's surface treatment and stacking
   convention so sidebar cards stay visually consistent.

   Note: the source designs used a cream/yellow note treatment
   (cs-note pattern). Current design moves notes to the same
   neutral off-white surface used by .task-item — a deliberate
   design evolution. The .modal--note variant still uses the
   cream palette for full-screen note modals.

   Anatomy:
     __head    — top row: author + timestamp
     __avatar  — slot for .avatar (typically .avatar--xs/sm)
     __actor   — author name
     __time    — timestamp text (right-aligned, dim)
     __body    — note body text (multi-line, free-form)

   Modifiers: none

   States: none
   =========================================================== */

.note-item {
  display: flex;
  flex-direction: column;
  gap: var(--space-3); /* 6px between head and body */
  padding: var(--space-6) var(--space-7); /* 12 14 */
  background: var(--color-bg-off);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-family: var(--font-body);
  color: var(--color-text);
  transition:
    background-color var(--duration-fast) var(--easing-default),
    border-color var(--duration-fast) var(--easing-default);
}
.note-item:hover {
  background: var(--color-bg-hover);
  border-color: var(--color-border);
}
.note-item:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}

/* Stacking — same convention as .task-item. */
.note-item + .note-item {
  margin-top: var(--space-4); /* 8px */
}

/* ----- __head: author + timestamp ----- */
.note-item__head {
  display: flex;
  align-items: center;
  gap: var(--space-3); /* 6px between avatar and actor */
}

.note-item__avatar {
  flex-shrink: 0;
}

.note-item__actor {
  font-size: var(--font-size-small); /* 13px */
  font-weight: var(--font-weight-semibold);
  line-height: 1.2;
  color: var(--color-text);
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.note-item__time {
  font-size: var(--font-size-caption); /* 12px */
  font-weight: var(--font-weight-regular);
  line-height: 1.2;
  color: var(--color-text-dim);
  flex-shrink: 0;
}

/* ----- __body: note text ----- */
.note-item__body {
  font-size: var(--font-size-small); /* 13px */
  font-weight: var(--font-weight-regular);
  line-height: 1.45;
  color: var(--color-text);
  /* Free-form text — pages can render plain text or rich
     content. The component sets baseline typography. */
}


/* ===========================================================
   39. TEAMCHAT THREAD — .teamchat-thread
   Visual reference: SMS Inbox / Email Inbox — TeamChat
   block (purple-themed thread) that appears inline within
   message and email lists.

   A self-contained purple-tinted block representing a
   TeamChat conversation attached to an SMS message or
   email. Lives between regular messages/emails in the
   thread view. Includes a label, a stack of messages, and
   a composer at the bottom.

   Distinct from .message (SMS bubble) and .email-message
   (full email). Distinct from any of the four standalone
   composers (.composer / .sms-composer / .email-composer-
   popup / .email-composer-inline) — the teamchat composer
   is purple-themed, smaller, and only appears inside this
   block, so it lives here as a sub-element rather than a
   separate component.

   Anatomy:
     __label        — top label strip (icon + "TEAMCHAT — …")
     __label-icon   — speech-bubble icon in the label

     __messages     — vertical stack of teamchat messages
     __message      — each individual message row
     __avatar       — slot for .avatar (sender avatar)
     __main         — wrapper for byline + body
     __byline       — actor name + timestamp line
     __byline-time  — italic timestamp portion
     __body         — message text
     __mention      — @mention pill inside body (blue)

     __composer     — input row at bottom
     __input        — text input with purple focus
     __emoji        — emoji icon button
     __send         — Send button (slot, composes .btn--primary)

   States:
     .is-flash — brief purple glow when a new message arrives
                 (typically toggled by JS, removed after ~600ms)

   Tokens: uses existing tokens where possible. Several
   purple shades are inlined because the token palette
   currently lacks the fuller --color-purple-{glow,pale,deep}
   range used here. See decisions doc for follow-up to
   expand the purple palette.
   =========================================================== */

.teamchat-thread {
  display: flex;
  flex-direction: column;
  gap: var(--space-5); /* 10px */
  padding: var(--space-7) var(--space-8) var(--space-6); /* 14 16 12 */
  background: linear-gradient(180deg, #FAF7FF 0%, #F6F1FE 100%);
  border: 1px solid #E9E2FB;
  border-radius: var(--radius);
  font-family: var(--font-body);
  color: var(--color-text);
  transition:
    box-shadow var(--duration-slow) var(--easing-default),
    border-color var(--duration-slow) var(--easing-default);
}

/* Flash state — brief purple glow when a new message arrives. */
.teamchat-thread.is-flash {
  border-color: #A78BFA;
  box-shadow: 0 0 0 3px rgba(167, 139, 250, 0.25);
}

/* ----- __label: top label strip ----- */
.teamchat-thread__label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3); /* 6px */
  padding-bottom: 2px;
  font-family: var(--font-body);
  font-size: 10.5px;
  font-weight: var(--font-weight-bold);
  line-height: 1;
  letter-spacing: var(--letter-spacing-uppercase);
  text-transform: uppercase;
  color: #6D28D9; /* purple-dark */
}

.teamchat-thread__label-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--color-purple);
}
.teamchat-thread__label-icon > svg {
  width: 12px;
  height: 12px;
}

/* ----- __messages: stack of message rows ----- */
.teamchat-thread__messages {
  display: flex;
  flex-direction: column;
  gap: var(--space-5); /* 10px between messages */
}

.teamchat-thread__message {
  display: flex;
  align-items: flex-start;
  gap: var(--space-5); /* 10px */
}

.teamchat-thread__avatar {
  flex-shrink: 0;
  margin-top: var(--space-7); /* 14px — aligns avatar with the body line */
}

.teamchat-thread__main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

/* ----- __byline: actor + timestamp ----- */
.teamchat-thread__byline {
  font-size: var(--font-size-micro); /* 11px */
  font-weight: var(--font-weight-medium);
  line-height: 1.3;
  color: var(--color-text-dim);
}

.teamchat-thread__byline-time {
  font-style: italic;
  font-weight: var(--font-weight-regular);
  color: var(--color-text-dim);
}

/* ----- __body: message text ----- */
.teamchat-thread__body {
  font-family: var(--font-body);
  font-size: 13.5px;
  font-weight: var(--font-weight-semibold);
  line-height: 1.5;
  color: var(--color-text);
}

/* ----- __mention: @mention pill inline in body ----- */
.teamchat-thread__mention {
  color: var(--color-blue);
  font-weight: var(--font-weight-semibold);
  margin-right: var(--space-3); /* 6px — breathing room before message content */
}

/* ----- __composer: input row at bottom ----- */
.teamchat-thread__composer {
  display: flex;
  align-items: center;
  gap: var(--space-4); /* 8px */
  padding-top: var(--space-3); /* 6px */
  margin-top: 2px;
  border-top: 1px solid rgba(124, 58, 237, 0.12);
}

/* ----- __input: text input with purple focus ----- */
.teamchat-thread__input {
  flex: 1;
  min-width: 0;
  height: 34px;
  padding: 0 var(--space-6); /* 0 12px */
  background: var(--color-bg);
  border: 1px solid #D4CCEC;
  border-radius: var(--radius-sm);
  outline: 0;
  font-family: var(--font-body);
  font-size: var(--font-size-small); /* 13px */
  color: var(--color-text);
  transition:
    border-color var(--duration-fast) var(--easing-default),
    box-shadow var(--duration-fast) var(--easing-default);
}
.teamchat-thread__input::placeholder {
  color: var(--color-text-dim);
}
.teamchat-thread__input:focus {
  border-color: #A78BFA; /* purple-light */
  box-shadow: 0 0 0 3px rgba(167, 139, 250, 0.22);
}

/* ----- __emoji: icon button with purple hover ----- */
.teamchat-thread__emoji {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  border-radius: var(--radius-xs);
  color: var(--color-text-dim);
  cursor: pointer;
  transition:
    background-color var(--duration-fast) var(--easing-default),
    color var(--duration-fast) var(--easing-default);
}
.teamchat-thread__emoji:hover {
  background: #F5F3FF; /* purple-glow */
  color: #6D28D9; /* purple-dark */
}
.teamchat-thread__emoji:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px rgba(167, 139, 250, 0.22);
}
.teamchat-thread__emoji > svg {
  width: 15px;
  height: 15px;
}

/* ----- __send: Send button slot ----- */
.teamchat-thread__send {
  flex-shrink: 0;
  /* Composes .btn--primary. Markup:
       <button class="btn btn--primary teamchat-thread__send">Send</button>
  */
}


/* ===========================================================
   40. DROPDOWN — .dropdown
   Visual reference: any anchored floating panel that
   contains menu-style content (action menus, option pickers,
   account switchers, etc.).

   Pure container chrome — white panel with rounded corners,
   subtle border, drop shadow, padding. No item styling.
   Other components (e.g., .action-menu, .option-list) mount
   inside .dropdown and provide their own item structure.

   Positioning:
     The component sets position: absolute; pages provide a
     position: relative parent to anchor against. Default is
     anchored bottom-left (top: 100% + 6px; left: 0). Pages
     override top/bottom/left/right directly when a different
     anchor is needed.

   Width:
     Component does NOT set width. Pages size via wrapper
     class or inline style. Common widths: 220px (action
     menus), 280px (option pickers), 320px (account lists).

   Anatomy: none. Single-element primitive.

   Modifiers: none.

   States: none.
   =========================================================== */

.dropdown {
  position: absolute;
  top: calc(100% + var(--space-3)); /* 6px below the trigger */
  left: 0;
  z-index: var(--z-popover);
  padding: var(--space-3); /* 6px */
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  font-family: var(--font-body);
  color: var(--color-text);
}


/* ===========================================================
   41. ACTION MENU — .action-menu
   Visual reference: Contact / Task / Property Detail "More"
   action dropdown; any kebab/overflow menu where each item
   triggers an action.

   List of action items with optional icons and group dividers.
   The current internal menus on .action-bar, .email-composer-
   popup, and .email-composer-inline duplicate this pattern;
   future refactor will replace those with .action-menu
   instances. (See decisions doc follow-ups.)

   Composition:
     Mounts inside .dropdown for chrome. Markup:
       <div class="dropdown">
         <ul class="action-menu">
           <li><button class="action-menu__item">…</button></li>
           …
         </ul>
       </div>

   Anatomy:
     __item     — each action row (a <button>)
     __icon     — icon slot inside an item (left)
     __label    — label text inside an item
     __divider  — horizontal divider between groups

   Modifiers:
     __item--danger — destructive action (red text, red icon,
                       red-glow hover) for items like
                       "Delete task", "Archive contact"

   States: none — actions fire on click, no persistent state.
   =========================================================== */

.action-menu {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
  font-family: var(--font-body);
}

.action-menu__item {
  display: flex;
  align-items: center;
  gap: var(--space-5); /* 10px */
  width: 100%;
  padding: var(--space-4) var(--space-5); /* 8 10 */
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
  font-family: var(--font-body);
  font-size: var(--font-size-small); /* 13px */
  font-weight: var(--font-weight-medium);
  line-height: 1.2;
  color: var(--color-text);
  text-align: left;
  cursor: pointer;
  transition:
    background-color var(--duration-fast) var(--easing-default),
    color var(--duration-fast) var(--easing-default);
}
.action-menu__item:hover {
  background: var(--color-bg-hover);
}
.action-menu__item:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}
.action-menu__item:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.action-menu__icon {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--color-text-secondary);
}
.action-menu__icon > svg {
  width: 18px;
  height: 18px;
}
.action-menu__item:hover .action-menu__icon {
  color: var(--color-text);
}

.action-menu__label {
  flex: 1;
  min-width: 0;
}

.action-menu__divider {
  height: 1px;
  background: var(--color-border-light);
  margin: var(--space-3) 0; /* 6px vertical */
  border: 0;
  list-style: none;
}

/* Danger modifier — destructive actions */
.action-menu__item--danger {
  color: var(--color-red);
}
.action-menu__item--danger .action-menu__icon {
  color: var(--color-red);
}
.action-menu__item--danger:hover {
  background: var(--color-red-glow);
  color: var(--color-red);
}
.action-menu__item--danger:hover .action-menu__icon {
  color: var(--color-red);
}


/* ===========================================================
   42. OPTION LIST — .option-list
   Visual reference: Task screen status picker — searchable
   dropdown with status-dot per option and a selected
   checkmark. Used for any "pick one value from a list"
   affordance: status pickers, assignee pickers, category
   pickers, tag selectors, etc.

   Composition:
     Mounts inside .dropdown for chrome. Markup:
       <div class="dropdown">
         <div class="option-list">
           <div class="option-list__search">
             <input class="option-list__search-input">
             <button class="option-list__clear">Clear</button>
           </div>
           <ul class="option-list__items">
             <li><button class="option-list__item">…</button></li>
             …
           </ul>
         </div>
       </div>

   Anatomy:
     __search        — search input wrapper at top
     __search-input  — the search <input>
     __clear         — "Clear" reset link button
     __items         — wrapper for the option list (a <ul>)
     __item          — each option row (a <button>)
     __indicator     — left visual cue: slot for .status-dot,
                        an icon, or a color swatch
     __label         — option label text
     __check         — right-side checkmark (shown via .is-selected)

   Modifiers: none

   States:
     __item.is-selected — currently-selected value (shows checkmark,
                           label color shifts to blue)
     __item.is-active   — keyboard-focused or pointer-highlighted
                           (soft-blue background tint)

     Both states co-exist. The selected item is the persistent
     value; the active item is the transient focus/hover.

   Tokens: existing only.
   =========================================================== */

.option-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2); /* 4px between search block and items */
  font-family: var(--font-body);
}

/* ----- __search: search input wrapper ----- */
.option-list__search {
  display: flex;
  flex-direction: column;
  gap: var(--space-2); /* 4px between input and clear link */
  padding: var(--space-2); /* 4px */
}

.option-list__search-input {
  width: 100%;
  height: 32px;
  padding: 0 var(--space-5); /* 0 10px */
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  outline: 0;
  font-family: var(--font-body);
  font-size: var(--font-size-small); /* 13px */
  color: var(--color-text);
  transition:
    border-color var(--duration-fast) var(--easing-default),
    box-shadow var(--duration-fast) var(--easing-default);
}
.option-list__search-input::placeholder {
  color: var(--color-text-dim);
}
.option-list__search-input:focus {
  border-color: var(--color-blue);
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}

.option-list__clear {
  align-self: flex-start;
  padding: 0 var(--space-2);
  background: transparent;
  border: 0;
  font-family: var(--font-body);
  font-size: var(--font-size-caption); /* 12px */
  font-weight: var(--font-weight-medium);
  color: var(--color-blue);
  cursor: pointer;
}
.option-list__clear:hover {
  text-decoration: underline;
}
.option-list__clear:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px var(--color-focus-ring);
  border-radius: var(--radius-xs);
}

/* ----- __items: option list wrapper ----- */
.option-list__items {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

/* ----- __item: each option row ----- */
.option-list__item {
  display: flex;
  align-items: center;
  gap: var(--space-5); /* 10px */
  width: 100%;
  padding: var(--space-4) var(--space-5); /* 8 10 */
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
  font-family: var(--font-body);
  font-size: var(--font-size-small); /* 13px */
  font-weight: var(--font-weight-medium);
  line-height: 1.2;
  color: var(--color-text);
  text-align: left;
  cursor: pointer;
  transition:
    background-color var(--duration-fast) var(--easing-default),
    color var(--duration-fast) var(--easing-default);
}
.option-list__item:hover {
  background: var(--color-bg-hover);
}
.option-list__item:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}
.option-list__item:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* ----- __indicator: left visual cue (dot / icon / swatch) ----- */
.option-list__indicator {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--color-text-secondary);
}
.option-list__indicator > svg {
  width: 16px;
  height: 16px;
}

/* ----- __label: option text ----- */
.option-list__label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ----- __check: right-side selected checkmark ----- */
.option-list__check {
  flex-shrink: 0;
  display: none; /* shown when __item.is-selected */
  align-items: center;
  justify-content: center;
  color: var(--color-blue);
}
.option-list__check > svg {
  width: 16px;
  height: 16px;
}

/* States */
.option-list__item.is-selected {
  color: var(--color-blue);
  font-weight: var(--font-weight-semibold);
}
.option-list__item.is-selected .option-list__check {
  display: inline-flex;
}

.option-list__item.is-active {
  background: var(--color-blue-glow);
}
/* When an item is BOTH active and selected, the active tint
   stays (no need to override). */


/* ===========================================================
   43. TOPBAR — .topbar
   App-level top navigation bar. Contains the logo, primary
   nav, and right-side utilities (notifications, profile).
   System-level alert strip (.topbar__system-banner) renders
   below the topbar as a sibling — both live inside the layout
   wrapper .app__topbar (positioning of .app__topbar itself
   is layout.css's job; this component handles internal layout
   only).

   Distinct from:
     .banner            — inline rounded callout. .topbar__system-banner
                          is a full-width edge-to-edge strip with
                          a different layout contract.
     .nav-sidebar (#3a) — left-rail vertical nav. .topbar is horizontal,
                          app-chrome.
     .action-bar (#29)  — page-level action cluster on a blue pill. The
                          topbar is the white app shell at the top.

   Anatomy:
     __logo               — wrapper for mark + wordmark on the far left
     __logo-mark          — slot for the logo SVG/image
     __logo-text          — wordmark text next to the mark
     __divider            — vertical line separating logo from nav
     __nav                — primary nav list container
     __nav-link           — individual nav link
     __spacer             — flex spacer pushing utils to the right edge
     __utils              — right-side utilities cluster (notifications,
                            profile)
     __notification-bell  — notification icon button
                            (composes .btn .btn--ghost .btn--icon — only
                            adds positioning + the pulse-dot child)
     __notification-pulse — small absolutely-positioned dot for unread
     __profile            — wrapper for avatar trigger + dropdown
     __avatar-trigger     — clickable button surrounding .avatar
     __profile-dropdown   — dropdown panel (composes .dropdown — only
                            adds topbar-specific positioning override:
                            hangs from the right edge instead of left)
     __dropdown-link      — individual link inside the profile dropdown
     __dropdown-divider   — thin horizontal divider between groups

     __system-banner      — full-width alert strip rendered below the
                            topbar. Sibling of .topbar, NOT a child.

   Modifiers (on __system-banner):
     --info     — blue tint
     --warning  — yellow tint
     --danger   — red tint

   States:
     .topbar__nav-link.is-active   — current page indicator
     .topbar__profile.is-open      — dropdown open. Toggled by the
                                     trigger; same pattern as
                                     .email-message.is-info-open.

   Composition notes:
     - .topbar__notification-bell is just a positioning hook — the
       button itself is .btn .btn--ghost .btn--icon. Markup:
         <button class="btn btn--ghost btn--icon topbar__notification-bell"
                 aria-label="Notifications">
           <svg>…</svg>
           <span class="topbar__notification-pulse"></span>
         </button>
     - .topbar__avatar-trigger is the borderless button wrapping
       .avatar. Markup:
         <button class="topbar__avatar-trigger" aria-label="Open menu">
           <span class="avatar avatar--sm">…</span>
         </button>
     - .topbar__profile-dropdown composes .dropdown. The component
       only adds the right: 0 / left: auto override so the dropdown
       hangs from the right edge instead of the left.
   =========================================================== */

.topbar {
  display: flex;
  align-items: center;
  gap: var(--space-9); /* 20px between logo, nav, utils */
  height: 100%;
  width: -webkit-fill-available;
  padding: 0 var(--space-9); /* 0 20 — vertical comes from container */
  background: var(--color-bg);
  border-bottom: 1px solid var(--color-border-light);
  font-family: var(--font-body);
  color: var(--color-text);
}

/* ----- __logo: brand mark + wordmark on the far left ----- */
.topbar__logo {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4); /* 8px */
  flex-shrink: 0;
  text-decoration: none;
  color: inherit;
}

.topbar__logo-img {
  height: 24px;
  width: auto;
}

.topbar__logo-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  flex-shrink: 0;
  /* The mark itself (SVG/image) is provided by the consumer.
     This slot only handles sizing + alignment. */
}
.topbar__logo-mark > svg,
.topbar__logo-mark > img {
  width: 100%;
  height: 100%;
}

.topbar__logo-text {
  font-family: var(--font-display);
  font-size: var(--font-size-h5); /* 15px — chrome scale */
  font-weight: var(--font-weight-bold);
  line-height: 1;
  letter-spacing: var(--letter-spacing-display);
  color: var(--color-text);
  white-space: nowrap;
}

/* ----- __divider: vertical line between logo and nav ----- */
.topbar__divider {
  width: 1px;
  height: 24px;
  flex-shrink: 0;
  background: var(--color-border);
  /* Use as <span class="topbar__divider"></span> between
     __logo and __nav. */
}

/* ----- __nav: primary nav list ----- */
.topbar__nav {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2); /* 4px between nav links */
  flex-shrink: 0;
  /* No <ul> styling assumptions — markup may use <nav> with
     <a> children or <ul><li> with <a>. The flex layout works
     either way. */
}

.topbar__nav-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3); /* 6px between optional icon and label */
  padding: var(--space-4) var(--space-6); /* 8 12 */
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
  font-family: var(--font-body);
  font-size: var(--font-size-body); /* 13px */
  font-weight: var(--font-weight-medium);
  line-height: 1;
  color: var(--color-text-secondary);
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  transition:
    background-color var(--duration-fast) var(--easing-default),
    color var(--duration-fast) var(--easing-default);
}
.topbar__nav-link:hover {
  background: var(--color-bg-hover);
  color: var(--color-text);
}
.topbar__nav-link:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}
.topbar__nav-link.is-active {
  background: var(--color-blue-glow);
  color: var(--color-blue);
  font-weight: var(--font-weight-semibold);
}

/* ----- __spacer: flex spacer ----- */
.topbar__spacer {
  flex: 1;
  min-width: 0;
}

/* ----- __utils: right-side utilities cluster ----- */
.topbar__utils {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3); /* 6px between bell, profile, etc. */
  flex-shrink: 0;
}

/* ----- __notification-bell: positioning hook ----- */
/* The button itself is .btn .btn--ghost .btn--icon. This class
   only adds the relative positioning context for the pulse dot. */
.topbar__notification-bell {
  position: relative;
}

.topbar__notification-pulse {
  position: absolute;
  top: var(--space-3); /* 6px from top */
  right: var(--space-3);
  width: 8px;
  height: 8px;
  background: var(--color-red);
  border: 2px solid var(--color-bg);
  border-radius: 50%;
  pointer-events: none;
  /* The white border lifts the dot off the button's hover bg
     so it stays visible during hover. */
}

/* ----- __profile: avatar trigger + dropdown wrapper ----- */
.topbar__profile {
  position: relative;
  /* Anchors __profile-dropdown's absolute positioning. */
}

.topbar__avatar-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: transparent;
  border: 0;
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: box-shadow var(--duration-fast) var(--easing-default);
}
.topbar__avatar-trigger:hover {
  box-shadow: 0 0 0 2px var(--color-border);
}
.topbar__avatar-trigger:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}
.topbar__profile.is-open .topbar__avatar-trigger {
  box-shadow: 0 0 0 2px var(--color-blue-pale);
}

/* ----- __profile-dropdown: composes .dropdown ----- */
/* .dropdown provides chrome (white surface, border, shadow,
   z-index). This class adds topbar-specific positioning:
   hangs from the right edge of __profile instead of the left. */
.topbar__profile-dropdown {
  left: auto;
  right: 0;
  min-width: 200px;
  padding: var(--space-3); /* 6px — overrides .dropdown's default if needed */
  display: none; /* shown only when parent has .is-open */
}
.topbar__profile.is-open .topbar__profile-dropdown {
  display: block;
}

.topbar__dropdown-link {
  display: flex;
  align-items: center;
  gap: var(--space-4); /* 8px */
  padding: var(--space-4) var(--space-5); /* 8 10 */
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
  font-family: var(--font-body);
  font-size: var(--font-size-small); /* 13px */
  font-weight: var(--font-weight-medium);
  line-height: 1.3;
  color: var(--color-text);
  text-decoration: none;
  cursor: pointer;
  width: 100%;
  text-align: left;
  transition: background-color var(--duration-fast) var(--easing-default);
}
.topbar__dropdown-link:hover {
  background: var(--color-bg-hover);
}
.topbar__dropdown-link:focus-visible {
  outline: 0;
  background: var(--color-bg-hover);
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}
.topbar__dropdown-link > svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  color: var(--color-text-dim);
}

.topbar__dropdown-divider {
  height: 1px;
  margin: var(--space-2) 0; /* 4px top/bottom */
  background: var(--color-border-light);
  border: 0;
  /* Use as <hr class="topbar__dropdown-divider"> */
}

/* ----- __system-banner: full-width strip below the topbar -----
   Sibling of .topbar, NOT a child. Both live inside .app__topbar
   (or whatever container layout.css uses). This is a full-width
   edge-to-edge strip — distinct from .banner (which is a rounded
   inline card with margins). */
.topbar__system-banner {
  display: flex;
  align-items: center;
  gap: var(--space-5); /* 10px */
  padding: var(--space-4) var(--space-9); /* 8 20 */
  font-family: var(--font-body);
  font-size: var(--font-size-small); /* 13px */
  font-weight: var(--font-weight-medium);
  line-height: 1.4;
  border-bottom: 1px solid var(--color-border-light);
  /* Default neutral chrome — modifiers below override bg / color. */
  background: var(--color-bg-off);
  color: var(--color-text);
}

.topbar__system-banner > svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

/* Push trailing actions (buttons, dismiss) to the right. */
.topbar__system-banner > :last-child {
  margin-left: auto;
}

/* Modifiers — semantic color treatments. Map to the same tokens
   .banner uses for visual consistency (info=blue, warning=yellow,
   danger=red), but as full-width strip chrome. */
.topbar__system-banner--info {
  background: var(--color-blue-glow);
  color: var(--color-text);
  border-bottom-color: var(--color-blue-pale);
}
.topbar__system-banner--info > svg {
  color: var(--color-blue);
}

.topbar__system-banner--warning {
  background: var(--color-yellow-glow);
  color: var(--color-text);
  border-bottom-color: var(--color-yellow-pale);
}
.topbar__system-banner--warning > svg {
  color: var(--color-yellow);
}

.topbar__system-banner--danger {
  background: var(--color-red-glow);
  color: var(--color-text);
  border-bottom-color: var(--color-red-pale);
}
.topbar__system-banner--danger > svg {
  color: var(--color-red);
}

/* ----- Responsive: topbar collapses at ≤1000px ----- */
/* Mobile-only dropdown nav items are hidden by default and
   revealed only when the primary nav disappears. */
.topbar__dropdown-link--mobile-only,
.topbar__dropdown-divider--mobile-only {
  display: none;
}

/* Icon-only logo is hidden by default; swapped in on phones. */
.topbar__logo-img--icon {
  display: none;
  height: 32px;
}

@media (max-width: 1000px) {
  /* Primary nav and its separating divider hide — nav moves into the profile dropdown */
  .topbar__nav,
  .topbar__divider {
    display: none;
  }

  .topbar__dropdown-link--mobile-only {
    display: flex;
  }

  .topbar__dropdown-divider--mobile-only {
    display: block;
  }
}

@media (max-width: 640px) {
  .topbar__logo-img--full {
    display: none;
  }

  .topbar__logo-img--icon {
    display: inline-block;
  }
}


/* ===========================================================
   44. URL FIELD — .url-field
   Visual reference: Settings → Basic Information page,
   "Scheduling page URL" and "Your company EveryChat URL" rows.
   Source pattern: .ps-url-field with .ps-url-fix prefix/suffix.

   Input field with a non-editable adornment on one or both
   sides. The adornment displays in monospace on a tinted
   surface, separated from the input by a vertical divider —
   visually communicates "you can't edit this part."

   Use cases:
     - URL slugs:    https://everychat.com/[your-slug]
     - Subdomains:   [your-subdomain].everychat.com
     - Extensions:   [phone] x [extension]
     - Currency:     $ [amount]

   Distinct from:
     .field / .input (#7) — the standard form field with label
                            + bare input. .url-field is a
                            specialized input replacement that
                            slots INSIDE .field (alongside the
                            label and hint chrome).
     .search-input (#12)  — has an inline icon, not a divided
                            adornment slot.

   Anatomy:
     __fix     — prefix or suffix slot (mono font, tinted bg)
     __input   — the editable input (borderless, fills space)

   Modifiers (on __fix):
     --left   — fix sits BEFORE the input (right-side divider)
     --right  — fix sits AFTER the input (left-side divider)

   Composition:
     This component is the input REPLACEMENT, not the whole row.
     Compose with .field for the label / hint chrome:

       <label class="field">
         <span class="field__label">Scheduling page URL</span>
         <div class="url-field">
           <span class="url-field__fix url-field__fix--left">
             https://everychat.com/
           </span>
           <input class="url-field__input" type="text" value="itsmerileyp">
         </div>
         <span class="field__hint">Share this link so customers can book.</span>
       </label>

     Both __fix modifiers can co-exist (prefix AND suffix on the
     same field) — useful for ranges or wrapped values.

   States:
     :hover         — border darkens (whole field reacts as one)
     :focus-within  — blue border + focus ring (whole field
                      reacts when input is focused)
=========================================================== */

.url-field {
  display: flex;
  align-items: stretch;
  width: 100%;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm); /* 8px */
  overflow: hidden; /* prevents __fix bg from bleeding past corners */
  transition:
    border-color var(--duration-fast) var(--easing-default),
    box-shadow var(--duration-fast) var(--easing-default);
}
.url-field:hover {
  border-color: var(--color-border-hover);
}
.url-field:focus-within {
  border-color: var(--color-blue);
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}

/* ----- __fix: prefix or suffix slot ----- */
.url-field__fix {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  padding: var(--space-5) var(--space-6); /* 10 12 */
  background: var(--color-bg-off);
  font-family: var(--font-mono);
  font-size: var(--font-size-small); /* 13px */
  font-weight: var(--font-weight-regular);
  line-height: 1.4;
  color: var(--color-text-dim);
  white-space: nowrap;
  user-select: all; /* one click selects the whole adornment for copy */
}

/* Modifiers — divider sits on the side facing the input. */
.url-field__fix--left {
  border-right: 1px solid var(--color-border);
}
.url-field__fix--right {
  border-left: 1px solid var(--color-border);
}

/* ----- __input: borderless input filling remaining space ----- */
.url-field__input {
  flex: 1;
  min-width: 0; /* allows flex shrinking below content width */
  padding: var(--space-5) var(--space-6); /* 10 12 — matches __fix */
  background: transparent;
  border: 0;
  font-family: var(--font-body);
  font-size: var(--font-size-body); /* 14px */
  font-weight: var(--font-weight-regular);
  line-height: 1.4;
  color: var(--color-text);
}
.url-field__input::placeholder {
  color: var(--color-text-dim);
}
.url-field__input:focus {
  outline: 0;
  /* Focus styling lives on the parent .url-field via :focus-within
      so the whole box reacts as a unit. */
}
.url-field__input:disabled {
  background: transparent;
  color: var(--color-text-dim);
  cursor: not-allowed;
}


/* ===========================================================
   45. SCHEDULING SIDEBAR — .sched-sidebar
   Public-facing scheduling pages. Sticky host-info panel
   shown on the left side of the two-column scheduling layout.
   Displays the host avatar, booking context, appointment
   title, an accent rule, and meta rows (duration, location…).

   Mobile: horizontal row stacked above the main content.
   Tablet+: sticky vertical column, 280px, border-right.
   Desktop: 300px.

   Anatomy:
     __info       — text block (kicker + title)
     __kicker     — "Booking with …" eyebrow label
     __title      — appointment name (h1)
     __accent     — decorative blue rule (tablet+ only)
     __meta       — wrapper for detail rows (hidden mobile)
     __meta-row   — individual detail row: icon + text
     __meta-icon  — icon slot inside a meta row
   =========================================================== */

.sched-sidebar {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: var(--space-6);
  padding: var(--space-6) var(--space-8);
  border-bottom: 1px solid var(--color-border-light);
  flex-shrink: 0;
}

.sched-sidebar__info {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}

.sched-sidebar__kicker {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-caption);
  color: var(--color-text-dim);
  font-weight: var(--font-weight-regular);
  margin: 0;
}

.sched-sidebar__title {
  font-family: var(--font-display);
  font-size: var(--font-size-h4);
  font-weight: var(--font-weight-bold);
  color: var(--color-text);
  margin: 0;
  line-height: 1.2;
  letter-spacing: var(--letter-spacing-h4);
}

.sched-sidebar__accent {
  display: none;
}

.sched-sidebar__meta {
  display: none;
}

@media (min-width: 768px) {
  .sched-sidebar {
    width: 280px;
    flex-shrink: 0;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-6);
    padding: var(--space-12) var(--space-10);
    border-bottom: none;
    border-right: 1px solid var(--color-border-light);
  }

  .sched-sidebar__info {
    gap: var(--space-2);
  }

  .sched-sidebar__kicker {
    font-size: var(--font-size-caption);
  }

  .sched-sidebar__title {
    font-size: var(--font-size-h3);
    letter-spacing: var(--letter-spacing-h3);
    margin-top: var(--space-1);
  }

  .sched-sidebar__accent {
    display: block;
    width: 48px;
    height: 3px;
    background: var(--color-action);
    border-radius: 2px;
    flex-shrink: 0;
  }

  .sched-sidebar__meta {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
  }

  .sched-sidebar__meta-row {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    font-size: var(--font-size-small);
    color: var(--color-text-secondary);
  }

  .sched-sidebar__meta-icon {
    width: 14px;
    text-align: center;
    flex-shrink: 0;
    color: var(--color-text-dim);
  }
}

@media (min-width: 1024px) {
  .sched-sidebar {
    width: 300px;
    padding: var(--space-14) var(--space-12);
  }
}


/* ============================================================
   END — components.css
   ============================================================
   ============================================================
   SUMMARY
   ============================================================

   Component count by category
   ---------------------------
   Action / control          (3): Button, Toggle, Segment
   Selection control         (2): Checkbox, Radio
   Container / surface       (4): Card, Modal, Filter Drawer,
                                  Side Panel
   Navigation                (2): Sidebars (4 canonical), Tabs
   Form / input              (2): Form Field (.field/.input),
                                  Search Input
   Composition               (2): Composer, Email Composer
   Display primitive         (4): Avatar, Chip, Status Dot,
                                  Tooltip
   Feedback / system         (4): Spinner + Loading Overlay,
                                  Banner, Toast, Empty State
   Onboarding / flow         (2): Onboarding Banner, Load More
   Conversation              (2): Message, Message Day Separator
                              ----
                              27 components — 24 from the
                              decisions doc plus .side-panel,
                              .message, and .message-day-separator
                              promoted later (see decisions doc
                              updates below).

   Decisions doc updates needed (component-decisions.md)
   -----------------------------------------------------
   The following changes have been made to the components in
   this file but are NOT yet reflected in component-decisions.md.
   Apply these in the next decisions-doc edit:

   - Component #3 (Sidebars), .profile-sidebar:
     Add canonical sub-elements: __header, __eyebrow, __title.
     These render the eyebrow + display-title block above the
     items (e.g. "SETTINGS / My Account") that ships on every
     Settings page.

   - Component #3 (Sidebars), .scheduling-sidebar:
     (1) Surface changed from dark navy (rail-bg) to white.
         The scheduling editor reads as an editor flow, not a
         Settings page; white surface matches that context.
     (2) Active-state changed from solid-blue fill to soft
         blue-glow background with blue text. Matches the
         visual reference (the scheduling editor in the source
         design).
     (3) Add canonical sub-element: __exit. Positioning slot
         only; the actual button uses .btn composition (e.g.
         .btn.btn--primary.btn--block.scheduling-sidebar__exit).
         Same pattern as .composer__send / .email-composer__send.

   - Component #3 (Sidebars), .form-builder-sidebar:
     Substantively rewritten. This sidebar is a SETTINGS PANEL,
     not a navigation list — it holds live form controls (text
     inputs, toggles, color swatches), not item links.
     (1) Surface: dark navy (--color-rail-bg). Same family as
         .inbox-rail and .profile-sidebar.
     (2) Anatomy replaced. Old: __section / __item / __icon /
         __label / __count. New: __top, __home, __selector,
         __title, __body, __divider, __section-label, __row,
         __row-label, __row-control, __foot. Three of these
         (__home, __selector) are positioning slots that
         compose existing primitives.
     (3) Form controls inside __body use the new --on-rail
         primitive modifiers (see below).

   - New primitive modifiers across multiple components:
     Add `.btn--on-rail`, `.input--on-rail`, `.field--on-rail`,
     `.toggle--on-rail`, `.checkbox--on-rail`, `.radio--on-rail`.
     Each re-skins its parent component for dark-rail surfaces
     (white text, dark fill, translucent borders, light-slate
     placeholders). Composes additively — apply to existing
     components alongside their normal modifiers, e.g.
     `<input class="input input--on-rail">` or
     `<button class="btn btn--secondary btn--icon btn--on-rail">`.
     These should be added to each component's "Modifiers" list
     in the decisions doc.

   - NEW Component #25: .side-panel
     A persistent right-side panel adjacent to main content
     (Inbox contact info, task lists, helpful videos, etc.).
     Distinct from .modal--drawer — no backdrop, content behind
     stays interactive, panel is a layout region rather than a
     transient overlay.

     Anatomy: __head, __title, __close, __body, __foot (all
     optional; pages compose what they need).

     Modifiers: --full (spans full viewport height), default
     (contained — height inherited from parent).

     States: .is-entering, .is-leaving (JS-toggled on
     mount/unmount; same contract as .toast).

     Surface: white background, 1px left border only (top is
     handled by the navigation bar above; right is the page
     edge). Always positioned on the right.

     Content inside is page-specific and composed from existing
     primitives (.avatar, .chip, .btn, etc.). The component is
     chrome only — same model as .card and .modal. Recurring
     content patterns inside side panels (e.g. the
     contact-detail action row, info-with-icon rows, task
     cards) are intentionally NOT promoted to the system at
     this time; revisit when patterns repeat across 2+ pages.

   - NEW Component #26: .message
     Conversation message bubble. Used in SMS Inbox and any
     detail-page thread (Contact, Property, Task) wherever a
     chronological message thread renders.

     Anatomy: __avatar (slot for an .avatar), __bubble (the
     text-holding shape), __bubble-wrap (positioning wrapper
     around bubble + meta inside the grid), __meta (timestamp +
     sender), __actions (hover-only floating action toolbar),
     __task-indicator (cream badge shown when the message has
     been converted to a task).

     Modifiers: --inbound (default; grey bubble, avatar left),
     --outbound (blue bubble, avatar right).

     States: .is-converted-to-task (shows __task-indicator).

     Notes:
     - Bubble has max-width: 70% by default. Pages can override.
     - __actions visibility is purely CSS-driven (parent :hover /
       :focus-within). No JS class toggle needed.
     - __task-indicator visibility is state-driven via the
       .is-converted-to-task class on the parent. The task
       indicator is a state communicator, NOT an action button —
       clicking it (if interactive at all) navigates to the
       linked task; it does not perform conversion.

   - NEW Component #27: .message-day-separator
     Centered uppercase label between groups of messages
     ("MONDAY, APR 13"). No sub-elements, modifiers, or states.
     Sits as a sibling of .message instances in the thread flow.

   - Note on .modal--drawer (Component #2):
     Currently unused in the product. .side-panel (above)
     handles all the side-anchored use cases that previously
     would have used .modal--drawer. Kept in the system anyway
     for a possible future "modal that slides in from the side
     with a backdrop" use case (wizard modals, etc.). No code
     change; leaving as-is. Worth noting in the decisions doc
     that .side-panel and .modal--drawer are distinct things
     and shouldn't be confused.

   TODO stubs (need clearer designs)
   ---------------------------------
   - .modal--full: stub layout (full-viewport with 24px gutter).
     TODO: confirm whether --full means truly edge-to-edge,
        or window-with-gutter as currently implemented

   - .empty-state--inline diagonal-stripe pattern:
     fallback uses repeating-linear-gradient with
     rgba(229, 231, 235, 0.3) (matching --color-border value)
     because no --color-stripe-bg token exists.
     TODO: needs the canonical stripe pattern color

   - .composer__textarea minimum height (64px) and
     .email-composer__body minimum height (240px) are best-
     guess based on source designs; confirm exact values when
     SMS Inbox composer redesign lands.
     TODO: confirm composer min-heights against final
        SMS Inbox / Email Thread View redesigns

   Missing tokens (referenced by decisions doc, not in tokens.css)
   --------------------------------------------------------------
   The decisions doc references many tokens whose names do not
   match tokens.css. For most of these the file resolves to the
   correct existing token (see "Token-mapping notes" at top).
   The list below is the tokens that have no clean equivalent
   and either fall back to a hex value, an inline rgba, or a
   close substitute. Adding these to tokens.css would clean up
   the file:

   1. --color-stripe-bg (diagonal-stripe pattern color for
        .empty-state--inline)
        Currently: inline rgba(229, 231, 235, 0.3)

   2. --color-blue-tone / --color-yellow-tone /
        --color-purple-tone (decorative tones for
        .empty-state__icon--tone-*)
        Currently mapped to *-glow / *-pale combinations,
        which works but conflates "tinted background" with
        "decorative empty-state tone". Worth a separate
        token family if the visual stays decorative-only.

   3. --color-{lifecycle/status/content}-bg (per-modifier
        chip background tokens)
        Currently: chip uses the *-pale token directly as bg
        and a darker matching token as text color. The
        decisions doc lists separate -bg aliases — those don't
        exist in tokens.css. Resolution choice: skip the
        aliases. If the alias layer is desired later, it can
        be added to tokens.css without changing this file.

   4. --shadow-blue-sm / --shadow-blue-md (referenced by .btn
        in the decisions doc)
        Currently mapped to --shadow-button-action-rest /
        --shadow-button-action-hover (the actual names in
        tokens.css). The decisions doc names should probably
        be reconciled with the tokens.css names in a follow-up.

   5. --color-border-dashed (for dashed empty-state border)
        Currently: --color-border. Acceptable, but a slightly
        lighter dashed token (e.g. --color-border-light) might
        read better. Worth a designer pass.

   6. --z-drawer / --z-overlay / --z-tooltip / --z-backdrop
        (referenced by decisions doc)
        Resolved against tokens.css's actual z-scale:
          --z-backdrop / --z-overlay → not present; .modal__
            backdrop uses --z-modal directly
          --z-drawer → mapped to --z-popover
          --z-tooltip → mapped to --z-popover
        Dedicated values would help if drawers and modals ever
        need to coexist.

   7. --transition-fast / --transition-base / --transition-tooltip
        (referenced by decisions doc)
        Resolved to --duration-fast / --duration-base. The
        tooltip's 250ms show delay is implemented as a literal
        transition-delay on parent hover, not a token.

   8. --anim-spin (referenced by .spinner in the decisions doc)
        Implemented inline as @keyframes ec-spin; the tokens
        spec mentions it but tokens.css does not currently
        export an animation timing variable. Acceptable as a
        component-local keyframe, but worth promoting if other
        components animate.

   9. --color-green-focus-ring (for field--success)
        Currently: literal rgba(16, 185, 129, 0.12). tokens.css
        defines --color-focus-ring (blue) and
        --color-focus-ring-danger (red); a green equivalent
        would round out the set.

  10. --color-on-action-subtle (translucent-white tint for
        elements layered on a blue-active background, e.g.
        the count pill on profile-sidebar__item.is-active)
        Currently: literal rgba(255, 255, 255, 0.2)

  11. --color-overlay-soft (very light black overlay used by
        chip__clear hover for a "press down" feel without
        a visible background color)
        Currently: literal rgba(0, 0, 0, 0.06)

   Disagreements between the design guide and the actual designs
   ------------------------------------------------------------
   1. Chip text color
        Guide: chip text = chip semantic color (e.g. lead chip
          text is blue-dark on blue-pale).
        Some source designs (e.g. Contact List filter chips
          when active) use the chip background as a fill and
          white text. The decisions doc clearly says outline is
          for filter chips and solid is for category labels.
        Resolution: implemented per the decisions doc — semantic
          modifiers are solid, filter chips use --outline. If
          the contact list "active filter chip" treatment
          (blue-glow background, blue text, blue border) is
          expected to be reachable, add a `.chip--outline.is-active`
          pattern in a follow-up, or model that as a separate
          state.

   2. Modal body / note dialog [RESOLVED]
        The Email Inbox source HTML (`note-dialog`) used a
        linear-gradient cream background and warm-brown text
        (#FEF9C3 / #FEF3C7 / #FDE68A / #713F12 / #78350F).
        These are now first-class tokens in tokens.css under
        the new "Cream" family (--color-cream, --color-cream-deep,
        --color-cream-border, --color-cream-text, etc.) plus
        the --gradient-note-surface gradient. .modal--note now
        reads correctly as a warm note surface, not a yellow
        warning surface.

   3. Toggle track sizing
        Guide says 36×20 px. Source designs use 40×22 px (the
        ps-switch implementation, which is the visual reference
        in the decisions doc). Implemented at 40×22 to match the
        reference. Consider updating the guide or the size
        modifiers if 36×20 is canonical.

   4. Button height
        Guide rules say "10px vertical · 20px horizontal" padding
        for primary buttons (≈ 36 line-height + padding ≈ 38–40px
        tall). The Profile Settings ps-btn uses 9px / 16px,
        landing at 36px height. Implemented at 36px to match the
        Profile Settings reference (which the decisions doc names
        as canonical). The guide should be reconciled.

   5. Search input background
        Guide says inputs default to white background. The
        Email Inbox / Contact List search bars use a tinted
        --color-bg-off background that switches to white only on
        focus. The decisions doc names Contact List as the
        reference, so .search-input is implemented with the
        bg-off → bg-on-focus pattern. The plain white .input is
        kept for form fields.

   6. Tabs visual reference
        Decisions doc points to "SMS Inbox tabs" as canonical
        for both --underline and --pills variants. SMS Inbox in
        the source designs uses the underline pattern; pills
        appear in Profile Settings (`.ps-tabs`). Both
        implementations here pull from those references — flag
        this if the SMS Inbox redesign produces a different
        pills treatment.
   ============================================================ */
