/* =============================================================================
   HailoCRM — Obsidian aesthetic + liquid glass v2 + themeable accents.
   See base.html for the design-token layer (CSS variables). Chrome reads
   through those tokens so accent colors swap cleanly at runtime.
   ============================================================================= */

/* ---------- Reset & base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; height: 100%; }
body {
  font-family: var(--font-body), 'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  background: var(--bg-deep, #0a0c10);
  color: var(--text-primary, #ECECEE);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
a { color: var(--accent, #2DD4BF); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ──────────────────────────────────────────────────────────────────────
   Global <select> fix (2026-05-19) — every dropdown was rendering with the
   native macOS chrome (gray gradient + up/down stepper arrows) on top of
   our dark UI, which looked completely broken. Strip the native styling
   here, supply a custom chevron via inline SVG data URI, and provide
   dark-glass defaults. Specific rules (.form-row select, .rev-input)
   layer their own padding/borders on top but must NOT use the `background`
   shorthand — that would clobber the chevron image. Use background-color.
   ────────────────────────────────────────────────────────────────────── */
select {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  background-color: rgba(255,255,255,0.04);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='%23ECECEE' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round' opacity='0.65'><polyline points='3,5 6,8 9,5'/></svg>");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 12px 12px;
  border: 1px solid rgba(255,255,255,0.10);
  border-radius: 10px;
  padding: 9px 34px 9px 12px;
  font: inherit;
  font-size: 13px;
  color: #ECECEE;
  cursor: pointer;
  transition: border-color 140ms ease, background-color 140ms ease, box-shadow 140ms ease;
}
select:hover { border-color: rgba(255,255,255,0.18); }
select:focus {
  outline: 0;
  border-color: rgba(45,212,191,0.55);
  background-color: rgba(255,255,255,0.06);
  box-shadow: 0 0 0 3px rgba(45,212,191,0.10);
}
/* The browser draws the native option list — limited styling available,
   but at least the dark fill applies on Linux/Windows Chromium/Firefox.
   macOS Safari/Chrome ignore most of this; the popover stays system-themed,
   which is acceptable as long as the closed control looks right. */
select option {
  background-color: #1a1d24;
  color: #ECECEE;
}
select:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}
h1, h2, h3, h4 {
  font-family: 'Inter', sans-serif;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 0 0 0.5em 0;
}
.page-title {
  font-family: 'Bebas Neue', 'Inter', sans-serif;
  font-weight: 400;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  font-size: 30px;
}

/* ---------- Halo top bar (wing switcher — above everything) ---------- */
.halo-topbar {
  position: relative; z-index: 10;
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 24px;
  background: rgba(13, 15, 20, 0.72);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border-bottom: 1px solid var(--border-faint);
  box-shadow: inset 0 1px 0 var(--rim-top);
  height: 60px;  /* fixed so edit-wing iframe can size itself with top:60px */
}
/* Brand cluster — icon + stacked HAILO/workspace name (2026-05-19).
   The icon is the dock-app SVG, sized to match the 28px row height.
   The wordmark is Bebas (display); the subtitle is small Inter and
   truncates with ellipsis if the workspace name is unusually long
   so the brand block has a stable footprint regardless of name. */
.halo-brand {
  display: flex; align-items: center; gap: 10px;
  flex: 0 0 auto;
  min-width: 0;
  max-width: 280px;
  color: var(--text-primary);
  text-decoration: none;
  transition: opacity 140ms ease;
}
.halo-brand:hover { opacity: 0.85; text-decoration: none; }
.halo-brand-mark {
  width: 30px; height: 30px;
  border-radius: 8px;
  flex: 0 0 30px;
  display: block;
}
.halo-brand-stack {
  display: flex; flex-direction: column;
  line-height: 1;
  min-width: 0;
}
.halo-brand-word {
  font-family: var(--font-display), 'Bebas Neue', sans-serif;
  font-size: 18px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--text-primary);
}
.halo-brand-sub {
  font-size: 10px;
  letter-spacing: 0.02em;
  color: var(--text-tertiary);
  margin-top: 3px;
  max-width: 220px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Obsidian segmented wing switcher.
   The liquid pill (May 2026) was retired — it read too "Tron." This is the
   quiet segmented control that replaced it: each wing is its own dark-glass
   tile, the active one a notch brighter with a hairline top-edge highlight.
   No spring physics, no sliding pill. Hover is a 180ms color cross-fade. */
.halo-wings {
  position: relative;
  display: flex; gap: 3px;
  background: var(--surface-1);
  padding: 5px;
  border-radius: 12px;
  border: 1px solid var(--border-faint);
  box-shadow: inset 0 1px 0 var(--rim-top);
}
.halo-wing-pill {
  /* Retired but kept hidden so we don't break any cached topbar markup
     that still renders the element. Zero visual contribution. */
  display: none !important;
}

.halo-wing {
  position: relative;
  z-index: 1;
  font-family: var(--font-display), 'Bebas Neue', sans-serif;
  font-size: 15px;
  letter-spacing: 0.16em;
  padding: 9px 22px;
  border-radius: 9px;
  color: var(--text-tertiary);
  text-decoration: none;
  transition: background 180ms ease, color 180ms ease;
}
.halo-wing:hover {
  color: var(--text-primary);
  text-decoration: none;
  background: rgba(255, 255, 255, 0.03);
}
.halo-wing.is-active {
  color: var(--text-primary);
  background: rgba(255, 255, 255, 0.055);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.10),
    inset 0 0 0 0.5px var(--border-line);
}
/* Active-wing "rudder" accent — a 2px Beyond Brand teal→purple bar
   floating just inside the bottom edge of the active tile. Signals
   "this is your current steering position" without resurrecting the
   sliding-pill Tron vibe that got retired on 2026-05-19. */
.halo-wing.is-active::after {
  content: "";
  position: absolute;
  left: 14%; right: 14%;
  bottom: 4px;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, #2DD4BF 0%, #A78BFA 100%);
  box-shadow: 0 0 8px rgba(45, 212, 191, 0.45);
}
/* Hide the rudder accent while the pipeline progress bar is active on the
   same tile — otherwise the two horizontal lines crowd each other and
   read as decoration noise instead of "this is steering" + "this is
   making progress". The progress bar takes over the visual job. */
.halo-wing.is-active.is-pipeline-active::after { display: none; }

/* ── Pipeline progress bar (under the Edit wing pill) ──────────────────
   NOTE (2026-05-19): The bar visual itself is OVERRIDDEN in
   hailo_unified.css to render as a pulsating teal halo around the Edit
   wing tile instead of a thin progress bar. We keep the original bar
   styling here as a fallback for pages that don't load the unified
   stylesheet (e.g. legacy embedded views). */
.halo-wing-progress {
  position: absolute;
  left: 10%; right: 10%;
  bottom: 3px;
  height: 3px;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.06);
  overflow: hidden;
  pointer-events: none;
  /* Soft glow so the bar reads as alive even at low widths. */
  box-shadow: 0 0 6px rgba(45, 212, 191, 0.25);
}
.halo-wing-progress[hidden] { display: none !important; }
.halo-wing-progress-fill {
  display: block;
  height: 100%;
  width: 0%;
  border-radius: 3px;
  background: linear-gradient(90deg, #2DD4BF 0%, #A78BFA 100%);
  transition: width 360ms cubic-bezier(.22,.8,.22,1);
  /* Subtle moving shimmer so the bar reads as ACTIVELY progressing even
     when the percent hasn't ticked for a few seconds (e.g. inside a long
     classify-moments stage). */
  background-size: 200% 100%;
  animation: haloProgressShimmer 2.4s linear infinite;
}
@keyframes haloProgressShimmer {
  from { background-position: 0% 0%; }
  to   { background-position: 200% 0%; }
}
.halo-topbar-right {
  flex: 0 0 auto;
  display: flex; align-items: center; gap: 14px;
  font-size: 13px; color: rgba(236,236,238,0.55);
}
.halo-biz { font-weight: 500; opacity: 0.55; }

/* ── Search trigger button (opens Cmd+K) ── */
.halo-search-trigger {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 8px 6px 10px;
  min-width: 220px;
  background: rgba(255,255,255,0.03);
  border: 1px solid rgba(255,255,255,0.06);
  border-radius: 999px;
  color: rgba(236,236,238,0.6);
  font-size: 12px;
  font-family: inherit;
  cursor: pointer;
  transition: background 140ms ease, color 140ms ease, border-color 140ms ease;
}
.halo-search-trigger kbd { margin-left: auto; }
.halo-search-trigger:hover {
  background: rgba(45,212,191,0.10);
  color: #fff;
  border-color: rgba(45,212,191,0.25);
}
.halo-search-trigger svg { opacity: 0.7; }
.halo-search-trigger kbd {
  font-family: ui-monospace, SFMono-Regular, monospace;
  font-size: 10px;
  padding: 2px 5px;
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 4px;
  color: rgba(236,236,238,0.55);
  background: rgba(0,0,0,0.18);
}

/* ── Workspace strip (lifted from the Hailo app's header, 2026-05-18) ── */
.halo-ws {
  display: flex; align-items: center; gap: 10px;
  padding: 4px 10px 4px 4px;
  background: rgba(255,255,255,0.03);
  border: 1px solid rgba(255,255,255,0.06);
  border-radius: 999px;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}
.halo-ws-identity {
  display: flex; align-items: center; gap: 8px;
  padding-right: 6px;
}
/* When the identity block is the settings entry point, mark it as clickable
   and give the avatar a subtle ring on hover so the user feels the affordance.
   `.halo-ws-identity-link` is now a <button> (opens dropdown), not an <a>. */
.halo-ws-identity-link {
  display: inline-flex; align-items: center;
  text-decoration: none;
  cursor: pointer;
  padding: 2px;
  border: none;
  background: transparent;
  border-radius: 999px;
  transition: background 140ms ease;
}
.halo-ws-identity-link:hover,
.halo-ws-identity-link.is-open {
  background: rgba(255,255,255,0.04);
  text-decoration: none;
}
.halo-ws-identity-link:hover .halo-ws-avatar,
.halo-ws-identity-link.is-open .halo-ws-avatar {
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.12),
              0 0 0 2px rgba(45,212,191,0.45),
              0 0 12px rgba(45,212,191,0.35);
}
.halo-ws-avatar {
  transition: box-shadow 160ms ease;
}

/* ── Avatar dropdown menu ──────────────────────────────────────────────
   Anchored to the avatar via the `.halo-avatar-wrap` relative container.
   Visual style mirrors the password modal: glass card, teal/purple accent
   on the header label, subtle hover. "Soon" tags inherit the same look
   used on the Settings index cards so the language is consistent. */
.halo-avatar-wrap {
  position: relative;
  display: inline-flex; align-items: center;
}
.halo-avatar-menu {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  min-width: 240px;
  max-width: 280px;
  padding: 8px;
  /* 2026-05-20 — Tried 0.62 → 0.82 → 0.93 transparency; Cody's verdict
     is that any fade-through hurts readability. Going fully solid;
     backdrop blur removed since there's nothing showing through. */
  background: #14161E;
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 14px;
  box-shadow: 0 20px 48px rgba(0,0,0,0.5),
              inset 0 0 0 1px rgba(255,255,255,0.04);
  z-index: 150;
  animation: halo-avatar-menu-in 140ms ease;
}
.halo-avatar-menu[hidden] { display: none; }
@keyframes halo-avatar-menu-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.halo-avatar-menu-header {
  padding: 8px 10px 10px;
}
.halo-avatar-menu-header-label {
  /* 2026-05-20 — was hard-coded to 'Bebas Neue' (the old wordmark font);
     switched to --font-display (Inter) so it matches the new Hailo
     branding used by .halo-brand-word. Letter-spacing and weight tuned
     for Inter, not the wide-display Bebas. */
  font-family: var(--font-display), 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.01em;
  background: linear-gradient(90deg, #2DD4BF, #A78BFA);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.halo-avatar-menu-header-sub {
  font-size: 12px;
  color: rgba(236,236,238,0.55);
  margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.halo-avatar-menu-sep {
  height: 1px;
  background: rgba(255,255,255,0.06);
  margin: 6px 4px;
}
.halo-avatar-menu-item {
  display: flex; align-items: center; gap: 10px;
  width: 100%;
  padding: 8px 10px;
  background: transparent;
  border: none;
  border-radius: 8px;
  color: rgba(236,236,238,0.85);
  font-size: 13px;
  font-family: inherit;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: background 100ms ease, color 100ms ease;
}
.halo-avatar-menu-item:hover {
  background: rgba(45,212,191,0.10);
  color: #fff;
  text-decoration: none;
}
.halo-avatar-menu-item[disabled],
.halo-avatar-menu-item-quiet {
  cursor: not-allowed;
  color: rgba(236,236,238,0.45);
}
.halo-avatar-menu-item[disabled]:hover {
  background: transparent;
  color: rgba(236,236,238,0.45);
}
.halo-avatar-menu-item-strong {
  color: #5EEAD4;
}
.halo-avatar-menu-item-strong:hover {
  background: rgba(45,212,191,0.18);
  color: #5EEAD4;
}
.halo-avatar-menu-icon {
  flex: 0 0 18px;
  width: 18px; height: 18px;
  display: inline-flex; align-items: center; justify-content: center;
  color: rgba(236,236,238,0.55);
}
.halo-avatar-menu-item:hover .halo-avatar-menu-icon {
  color: #5EEAD4;
}
.halo-avatar-menu-label {
  flex: 1 1 auto;
  min-width: 0;
}
.halo-avatar-menu-chev {
  color: rgba(236,236,238,0.4);
  font-size: 16px; line-height: 1;
}
.halo-avatar-menu-tag {
  display: inline-flex; align-items: center;
  padding: 2px 7px;
  border-radius: 999px;
  font-size: 10px; font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.halo-avatar-menu-tag-soon {
  background: rgba(167,139,250,0.15);
  color: #C4B5FD;
  border: 1px solid rgba(167,139,250,0.28);
}
.halo-ws-avatar {
  width: 28px; height: 28px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, #2DD4BF, #A78BFA);
  color: #0a0a0d;
  font-family: 'Bebas Neue', sans-serif;
  font-size: 14px; letter-spacing: 0.04em;
  overflow: hidden;
  flex: 0 0 auto;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.12);
}
.halo-ws-avatar.has-photo { background: #0a0a0d; }
.halo-ws-avatar img {
  width: 100%; height: 100%; object-fit: cover; display: block;
}
/* .halo-ws-name was removed 2026-05-19 along with the workspace name text. */

/* Mode toggle — Creator (teal) / Customer (purple). On-brand Beyond Brand
   palette: teal track for back-end mode, purple track for client-facing
   mode. Glow follows the active side so the chip reads as branded chrome
   rather than a generic switch. */
.halo-mode-toggle {
  display: flex; align-items: center; gap: 8px;
  cursor: pointer; user-select: none;
  padding: 4px 8px;
  border-radius: 999px;
  transition: background 140ms ease;
}
.halo-mode-toggle:hover { background: rgba(255,255,255,0.04); }
.halo-mode-toggle-track {
  width: 32px; height: 18px;
  background: linear-gradient(135deg, #2DD4BF, #22d3ee);
  border-radius: 9px;
  position: relative;
  box-shadow: 0 0 0 1px rgba(45,212,191,0.35),
              0 0 12px rgba(34,211,238,0.35);
  transition: background 0.2s ease, box-shadow 0.2s ease;
}
.halo-mode-toggle.is-customer .halo-mode-toggle-track {
  background: linear-gradient(135deg, #7c3aed, #a78bfa);
  box-shadow: 0 0 0 1px rgba(167,139,250,0.40),
              0 0 12px rgba(124,58,237,0.40);
}
.halo-mode-toggle-thumb {
  width: 14px; height: 14px;
  background: #fff;
  border-radius: 50%;
  position: absolute; top: 2px; left: 2px;
  transition: transform 0.2s ease;
}
.halo-mode-toggle.is-customer .halo-mode-toggle-thumb {
  transform: translateX(14px);
}
.halo-mode-toggle-label {
  font-size: 11px; font-weight: 600;
  color: rgba(236,236,238,0.75);
  letter-spacing: 0.3px;
  min-width: 56px;
}

/* Bell + gear icon buttons */
.halo-icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px;
  background: transparent;
  border: 1px solid rgba(255,255,255,0.06);
  border-radius: 50%;
  color: rgba(236,236,238,0.75);
  cursor: pointer;
  position: relative;
  transition: background 140ms ease, color 140ms ease, border-color 140ms ease;
  text-decoration: none;
}
.halo-icon-btn:hover {
  background: rgba(255,255,255,0.06);
  border-color: rgba(255,255,255,0.12);
  color: #fff;
  text-decoration: none;
}
/* Bell count badge — replaces the old plain dot. Shows unread count
   (1, 23, "99+") so a glance at the top bar tells you whether anything
   actually needs attention, not just that something does. */
.halo-bell-badge {
  position: absolute; top: -4px; right: -4px;
  min-width: 16px; height: 16px;
  padding: 0 4px;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, #6366f1, #A78BFA);
  border: 1.5px solid rgba(13,15,20,0.95);
  border-radius: 999px;
  color: #fff;
  font-size: 10px; font-weight: 700;
  line-height: 1;
  box-shadow: 0 0 10px rgba(99,102,241,0.55);
  pointer-events: none;
}

/* Status pill — matches Hailo app's set of states */
.halo-status-pill {
  display: flex; align-items: center; gap: 6px;
  padding: 5px 12px 5px 8px;
  border-radius: 20px;
  font-size: 11px; font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.halo-status-dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  flex-shrink: 0;
}
.halo-status-pill.idle { background: rgba(255,255,255,0.04); color: rgba(236,236,238,0.55); }
.halo-status-pill.idle .halo-status-dot { background: rgba(236,236,238,0.45); }
.halo-status-pill.scanning, .halo-status-pill.analyzing_smoothness,
.halo-status-pill.analyzing_focus, .halo-status-pill.analyzing_vision,
.halo-status-pill.classifying_moments, .halo-status-pill.analyzing_audio,
.halo-status-pill.auto_selecting, .halo-status-pill.generating_xml,
.halo-status-pill.deep_classifying, .halo-status-pill.running_full_pipeline,
.halo-status-pill.running_music_sync, .halo-status-pill.music_sync_analyzing,
.halo-status-pill.music_sync_mapping, .halo-status-pill.music_sync_assembling,
.halo-status-pill.music_sync_exporting {
  background: rgba(45,212,191,0.14); color: #5EEAD4;
}
.halo-status-pill.scanning .halo-status-dot,
.halo-status-pill.analyzing_smoothness .halo-status-dot,
.halo-status-pill.analyzing_focus .halo-status-dot,
.halo-status-pill.analyzing_vision .halo-status-dot,
.halo-status-pill.classifying_moments .halo-status-dot,
.halo-status-pill.analyzing_audio .halo-status-dot,
.halo-status-pill.auto_selecting .halo-status-dot,
.halo-status-pill.generating_xml .halo-status-dot,
.halo-status-pill.deep_classifying .halo-status-dot,
.halo-status-pill.running_full_pipeline .halo-status-dot,
.halo-status-pill.running_music_sync .halo-status-dot,
.halo-status-pill.music_sync_analyzing .halo-status-dot,
.halo-status-pill.music_sync_mapping .halo-status-dot,
.halo-status-pill.music_sync_assembling .halo-status-dot,
.halo-status-pill.music_sync_exporting .halo-status-dot {
  background: #2DD4BF;
  animation: halo-pulse-dot 1.5s ease-in-out infinite;
}
.halo-status-pill.complete, .halo-status-pill.scanned,
.halo-status-pill.smoothness_done, .halo-status-pill.focus_done,
.halo-status-pill.vision_done, .halo-status-pill.moments_done,
.halo-status-pill.audio_done, .halo-status-pill.selected,
.halo-status-pill.music_sync_complete {
  background: rgba(52,211,153,0.16); color: #6EE7B7;
}
.halo-status-pill.complete .halo-status-dot,
.halo-status-pill.scanned .halo-status-dot,
.halo-status-pill.smoothness_done .halo-status-dot,
.halo-status-pill.focus_done .halo-status-dot,
.halo-status-pill.vision_done .halo-status-dot,
.halo-status-pill.moments_done .halo-status-dot,
.halo-status-pill.audio_done .halo-status-dot,
.halo-status-pill.selected .halo-status-dot,
.halo-status-pill.music_sync_complete .halo-status-dot {
  background: #34D399;
}
.halo-status-pill.paused, .halo-status-pill.music_sync_error,
.halo-status-pill.error {
  background: rgba(239,68,68,0.16); color: #FCA5A5;
}
.halo-status-pill.paused .halo-status-dot,
.halo-status-pill.music_sync_error .halo-status-dot,
.halo-status-pill.error .halo-status-dot {
  background: #EF4444;
}
@keyframes halo-pulse-dot {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.4; transform: scale(0.8); }
}

/* ── Active project chip ──────────────────────────────────────────────
   Persistent chip in the top bar that shows which project you're
   currently working on. Click to jump to its detail page. The × button
   clears the active project. Hidden by default until a page calls
   window.haloSetActiveProject(...). */
.halo-project-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 4px 5px 10px;
  background: rgba(45,212,191,0.10);
  border: 1px solid rgba(45,212,191,0.28);
  border-radius: 999px;
  color: #5EEAD4;
  font-size: 12px; font-weight: 600;
  text-decoration: none;
  max-width: 220px;
  transition: background 140ms ease, border-color 140ms ease;
}
.halo-project-chip:hover {
  background: rgba(45,212,191,0.18);
  border-color: rgba(45,212,191,0.45);
  color: #5EEAD4;
  text-decoration: none;
}
.halo-project-chip-dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: #2DD4BF;
  box-shadow: 0 0 8px rgba(45,212,191,0.7);
  flex: 0 0 auto;
}
.halo-project-chip-label {
  max-width: 160px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.halo-project-chip-clear {
  width: 18px; height: 18px;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,0.18);
  border: none;
  border-radius: 50%;
  color: rgba(236,236,238,0.7);
  cursor: pointer;
  font-size: 14px; line-height: 1;
  padding: 0;
  transition: background 120ms ease, color 120ms ease;
}
.halo-project-chip-clear:hover {
  background: rgba(239,68,68,0.35);
  color: #fff;
}

/* ── Creator password modal (Customer → Creator gate) ──────────────── */
.halo-mode-pwd-scrim {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(5, 6, 10, 0.72);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
}
.halo-mode-pwd-scrim[hidden] { display: none; }
.halo-mode-pwd-card {
  position: relative;
  overflow: hidden;
  width: 100%; max-width: 420px;
  padding: 40px 36px 28px;
  background: rgba(20, 12, 38, 0.85);
  border: 1px solid rgba(167,139,250,0.35);
  border-radius: 24px;
  backdrop-filter: blur(24px);
  -webkit-backdrop-filter: blur(24px);
  box-shadow: 0 24px 64px rgba(0,0,0,0.5),
              inset 0 0 0 1px rgba(167,139,250,0.06);
  color: #ECECEE;
}
.halo-mode-pwd-card::before {
  content: '';
  position: absolute; top: 0; left: 0; right: 0;
  height: 2px;
  background: linear-gradient(90deg, transparent, #a78bfa, #4dd0e1, transparent);
}
.halo-mode-pwd-title {
  margin: 0 0 8px;
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 28px; font-weight: 900;
  letter-spacing: -0.8px; line-height: 1.15;
  background: linear-gradient(140deg, #f0eaff, #c4b5fd 50%, #22d3ee);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
}
.halo-mode-pwd-sub {
  margin: 0 0 20px;
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 14px;
  color: rgba(196,181,253,0.65);
  line-height: 1.5;
}
.halo-mode-pwd-input {
  width: 100%;
  padding: 13px 16px;
  background: rgba(6,4,13,0.45);
  border: 1px solid rgba(167,139,250,0.18);
  border-radius: 10px;
  color: #ECECEE;
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 14px;
  outline: none;
  transition: border-color 250ms ease, box-shadow 250ms ease, background 250ms ease;
}
.halo-mode-pwd-input::placeholder { color: rgba(196,181,253,0.25); }
.halo-mode-pwd-input:focus {
  border-color: #4dd0e1;
  background: rgba(6,4,13,0.6);
  box-shadow: 0 0 0 3px rgba(34,211,238,0.10);
}
.halo-mode-pwd-err {
  margin-top: 10px;
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  color: #FCA5A5;
  font-size: 12px;
}
.halo-mode-pwd-actions {
  display: flex; justify-content: flex-end; gap: 10px;
  margin-top: 20px;
}
/* Scoped Unlock button — purple gradient w/ purple glow, matches the
   .form-submit style on hailo.studio auth cards. Cancel keeps the
   ghost .btn look. */
.halo-mode-pwd-actions .btn-primary {
  padding: 12px 22px;
  background: linear-gradient(135deg, #7c3aed, #8b5cf6);
  color: #fff;
  border: none;
  border-radius: 12px;
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 14px; font-weight: 700;
  box-shadow: 0 8px 32px rgba(124,58,237,0.4);
  transition: transform 200ms ease, box-shadow 200ms ease, filter 200ms ease;
}
.halo-mode-pwd-actions .btn-primary:hover {
  filter: brightness(1.05);
  transform: translateY(-1px);
  box-shadow: 0 12px 36px rgba(124,58,237,0.5);
}
.halo-mode-pwd-card.shake {
  animation: halo-pwd-shake 0.4s ease;
}
@keyframes halo-pwd-shake {
  0%, 100% { transform: translateX(0); }
  20%      { transform: translateX(-6px); }
  40%      { transform: translateX(6px); }
  60%      { transform: translateX(-4px); }
  80%      { transform: translateX(4px); }
}

/* Narrow viewports: drop the mode toggle label to keep room for controls.
   MED wings are the rudder of the UI — they don't shrink. The right-side
   cluster sheds labels first; if the bar is still cramped, the brand
   subtitle / search trigger compress before the wings ever do. */
@media (max-width: 1100px) {
  .halo-mode-toggle-label { display: none; }
  .halo-project-chip-label { max-width: 100px; }
}
@media (max-width: 860px) {
  .halo-project-chip-label { display: none; }
}

/* ---------- App shell ----------
   The sidebar column width flips between two states via the
   --sidebar-w variable. <html class="is-sidebar-collapsed"> swaps
   the variable below (see the collapsed-sidebar block further down).
   Transitioning grid-template-columns gives a smooth slide. */
.app-shell {
  display: grid;
  grid-template-columns: var(--sidebar-w, 240px) 1fr;
  min-height: 100vh;
  transition: grid-template-columns 200ms ease;
}
html.is-sidebar-collapsed { --sidebar-w: 72px; }

/* ---------- Ambient background orbs ----------
   Dialed way down (May 2026): orbs now read as faint ambient color through
   the glass rather than decoration. Opacity dropped 0.45 → 0.10, slowed,
   desaturated, and re-tinted toward the accent tokens so they re-theme
   with the user's brand colors. */
.orbs {
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  overflow: hidden;
}
.orb {
  position: absolute;
  border-radius: 50%;
  filter: blur(120px) saturate(70%);
  opacity: 0.10;
}
.orb-1 {
  width: 620px; height: 620px;
  background: radial-gradient(circle, var(--accent, #2DD4BF) 0%, transparent 70%);
  top: -180px; left: -160px;
  animation: orb1 48s ease-in-out infinite;
}
.orb-2 {
  width: 580px; height: 580px;
  background: radial-gradient(circle, var(--accent-soft, #A78BFA) 0%, transparent 70%);
  bottom: -200px; right: -140px;
  animation: orb2 56s ease-in-out infinite;
}
.orb-3 {
  width: 480px; height: 480px;
  background: radial-gradient(circle, var(--accent, #2DD4BF) 0%, transparent 70%);
  top: 45%; left: 55%;
  animation: orb3 64s ease-in-out infinite;
  opacity: 0.06;
}
@keyframes orb1 {
  0%,100% { transform: translate(0,0) scale(1); }
  50%     { transform: translate(40px,30px) scale(1.08); }
}
@keyframes orb2 {
  0%,100% { transform: translate(0,0) scale(1); }
  50%     { transform: translate(-30px,-20px) scale(0.95); }
}
@keyframes orb3 {
  0%,100% { transform: translate(0,0) scale(1); }
  50%     { transform: translate(-50px,40px) scale(1.10); }
}

/* ---------- Glass surface — liquid glass v2 ----------
   The defining moves (from Apple's WWDC 2025 Liquid Glass spec):
   1. backdrop-filter blur + saturation boost (saturation is what makes
      the blurred content behind pop through — that's the "wet" look)
   2. Multi-layer surface tint (translucent base + faint internal gradient)
   3. Edge lighting — 1px specular highlight at the TOP edge (rim light),
      1px depth shadow at the BOTTOM (cast shadow inside the surface)
   4. Soft outer drop shadow for elevation off the page bg
   5. A specular pseudo-element pinned to the top-left corner that
      simulates a fixed light source catching the surface — that's the
      detail that sells "polished glass" instead of "frosted plastic"
*/
.glass {
  position: relative;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.06) 0%, transparent 50%),
    var(--surface-1);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border: 1px solid var(--border-faint);
  border-radius: 18px;
  box-shadow:
    inset 0 1px 0 var(--rim-top),
    inset 0 -1px 0 var(--rim-bottom),
    var(--shadow-card);
  isolation: isolate;          /* so the ::before sheen doesn't bleed children */
}
/* Specular sheen — a soft radial highlight pinned to the top-left, ~12%
   max opacity, fading to nothing within ~40% of the surface. Reads as a
   fixed light source catching the glass. CSS-only, no JS, no perf cost. */
.glass::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: radial-gradient(
    ellipse 60% 50% at 0% 0%,
    rgba(255, 255, 255, 0.06),
    transparent 60%
  );
  pointer-events: none;
  z-index: 0;
}
.glass > * { position: relative; z-index: 1; }

/* ---------- Sidebar ---------- */
.sidebar {
  position: sticky; top: 16px;
  margin: 16px 0 16px 16px;
  padding: 22px 16px;
  height: calc(100vh - 32px);
  display: flex; flex-direction: column;
  z-index: 5;
  border-radius: 22px;
}
.sidebar-brand {
  display: flex; align-items: center; gap: 12px;
  padding: 4px 8px 18px 8px;
  border-bottom: 1px solid rgba(255,255,255,0.06);
  margin-bottom: 14px;
}
.sidebar-logo { width: 36px; height: 36px; border-radius: 10px; object-fit: cover; }
.sidebar-app-name {
  font-family: 'Bebas Neue', sans-serif;
  font-size: 20px;
  font-weight: 400;
  letter-spacing: 0.08em;
}
.sidebar-business-name { font-size: 11px; opacity: 0.55; }

.sidebar-nav { display: flex; flex-direction: column; gap: 2px; }
.sidebar-spine { padding-bottom: 4px; }
.nav-item {
  position: relative;
  display: flex; align-items: center; gap: 12px;
  padding: 9px 14px;
  border-radius: 10px;
  color: var(--text-secondary);
  text-decoration: none;
  font-size: 13.5px;
  font-weight: 500;
  letter-spacing: 0.005em;
  transition: background 150ms ease, color 150ms ease;
}
.nav-item:hover {
  background: rgba(255, 255, 255, 0.03);
  color: var(--text-primary);
  text-decoration: none;
}
.nav-item:hover .nav-icon { color: var(--text-primary); }

/* Obsidian active state:
   - accent-tinted gradient that's brightest near the left glow and
     fades toward the right edge of the row
   - hairline rim highlight along the top edge
   - glowing rounded bar on the left handles the wayfinding (see .nav-active-pill)
   - right-pointing chevron on the right edge as a "you are inside" cue
   Brand color flows from --accent so the AI-extracted-color feature
   swaps everything in one go with no chrome re-tuning. */
.nav-item.is-active {
  background:
    linear-gradient(
      to right,
      color-mix(in srgb, var(--accent) 16%, transparent) 0%,
      color-mix(in srgb, var(--accent) 6%, transparent) 35%,
      var(--surface-active) 100%
    );
  color: var(--text-primary);
  box-shadow:
    inset 0 1px 0 var(--rim-top),
    inset 0 0 0 0.5px var(--border-faint);
}
.nav-item.is-active .nav-icon { color: var(--accent); }

/* Right-pointing chevron on the active row — wayfinding cue that
   you're "inside" this section. Sits flush with the right edge. */
.nav-item.is-active::after {
  content: "";
  position: absolute;
  right: 14px; top: 50%;
  width: 6px; height: 6px;
  border-right: 1.5px solid var(--text-tertiary);
  border-top: 1.5px solid var(--text-tertiary);
  transform: translateY(-50%) rotate(45deg);
  opacity: 0.7;
  pointer-events: none;
}

/* Active-state accent line — glowing rounded bar that snaps in on the
   left edge. This is the wayfinding signal. Brand color flows from
   --accent so the AI-extracted-color feature swaps with no chrome re-tuning. */
.nav-active-pill {
  position: absolute;
  left: 3px; top: 50%; transform: translateY(-50%) scaleY(0);
  width: 3px; height: 22px;
  border-radius: 3px;
  background: var(--accent);
  box-shadow:
    0 0 6px  color-mix(in srgb, var(--accent) 70%, transparent),
    0 0 14px color-mix(in srgb, var(--accent) 45%, transparent);
  transition: transform 180ms cubic-bezier(.2, .8, .2, 1);
}
.nav-item.is-active .nav-active-pill { transform: translateY(-50%) scaleY(1); }

.nav-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px;
  flex: 0 0 18px;
  color: var(--text-tertiary);
  transition: color 150ms ease;
}
.nav-icon svg { width: 18px; height: 18px; display: block; }
.nav-label { flex: 1; }

.sidebar-footer {
  display: flex; justify-content: space-between; align-items: center;
  padding-top: 12px;
  border-top: 1px solid rgba(255,255,255,0.06);
  font-size: 12px;
  opacity: 0.55;
}
.sidebar-foot-link { color: inherit; }
.sidebar-version { font-family: ui-monospace, SFMono-Regular, monospace; }

/* ---------- Sidebar collapse — no UI affordance ----------
   Collapse is still available via the ⌘\ keyboard shortcut and state
   still persists in localStorage (see base.html's pre-paint script and
   the toggle script at the bottom of _sidebar.html). There used to be
   a visible button here — removed 2026-05-19 because it never sat right
   in the layout. Re-add a `.sidebar-toggle` button if you want it back. */

/* ---------- Collapsed icon-rail state ----------
   In collapsed mode the rail shrinks to 72px and we hide every
   text element + structural divider, leaving just the toggle and
   the icons. Group children are also hidden — the user has to
   expand to navigate within a group. */
html.is-sidebar-collapsed .sidebar {
  padding: 18px 10px;
  align-items: stretch;
}
html.is-sidebar-collapsed .sidebar-search,
html.is-sidebar-collapsed .sidebar-wing-section-head,
html.is-sidebar-collapsed .sidebar-footer-meta,
html.is-sidebar-collapsed .nav-label,
html.is-sidebar-collapsed .nav-group-chevron,
html.is-sidebar-collapsed .nav-group > .nav-group-children {
  display: none !important;
}
html.is-sidebar-collapsed .nav-item {
  justify-content: center;
  padding: 10px 0;
  gap: 0;
}
html.is-sidebar-collapsed .nav-active-pill {
  left: -10px;          /* sit against the padded edge of the rail */
}
html.is-sidebar-collapsed .sidebar-wing-section {
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid var(--border-faint);
}
html.is-sidebar-collapsed .sidebar-bottom {
  padding-top: 6px;
}

/* ---------- Main column ---------- */
.app-main {
  position: relative; z-index: 1;
  padding: 16px 22px 60px 16px;
  max-width: 100%;
}

/* ---------- Page header (flat, 2026-05-19) ----------
   Previously this was a .glass card with a 32px Bebas title and an
   accent-gradient hairline. The whole thing read like a floating bubble
   pinned to the top of every page — too much chrome for what's really
   just a "you are here" label. Now it's a quiet text line; the page
   body below carries the visual weight. */
.page-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 6px 6px 14px;
  margin-bottom: 10px;
  position: relative;
}
.page-title {
  font-size: 22px;
  font-weight: 500;
  letter-spacing: 0;
  margin: 0;
  line-height: 1.2;
  color: var(--text-primary);
}
.page-actions { display: flex; gap: 8px; }

/* ---------- Buttons ---------- */
.btn, button.btn, a.btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 16px;
  border-radius: 10px;
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.08);
  color: #ECECEE;
  font-size: 14px; font-weight: 500;
  text-decoration: none;
  cursor: pointer;
  transition: background 120ms ease, transform 80ms ease;
}
.btn:hover { background: rgba(255,255,255,0.08); text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn-primary {
  background: var(--brand-primary);
  color: #1a1d24;
  border-color: transparent;
}
.btn-primary:hover { filter: brightness(1.05); }
.btn-ghost {
  background: transparent;
}

/* ---------- Cards ---------- */
.card { padding: 20px 22px; margin-bottom: 14px; }
.card-title { font-size: 18px; margin-bottom: 10px; }

.grid { display: grid; gap: 14px; }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 1100px) { .grid-3, .grid-4 { grid-template-columns: 1fr 1fr; } }
@media (max-width: 720px)  { .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; } }

/* ---------- Metric tiles ---------- */
.metric-row { margin-bottom: 4px; }
.metric {
  position: relative;
  padding: 20px 22px 22px;
  min-height: 122px;
  display: flex; flex-direction: column; justify-content: flex-end;
}
.metric-card { overflow: hidden; }
.metric-card::before {
  /* subtle inner shine */
  content: "";
  position: absolute; inset: 0;
  background: radial-gradient(120% 80% at 0% 0%, rgba(255,255,255,0.05), transparent 60%);
  pointer-events: none;
}
.metric-value {
  font-family: 'Bebas Neue', sans-serif;
  font-size: 44px;
  line-height: 1;
  letter-spacing: 0.02em;
  color: #fff;
  font-weight: 400;
}
.metric-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.10em;
  opacity: 0.55;
  margin-bottom: 6px;
  font-weight: 600;
}

/* Icon badge in the top-right corner of each metric. */
.metric-icon {
  position: absolute; top: 16px; right: 16px;
  width: 38px; height: 38px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 12px;
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.07);
}
.metric-icon-teal   { color: #5EEAD4; background: rgba(45,212,191,0.10);  border-color: rgba(45,212,191,0.22); }
.metric-icon-purple { color: #C4B5FD; background: rgba(167,139,250,0.10); border-color: rgba(167,139,250,0.22); }
.metric-icon-cyan   { color: #7DD3FC; background: rgba(103,232,249,0.10); border-color: rgba(103,232,249,0.22); }
.metric-icon-amber  { color: #FBBF24; background: rgba(251,191,36,0.10);  border-color: rgba(251,191,36,0.22); }

/* Trend chip on the revenue tile (arrow + delta vs last period). */
.trend-chip {
  display: inline-flex; align-items: center; gap: 4px;
  margin-top: 8px;
  padding: 3px 8px 3px 6px;
  border-radius: 999px;
  font-size: 11px; font-weight: 600;
  letter-spacing: 0.02em;
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.06);
  width: fit-content;
}
.trend-chip.trend-up   { color: #6EE7B7; background: rgba(52,211,153,0.10);  border-color: rgba(52,211,153,0.22); }
.trend-chip.trend-down { color: #FCA5A5; background: rgba(239,68,68,0.10);   border-color: rgba(239,68,68,0.22); }

/* ---------- Card title with leading icon ---------- */
.card-title {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 14px;
  text-transform: uppercase;
  letter-spacing: 0.10em;
  font-weight: 600;
  color: rgba(236,236,238,0.85);
}
.card-title-icon {
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--brand-primary, #2DD4BF);
  opacity: 0.85;
}
.card-title-icon svg { display: block; }

/* ---------- Needs attention ---------- */
.attention-card {
  margin-top: 18px;
  border-left: 3px solid rgba(251,191,36,0.55);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.04),
              0 0 32px -12px rgba(251,191,36,0.25),
              0 12px 32px rgba(0,0,0,0.35);
}
.attention-icon { color: #FBBF24; }
.attention-list { list-style: none; padding: 0; margin: 0; }
.attention-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px;
  padding: 10px 0;
  border-bottom: 1px solid rgba(255,255,255,0.04);
}
.attention-row:last-child { border-bottom: none; }
.attention-link {
  flex: 1;
  display: flex; align-items: center; gap: 12px;
  color: inherit;
  text-decoration: none;
  font-size: 13.5px;
}
.attention-link:hover { text-decoration: none; color: #fff; }
.attention-cat {
  width: 30px; height: 30px;
  border-radius: 9px;
  display: inline-flex; align-items: center; justify-content: center;
  flex: 0 0 30px;
  border: 1px solid rgba(255,255,255,0.06);
}
.attention-cat-invoice   { color: #FCA5A5; background: rgba(239,68,68,0.10);  border-color: rgba(239,68,68,0.22); }
.attention-cat-lead_cold { color: #93C5FD; background: rgba(96,165,250,0.10); border-color: rgba(96,165,250,0.22); }
.attention-cat-proposal  { color: #C4B5FD; background: rgba(167,139,250,0.10);border-color: rgba(167,139,250,0.22); }
.attention-end { display: flex; gap: 14px; align-items: center; flex: 0 0 auto; }
.attention-amount { font-weight: 600; font-size: 13.5px; }
.attention-amount.is-high { color: #FF8585; }
.attention-amount.is-med  { color: #FBBF24; }

/* ---------- Small helpers used in dashboard ---------- */
.page-sub        { opacity: 0.55; font-size: 13px; margin-top: 2px; }
.row-sub         { font-size: 11px; opacity: 0.55; }
.row-sub-soft    { opacity: 0.7; font-size: 12px; margin-top: 2px; }
.row-quiet       { opacity: 0.6; font-size: 13px; margin: 0; }
.row-link        { text-align: center; margin-top: 10px; }
.row-link a      { font-size: 12px; }

.state-row { display: flex; gap: 8px; flex-wrap: wrap; }
.state-tile {
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.06);
  padding: 12px 14px;
  border-radius: 12px;
  flex: 1;
  min-width: 120px;
}
.state-count {
  font-family: 'Bebas Neue', sans-serif;
  font-size: 28px;
  letter-spacing: 0.02em;
  line-height: 1;
}
.state-label {
  font-size: 10.5px;
  opacity: 0.6;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-top: 4px;
  font-weight: 600;
}
.big-money {
  font-family: 'Bebas Neue', sans-serif;
  font-size: 44px; line-height: 1;
  letter-spacing: 0.02em;
  background: linear-gradient(135deg, #FBBF24 0%, #F59E0B 60%, #A78BFA 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}

/* ---------- Quick actions ---------- */
.quick-card { margin-top: 18px; }
.quick-row { display: flex; gap: 10px; flex-wrap: wrap; }
.btn-sm  { padding: 6px 12px; font-size: 12px; }
.btn-soft {
  background: rgba(255,255,255,0.045);
  border: 1px solid rgba(255,255,255,0.08);
  color: #ECECEE;
}
.btn-soft:hover { background: rgba(255,255,255,0.085); }
.btn-gradient {
  background: linear-gradient(135deg, #2DD4BF 0%, #67E8F9 50%, #A78BFA 100%);
  color: #0d0f14;
  border: none;
  font-weight: 600;
  letter-spacing: 0.01em;
  box-shadow: 0 0 0 1px rgba(45,212,191,0.35),
              0 8px 24px -8px rgba(45,212,191,0.55);
}
.btn-gradient:hover { filter: brightness(1.08); text-decoration: none; }
.btn svg { display: block; }

/* ---------- Tables ---------- */
table.list {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
}
table.list th {
  text-align: left;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  opacity: 0.55;
  padding: 10px 14px;
  border-bottom: 1px solid rgba(255,255,255,0.06);
  font-weight: 500;
}
table.list td {
  padding: 14px 14px;
  border-bottom: 1px solid rgba(255,255,255,0.04);
  font-size: 14px;
}
table.list tr:hover td { background: rgba(255,255,255,0.03); }
table.list tr:last-child td { border-bottom: none; }

/* ---------- Status pills ---------- */
.pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 500;
  background: rgba(255,255,255,0.06);
}
.pill::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: currentColor;
}

/* ---------- Forms ---------- */
.form-row { display: flex; flex-direction: column; margin-bottom: 14px; }
.form-row label {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  opacity: 0.55;
  margin-bottom: 6px;
}
.form-row input[type=text], .form-row input[type=email], .form-row input[type=tel],
.form-row input[type=date], .form-row input[type=number], .form-row input[type=password],
.form-row textarea, .form-row select {
  /* background-color (not background shorthand) so the global select rule's
     chevron image survives. The select gets 34px right-padding from the
     global rule, which is correct for our chevron. */
  background-color: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 10px;
  padding: 10px 12px;
  font: inherit;
  color: #ECECEE;
  outline: none;
  transition: border-color 120ms ease, background-color 120ms ease;
}
.form-row select { padding-right: 34px; }
.form-row input:focus, .form-row textarea:focus, .form-row select:focus {
  border-color: var(--brand-primary);
  background-color: rgba(255,255,255,0.06);
}
.form-row textarea { min-height: 100px; resize: vertical; }
.form-row.inline { flex-direction: row; gap: 10px; align-items: center; }

/* ---------- Flash messages ---------- */
.flash-stack { margin-bottom: 14px; }
.flash {
  position: relative;
  padding: 12px 16px 12px 44px;
  margin-bottom: 8px;
  border-radius: 12px;
  font-size: 14px;
  border: 1px solid rgba(255,255,255,0.08);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}
.flash::before {
  content: "";
  position: absolute;
  left: 14px; top: 50%;
  width: 18px; height: 18px;
  transform: translateY(-50%);
  background: currentColor;
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: contain; mask-size: contain;
}
.flash-success {
  background: rgba(133,221,177,0.10);
  border-color: rgba(133,221,177,0.25);
  color: #6EE7B7;
}
.flash-success::before {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6 9 17 4 12'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6 9 17 4 12'/></svg>");
}
.flash-error {
  background: rgba(255,133,133,0.10);
  border-color: rgba(255,133,133,0.25);
  color: #FCA5A5;
}
.flash-error::before {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='10'/><line x1='12' y1='8' x2='12' y2='12'/><line x1='12' y1='16' x2='12.01' y2='16'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='10'/><line x1='12' y1='8' x2='12' y2='12'/><line x1='12' y1='16' x2='12.01' y2='16'/></svg>");
}
.flash-info, .flash-message {
  background: rgba(103,232,249,0.08);
  border-color: rgba(103,232,249,0.22);
  color: #7DD3FC;
}
.flash-info::before, .flash-message::before {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='10'/><line x1='12' y1='16' x2='12' y2='12'/><line x1='12' y1='8' x2='12.01' y2='8'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='10'/><line x1='12' y1='16' x2='12' y2='12'/><line x1='12' y1='8' x2='12.01' y2='8'/></svg>");
}

/* ---------- Empty states ---------- */
.empty {
  text-align: center;
  padding: 50px 22px;
  opacity: 0.7;
}
.empty h3 { font-size: 20px; margin-bottom: 8px; }
.empty p  { font-size: 14px; max-width: 460px; margin: 0 auto 18px; opacity: 0.7; }

/* ---------- Timeline (lead/client communications) ---------- */
.timeline { list-style: none; padding: 0; margin: 0; }
.timeline li {
  position: relative;
  padding: 12px 14px 12px 28px;
  border-bottom: 1px solid rgba(255,255,255,0.04);
}
.timeline li::before {
  content: "";
  position: absolute;
  left: 8px; top: 18px;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--brand-primary);
  opacity: 0.7;
}
.timeline-meta {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  opacity: 0.55;
  margin-bottom: 4px;
}

/* ---------- Responsive: collapse sidebar on narrow ---------- */
@media (max-width: 840px) {
  .app-shell { grid-template-columns: 1fr; }
  .sidebar {
    position: relative; top: 0; margin: 12px;
    height: auto;
    flex-direction: row; gap: 8px; overflow-x: auto;
    padding: 12px;
  }
  .sidebar-brand, .sidebar-footer { display: none; }
  .sidebar-nav { flex-direction: row; }
  .nav-label { display: none; }
  .nav-item { padding: 8px; }
}

/* =============================================================================
   Cmd+K command palette
   ============================================================================= */
.cmdk[hidden] { display: none !important; }
.cmdk {
  position: fixed; inset: 0; z-index: 100;
  display: flex; align-items: flex-start; justify-content: center;
  padding-top: 14vh;
  animation: cmdkFade 140ms ease-out;
}
.cmdk-scrim {
  position: absolute; inset: 0;
  background: rgba(8, 10, 14, 0.62);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.cmdk-shell {
  position: relative;
  width: min(640px, calc(100vw - 32px));
  border-radius: 18px;
  background: rgba(22, 25, 32, 0.92);
  backdrop-filter: blur(28px) saturate(180%);
  -webkit-backdrop-filter: blur(28px) saturate(180%);
  border: 1px solid rgba(255,255,255,0.08);
  box-shadow:
    0 1px 0 rgba(255,255,255,0.08) inset,
    0 28px 72px rgba(0,0,0,0.55),
    0 0 60px rgba(45,212,191,0.08);
  overflow: hidden;
  animation: cmdkPop 180ms cubic-bezier(.2,.8,.2,1);
}
.cmdk-input-row {
  display: flex; align-items: center; gap: 12px;
  padding: 16px 18px 14px 18px;
  border-bottom: 1px solid rgba(255,255,255,0.05);
}
.cmdk-icon {
  width: 18px; height: 18px;
  color: rgba(236,236,238,0.45);
  flex: 0 0 18px;
}
.cmdk-input {
  flex: 1;
  background: transparent;
  border: 0;
  outline: 0;
  color: #fff;
  font-size: 16px;
  font-family: inherit;
  caret-color: var(--brand-primary);
}
.cmdk-input::placeholder { color: rgba(236,236,238,0.4); }
.cmdk-kbd {
  font-family: ui-monospace, SFMono-Regular, monospace;
  font-size: 10.5px;
  padding: 3px 6px;
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 5px;
  color: rgba(236,236,238,0.55);
  background: rgba(255,255,255,0.02);
}
.cmdk-results {
  max-height: 48vh;
  overflow-y: auto;
  padding: 6px;
}
.cmdk-results:empty { display: none; }
.cmdk-empty {
  padding: 22px 18px;
  color: rgba(236,236,238,0.5);
  font-size: 13.5px;
  text-align: center;
}
.cmdk-item {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 12px;
  border-radius: 10px;
  cursor: pointer;
  color: rgba(236,236,238,0.85);
  font-size: 13.5px;
  transition: background 90ms ease, color 90ms ease;
}
.cmdk-item:hover, .cmdk-item.is-selected {
  background: linear-gradient(135deg, rgba(45,212,191,0.16), rgba(167,139,250,0.10));
  color: #fff;
}
.cmdk-item.is-selected { box-shadow: inset 0 0 0 1px rgba(45,212,191,0.22); }
.cmdk-pill {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 3px 7px;
  border-radius: 999px;
  background: rgba(255,255,255,0.05);
  border: 1px solid rgba(255,255,255,0.06);
  color: rgba(236,236,238,0.6);
  flex: 0 0 auto;
}
.cmdk-pill[data-category="lead"]     { color: #5EEAD4; border-color: rgba(94,234,212,0.25); }
.cmdk-pill[data-category="client"]   { color: #A78BFA; border-color: rgba(167,139,250,0.25); }
.cmdk-pill[data-category="invoice"]  { color: #F472B6; border-color: rgba(244,114,182,0.25); }
.cmdk-pill[data-category="proposal"] { color: #67E8F9; border-color: rgba(103,232,249,0.25); }
.cmdk-pill[data-category="vendor"]   { color: #FCD34D; border-color: rgba(252,211,77,0.25); }
.cmdk-pill[data-category="action"]   { color: #5EEAD4; background: rgba(45,212,191,0.10); border-color: rgba(45,212,191,0.25); }
.cmdk-item-body { flex: 1; min-width: 0; }
.cmdk-item-title { color: inherit; }
.cmdk-item-sub {
  font-size: 11.5px;
  color: rgba(236,236,238,0.5);
  margin-top: 1px;
}
.cmdk-foot {
  display: flex; gap: 16px;
  padding: 8px 16px;
  border-top: 1px solid rgba(255,255,255,0.05);
  font-size: 11px;
  color: rgba(236,236,238,0.45);
  background: rgba(13,15,20,0.45);
}
.cmdk-foot kbd {
  font-family: ui-monospace, SFMono-Regular, monospace;
  font-size: 10px;
  padding: 1px 5px;
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 4px;
  margin-right: 4px;
}
@keyframes cmdkFade { from { opacity: 0; } to { opacity: 1; } }
@keyframes cmdkPop {
  from { opacity: 0; transform: translateY(-6px) scale(0.985); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* =============================================================================
   Right-edge quick-preview drawer
   ============================================================================= */
.quickview[hidden] { display: none !important; }
.quickview {
  position: fixed; inset: 0; z-index: 90;
}
.quickview-scrim {
  position: absolute; inset: 0;
  background: rgba(8, 10, 14, 0.42);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  animation: qvFade 160ms ease-out;
}
.quickview-panel {
  position: absolute;
  top: 16px; bottom: 16px; right: 16px;
  width: min(440px, calc(100vw - 32px));
  border-radius: 22px;
  background: rgba(22, 25, 32, 0.86);
  backdrop-filter: blur(24px) saturate(170%);
  -webkit-backdrop-filter: blur(24px) saturate(170%);
  border: 1px solid rgba(255,255,255,0.08);
  box-shadow: 0 24px 60px rgba(0,0,0,0.5);
  overflow: hidden;
  animation: qvSlide 220ms cubic-bezier(.2,.8,.2,1);
  display: flex; flex-direction: column;
}
.quickview-close {
  position: absolute; top: 12px; right: 14px; z-index: 2;
  width: 30px; height: 30px;
  border-radius: 50%;
  background: rgba(255,255,255,0.06);
  border: 1px solid rgba(255,255,255,0.08);
  color: rgba(236,236,238,0.7);
  font-size: 18px; line-height: 1;
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}
.quickview-close:hover {
  background: rgba(45,212,191,0.18);
  color: #fff;
}
.quickview-body {
  flex: 1;
  padding: 28px 24px 22px 24px;
  overflow-y: auto;
}
.quickview-skeleton { display: flex; flex-direction: column; gap: 10px; padding-top: 14px; }
.skel {
  background: linear-gradient(90deg,
    rgba(255,255,255,0.04) 0%,
    rgba(255,255,255,0.12) 50%,
    rgba(255,255,255,0.04) 100%);
  background-size: 200% 100%;
  border-radius: 8px;
  animation: skelShimmer 1.4s linear infinite;
}
.skel-title { height: 22px; width: 60%; }
.skel-line { height: 12px; width: 92%; }
.skel-line.short { width: 60%; }
@keyframes skelShimmer {
  0%   { background-position: 100% 0; }
  100% { background-position: -100% 0; }
}
@keyframes qvFade { from { opacity: 0; } to { opacity: 1; } }
@keyframes qvSlide {
  from { opacity: 0; transform: translateX(28px); }
  to   { opacity: 1; transform: translateX(0); }
}

.qv-eyebrow {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: rgba(236,236,238,0.55);
  margin-bottom: 4px;
}
.qv-title {
  font-family: 'Bebas Neue', sans-serif;
  font-size: 28px;
  letter-spacing: 0.04em;
  margin: 0 0 14px 0;
}
.qv-grid {
  display: grid;
  grid-template-columns: 96px 1fr;
  gap: 6px 14px;
  font-size: 13px;
  margin-bottom: 18px;
}
.qv-grid dt {
  color: rgba(236,236,238,0.5);
  text-transform: uppercase;
  font-size: 10.5px;
  letter-spacing: 0.08em;
  padding-top: 2px;
}
.qv-grid dd { margin: 0; color: #ECECEE; word-break: break-word; }
.qv-section { margin-top: 16px; padding-top: 14px; border-top: 1px solid rgba(255,255,255,0.06); }
.qv-section h4 {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: rgba(236,236,238,0.55);
  margin: 0 0 8px 0;
}
.qv-section p { margin: 0 0 6px 0; font-size: 13px; line-height: 1.5; }
.qv-actions {
  display: flex; gap: 10px;
  margin-top: 22px;
}
.qv-actions a {
  flex: 1;
  text-align: center;
  padding: 9px 14px;
  border-radius: 10px;
  font-size: 13px;
  font-weight: 500;
  text-decoration: none;
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.07);
  color: rgba(236,236,238,0.85);
  transition: background 120ms ease, color 120ms ease, transform 120ms ease;
}
.qv-actions a.primary {
  background: linear-gradient(135deg, rgba(45,212,191,0.22), rgba(167,139,250,0.18));
  border-color: rgba(45,212,191,0.32);
  color: #fff;
}
.qv-actions a:hover { transform: translateY(-1px); }

/* =============================================================================
   Motion polish — count-up, hover-lift, page fade, transition sweep
   ============================================================================= */
.count-up { font-variant-numeric: tabular-nums; }
.lift, .stat-tile, .action-card {
  transition: transform 180ms ease, box-shadow 180ms ease, border-color 180ms ease;
}
.lift:hover, .stat-tile:hover, .action-card:hover {
  transform: translateY(-2px);
  box-shadow:
    0 1px 0 rgba(255,255,255,0.06) inset,
    0 18px 40px rgba(0,0,0,0.4),
    0 0 24px rgba(45,212,191,0.10);
  /* Suppress the global a:hover underline so the card text doesn't get
     scribbled on when hovered. The card anchor's base rule already sets
     text-decoration: none, but a:hover overrides for the hover state
     unless we restate it here. */
  text-decoration: none;
}
.lift:hover *, .stat-tile:hover *, .action-card:hover * {
  text-decoration: none;
}

.app-main, .page-body { animation: pageFade 280ms ease-out; }
@keyframes pageFade {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Wing-switch transition: brief gradient sweep across the screen. */
.wing-sweep {
  position: fixed; inset: 0; z-index: 99;
  pointer-events: none;
  background: linear-gradient(120deg,
    transparent 30%,
    rgba(45,212,191,0.22) 50%,
    rgba(167,139,250,0.22) 60%,
    transparent 80%);
  transform: translateX(-100%);
  animation: wingSweep 520ms cubic-bezier(.4,0,.2,1) forwards;
}
@keyframes wingSweep {
  to { transform: translateX(100%); }
}

/* =============================================================================
   Empty states with personality
   ============================================================================= */
.empty-state {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 60px 28px;
  text-align: center;
  max-width: 460px; margin: 0 auto;
}
.empty-state-art {
  width: 96px; height: 96px;
  margin-bottom: 18px;
  display: flex; align-items: center; justify-content: center;
  color: rgba(45,212,191,0.55);
  filter: drop-shadow(0 6px 16px rgba(45,212,191,0.18));
}
.empty-state-art svg { width: 100%; height: 100%; }
.empty-state h3 {
  font-family: 'Bebas Neue', sans-serif;
  font-size: 22px;
  letter-spacing: 0.04em;
  margin: 0 0 6px 0;
  color: #fff;
}
.empty-state p {
  margin: 0 0 18px 0;
  color: rgba(236,236,238,0.6);
  font-size: 14px;
  line-height: 1.55;
}
.empty-state .button {
  align-self: center;
}
.empty-state.empty-state-inline {
  padding: 36px 18px;
}

/* =============================================================================
   Action cards (dashboard)
   ============================================================================= */
.action-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 16px;
  margin-bottom: 26px;
}
.action-card {
  position: relative;
  padding: 18px 18px 16px 18px;
  border-radius: 16px;
  background: rgba(22, 25, 32, 0.55);
  backdrop-filter: blur(20px) saturate(150%);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
  border: 1px solid rgba(255,255,255,0.06);
  display: flex; flex-direction: column;
  text-decoration: none;
  color: inherit;
  overflow: hidden;
}
.action-card::before {
  content: "";
  position: absolute; inset: 0;
  background: radial-gradient(circle at 100% 0%, rgba(45,212,191,0.10), transparent 55%);
  pointer-events: none;
}
.action-card[data-urgency="high"]::before {
  background: radial-gradient(circle at 100% 0%, rgba(244,114,182,0.16), transparent 55%);
}
.action-card[data-urgency="medium"]::before {
  background: radial-gradient(circle at 100% 0%, rgba(167,139,250,0.13), transparent 55%);
}
.action-card-eyebrow {
  display: flex; align-items: center; gap: 8px;
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: rgba(236,236,238,0.55);
  margin-bottom: 6px;
}
.action-card-eyebrow .dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--brand-primary);
  box-shadow: 0 0 10px rgba(45,212,191,0.6);
}
.action-card[data-urgency="high"] .action-card-eyebrow .dot { background: #F472B6; box-shadow: 0 0 10px rgba(244,114,182,0.6); }
.action-card[data-urgency="medium"] .action-card-eyebrow .dot { background: #A78BFA; box-shadow: 0 0 10px rgba(167,139,250,0.6); }
.action-card-headline {
  font-family: 'Bebas Neue', sans-serif;
  font-size: 28px;
  letter-spacing: 0.03em;
  line-height: 1.05;
  margin: 0 0 6px 0;
  color: #fff;
}
.action-card-body {
  font-size: 13px;
  color: rgba(236,236,238,0.65);
  flex: 1;
  margin-bottom: 14px;
  line-height: 1.5;
}
.action-card-cta {
  align-self: flex-start;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 13px;
  border-radius: 999px;
  font-size: 12px;
  letter-spacing: 0.02em;
  background: rgba(45,212,191,0.14);
  border: 1px solid rgba(45,212,191,0.32);
  color: #5EEAD4;
  transition: background 120ms ease, transform 120ms ease;
}
.action-card-cta::after {
  content: "→";
  transition: transform 140ms ease;
}
.action-card:hover .action-card-cta { background: rgba(45,212,191,0.22); }
.action-card:hover .action-card-cta::after { transform: translateX(2px); }

/* =============================================================================
   Wedding data-viz: heatmap, funnel, countdown ring
   ============================================================================= */
.year-heatmap {
  display: flex; flex-direction: column; gap: 6px;
  padding: 6px 0 0 0;
}
.heatmap-row {
  display: grid;
  grid-template-columns: 36px repeat(53, 1fr);
  gap: 2px;
  align-items: center;
}
.heatmap-month-label {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: rgba(236,236,238,0.4);
}
.heatmap-cell {
  aspect-ratio: 1;
  border-radius: 3px;
  background: rgba(255,255,255,0.03);
  transition: transform 140ms ease, background 140ms ease;
}
.heatmap-cell[data-count="1"] { background: rgba(45,212,191,0.32); }
.heatmap-cell[data-count="2"] { background: rgba(45,212,191,0.55); }
.heatmap-cell[data-count="3"] { background: linear-gradient(135deg, rgba(45,212,191,0.85), rgba(167,139,250,0.65)); }
.heatmap-cell[data-count="4"] { background: linear-gradient(135deg, #2DD4BF, #A78BFA); box-shadow: 0 0 8px rgba(45,212,191,0.4); }
.heatmap-cell:hover { transform: scale(1.4); z-index: 2; position: relative; }

.viz-card {
  padding: 22px 22px 16px;
  border-radius: 18px;
  background: rgba(22, 25, 32, 0.5);
  border: 1px solid rgba(255,255,255,0.06);
  backdrop-filter: blur(18px) saturate(150%);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
  margin-bottom: 18px;
}
.viz-card-head {
  display: flex; align-items: baseline; justify-content: space-between;
  margin-bottom: 14px;
}
.viz-card-title {
  font-family: 'Bebas Neue', sans-serif;
  font-size: 16px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(236,236,238,0.75);
}
.viz-card-meta {
  font-size: 11px;
  color: rgba(236,236,238,0.45);
}

.funnel {
  display: flex; align-items: stretch; gap: 6px;
  height: 88px;
}
.funnel-stage {
  flex: 1;
  position: relative;
  border-radius: 12px;
  padding: 12px;
  display: flex; flex-direction: column; justify-content: space-between;
  color: rgba(236,236,238,0.85);
  border: 1px solid rgba(255,255,255,0.06);
  background: rgba(255,255,255,0.03);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  overflow: hidden;
}
.funnel-stage::before {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(135deg,
    rgba(45,212,191, var(--fill, 0.0)),
    rgba(167,139,250, calc(var(--fill, 0.0) * 0.7)));
  pointer-events: none;
}
.funnel-stage strong {
  position: relative;
  font-family: 'Bebas Neue', sans-serif;
  font-size: 28px;
  letter-spacing: 0.03em;
  color: #fff;
}
.funnel-stage span { position: relative; opacity: 0.7; }

.countdown-ring {
  position: relative;
  width: 56px; height: 56px;
  flex: 0 0 56px;
}
.countdown-ring svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.countdown-ring-track { stroke: rgba(255,255,255,0.06); fill: none; stroke-width: 5; }
.countdown-ring-fill {
  fill: none; stroke-width: 5; stroke-linecap: round;
  stroke: url(#ringGrad);
  transition: stroke-dashoffset 480ms cubic-bezier(.2,.8,.2,1);
}
.countdown-ring-num {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  font-family: 'Bebas Neue', sans-serif;
  font-size: 18px;
  letter-spacing: 0.04em;
  color: #fff;
}
.countdown-row {
  display: flex; align-items: center; gap: 14px;
  padding: 10px 12px;
  border-radius: 12px;
  background: rgba(255,255,255,0.025);
  border: 1px solid rgba(255,255,255,0.05);
  margin-bottom: 8px;
}
.countdown-row .info { flex: 1; min-width: 0; }
.countdown-row .info strong {
  display: block; color: #fff;
  font-size: 14px; margin-bottom: 2px;
}
.countdown-row .info span {
  display: block; font-size: 11.5px; color: rgba(236,236,238,0.5);
}

/* =============================================================================
   Embed form builder — split-screen with live preview
   ============================================================================= */
.embed-split {
  display: grid;
  grid-template-columns: minmax(340px, 1fr) minmax(340px, 1fr);
  gap: 18px;
  align-items: start;
}
@media (max-width: 1100px) {
  .embed-split { grid-template-columns: 1fr; }
}
.embed-preview-shell {
  position: sticky; top: 20px;
  border-radius: 18px;
  background: rgba(22, 25, 32, 0.5);
  border: 1px solid rgba(255,255,255,0.06);
  backdrop-filter: blur(18px) saturate(150%);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
  padding: 14px;
  max-height: calc(100vh - 80px);
  overflow: auto;
}
.embed-preview-eyebrow {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 12px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: rgba(236,236,238,0.55);
}
.embed-preview-eyebrow .live-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: #5EEAD4;
  box-shadow: 0 0 10px rgba(94,234,212,0.6);
  animation: pulseDot 1.6s ease-in-out infinite;
}
@keyframes pulseDot {
  0%, 100% { opacity: 0.7; }
  50%      { opacity: 1; }
}
.embed-preview-iframe {
  border-radius: 12px;
  overflow: hidden;
  background: #fafafa;
  color: #1a1d24;
  padding: 22px;
  font-family: 'Inter', sans-serif;
}
.embed-preview-iframe .ep-headline {
  font-size: 22px;
  font-weight: 600;
  margin: 0 0 8px 0;
  color: var(--ep-accent, #2DD4BF);
}
.embed-preview-iframe .ep-intro {
  font-size: 13.5px;
  color: #555;
  margin: 0 0 18px 0;
  line-height: 1.55;
}
.embed-preview-iframe .ep-field { margin-bottom: 12px; }
.embed-preview-iframe .ep-label {
  display: block;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: #777;
  margin-bottom: 4px;
}
.embed-preview-iframe .ep-input {
  display: block;
  width: 100%;
  padding: 9px 11px;
  border: 1px solid #ddd;
  border-radius: 8px;
  font-size: 13.5px;
  color: #1a1d24;
  background: #fff;
}
.embed-preview-iframe textarea.ep-input { resize: vertical; min-height: 60px; }
.embed-preview-iframe .ep-button {
  background: var(--ep-accent, #2DD4BF);
  color: #1a1d24;
  font-weight: 600;
  font-size: 13.5px;
  padding: 11px 22px;
  border: 0;
  border-radius: 8px;
  cursor: pointer;
  margin-top: 4px;
}

/* ============================================================================
   BENTO DASHBOARD (2026-05-19)
   The dashboard was rewritten around what a wedding videographer actually
   wants to see in the morning — next shoot, money, films on the bench, the
   week, the year — instead of count tiles + pipeline funnels. The styles
   below live here (not inline) so brand-color overrides on :root re-theme
   the cards along with the rest of the chrome.

   Layout: 12-col grid, mostly 4+4+4 stat row, 7+5 + 8+4 mid rows, 12 heat row.
   Cards: shared .dash-cell (glass surface with a top-left specular sheen
   and a hairline rim). Quiet by default; lift + accent line on hover.
   ============================================================================ */

.dash-hero {
  padding: 4px 4px 18px;
}
.dash-hero-eyebrow {
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin: 0 0 6px;
}
.dash-hero-h {
  font-family: var(--font-display), 'Bebas Neue', sans-serif;
  font-size: 38px;
  letter-spacing: 0.04em;
  line-height: 1;
  color: var(--text-primary);
  margin: 0 0 8px;
}
.dash-hero-sub {
  font-size: 14px;
  color: var(--text-secondary);
  margin: 0;
  max-width: 620px;
  line-height: 1.5;
}

.dash-grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: 12px;
}

/* ── Shared cell ── */
.dash-cell {
  position: relative;
  padding: 16px 18px;
  border-radius: 16px;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.045) 0%, transparent 50%),
    var(--surface-1);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border: 1px solid var(--border-faint);
  box-shadow:
    inset 0 1px 0 var(--rim-top),
    inset 0 -1px 0 var(--rim-bottom),
    0 6px 18px rgba(0, 0, 0, 0.30);
  isolation: isolate;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  min-width: 0;
  color: var(--text-primary);
  text-decoration: none;
  transition: transform 180ms cubic-bezier(.2,.8,.2,1),
              border-color 180ms ease, box-shadow 180ms ease;
}
.dash-cell::before {
  content: "";
  position: absolute; inset: 0;
  border-radius: inherit;
  background: radial-gradient(ellipse 65% 50% at 0% 0%,
                              rgba(255,255,255,0.05), transparent 60%);
  pointer-events: none;
  z-index: 0;
}
.dash-cell > * { position: relative; z-index: 1; }

a.dash-cell { color: var(--text-primary); }
a.dash-cell:hover, a.dash-cell:focus-visible {
  transform: translateY(-2px);
  border-color: var(--border-line);
  box-shadow:
    inset 0 1px 0 var(--rim-top),
    inset 0 -1px 0 var(--rim-bottom),
    0 12px 28px rgba(0, 0, 0, 0.40),
    0 0 0 0.5px var(--accent-line);
  text-decoration: none;
}

/* ── Tag (small eyebrow label inside every cell) ── */
.dash-tag {
  display: flex; align-items: baseline; justify-content: space-between;
  font-family: var(--font-display), 'Bebas Neue', sans-serif;
  font-size: 10px;
  letter-spacing: 0.20em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin: 0 0 12px;
}
.dash-tag .meta {
  letter-spacing: 0.08em;
  color: var(--text-faint);
  font-family: 'Inter', sans-serif;
  font-size: 11px;
  font-weight: 400;
  text-transform: none;
}

/* ── Stat row (Edit time / Next shoot / Money) ── */
.dash-stat { min-height: 130px; }

.dash-bignum {
  font-family: var(--font-display), 'Bebas Neue', sans-serif;
  font-size: 42px;
  line-height: 1;
  letter-spacing: 0.02em;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}

/* Sparkline (edit time) */
.dash-spark {
  display: flex; align-items: flex-end; gap: 3px;
  height: 26px; margin-top: 12px;
}
.dash-spark > span {
  flex: 1;
  background: linear-gradient(180deg, rgba(45,212,191,0.95), rgba(167,139,250,0.65));
  border-radius: 2px;
  min-height: 2px;
}
.dash-spark > span.is-empty {
  background: rgba(255,255,255,0.06);
}

/* Live pulse (edit time card) */
.dash-edit-time { position: relative; }
.dash-live-dot {
  position: absolute;
  top: 14px; right: 14px;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 0 var(--accent-glow);
  animation: dashLivePulse 1.8s ease-out infinite;
}
@keyframes dashLivePulse {
  0%   { box-shadow: 0 0 0 0 rgba(45,212,191,0.55); }
  70%  { box-shadow: 0 0 0 10px rgba(45,212,191,0); }
  100% { box-shadow: 0 0 0 0 rgba(45,212,191,0); }
}

/* ── Edit-Time card (2026-05-20 — clean rebuild) ──
   Title uses the standard .dash-tag pattern (same as every other dashboard
   panel — small Bebas eyebrow with a .meta slot on the right) so the card
   feels native to the dashboard instead of a one-off. Card is compact:
   header row → laptop + number side-by-side → sparkline + axis. No
   empty zones.

   The toggle still mirrors the MED top-bar wing-pill — same spring
   easing, same gradient, same bulge keyframe — and follows the cursor on
   hover, bulges on every switch. */
.edit-time-card {
  min-height: 168px;
  padding: 16px 18px 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
/* Title-row tweak — make the .meta slot (which holds the toggle) actually
   align center vertically with the title text, not baseline (the toggle
   pill is taller than text so baseline-align sinks it). */
.edit-time-card .et-head { align-items: center; margin: 0 0 4px; }
.edit-time-card .et-head .meta { display: flex; align-items: center; }

.edit-time-card .et-body {
  display: flex;
  align-items: center;
  gap: 14px;
  flex: 1 1 auto;
  min-width: 0;
}

/* Animated MacBook — sized to fit a compact body row (was 130px and made
   the card 230px tall; was 72px and looked timid). 96×80 is the goldilocks
   that the original pass landed on. */
.et-laptop {
  width: 96px; height: 80px;
  flex-shrink: 0;
  position: relative;
  /* Halo pulse on the whole laptop — guarantees visible motion even if a
     browser ignores the SVG-internal transforms below. */
  animation: etLaptopHalo 3.8s ease-in-out infinite;
  filter: drop-shadow(0 6px 14px rgba(45,212,191,0.24));
}
@keyframes etLaptopHalo {
  0%, 100% { filter: drop-shadow(0 6px 14px rgba(45,212,191,0.20)); }
  50%      { filter: drop-shadow(0 6px 22px rgba(45,212,191,0.55)); }
}
.et-laptop svg { width: 100%; height: 100%; display: block; overflow: visible; }
.et-laptop .et-lid {
  /* SVG transforms — use 2D scaleY (WebKit reliably renders this on <g>;
     the earlier rotateX 3D transform got dropped on WKWebView without an
     ancestor `perspective`). transform-origin in user-space coords so
     WebKit doesn't reinterpret % values inconsistently inside SVG. */
  transform-origin: 48px 61px;
  animation: etLidBreathe 4.4s ease-in-out infinite;
}
.et-laptop .et-screen-glow {
  opacity: 0.55;
  animation: etScreenGlow 2.6s ease-in-out infinite;
  transform-origin: 48px 33px;
}
.edit-time-card.is-live .et-laptop {
  animation-duration: 1.8s;
}
.edit-time-card.is-live .et-laptop .et-screen-glow {
  animation-duration: 1.4s;
  opacity: 0.95;
}
@keyframes etLidBreathe {
  0%, 100% { transform: scaleY(1)    translateY(0); }
  50%      { transform: scaleY(0.93) translateY(2px); }
}
@keyframes etScreenGlow {
  0%, 100% { opacity: 0.40; transform: scale(0.96); }
  50%      { opacity: 0.95; transform: scale(1.04); }
}
@media (prefers-reduced-motion: reduce) {
  .et-laptop,
  .et-laptop .et-lid,
  .et-laptop .et-screen-glow { animation: none; }
}

/* Number block — sits inline beside the laptop. Left-aligned so it
   reads naturally next to the icon. */
.et-number {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  min-width: 0;
  transition: opacity 180ms ease;
  flex: 1 1 auto;
}
.et-number.is-swapping { opacity: 0.35; }
.et-number-line {
  display: flex;
  align-items: baseline;
  gap: 6px;
  line-height: 1;
}
.et-number .et-value {
  font-family: var(--font-display), 'Bebas Neue', sans-serif;
  font-size: 34px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.02em;
  color: #ffffff;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 2px 12px rgba(45,212,191,0.15);
}
.et-number .et-unit {
  font-family: 'Inter', sans-serif;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.80);
  white-space: nowrap;
}
/* Caption ties the number to the active range. Toggle says WHICH window,
   caption says WHEN — they reinforce each other. */
.et-number .et-caption {
  font-family: 'Inter', sans-serif;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-top: 2px;
  transition: opacity 220ms ease;
}

/* ── Range toggle — MED-style sliding bubble ──
   Mirrors crm/static/css/hailo_unified.css `.halo-wing-pill`. */
.et-toggle {
  position: relative;
  display: inline-flex;
  gap: 0;
  padding: 3px;
  border-radius: 999px;
  background: rgba(28, 18, 48, 0.55);
  border: 1px solid rgba(167, 139, 250, 0.22);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.06),
              0 4px 14px rgba(0,0,0,0.30);
  overflow: visible;
  flex-shrink: 0;
}
.et-toggle-pill {
  position: absolute;
  top: 3px; bottom: 3px;
  left: 0; width: 0;
  border-radius: 999px;
  background: linear-gradient(135deg,
              rgba(124, 58, 237, 0.55),
              rgba(34, 211, 238, 0.38));
  border: 1px solid rgba(167, 139, 250, 0.50);
  transition: left 0.85s cubic-bezier(0.5, 1.4, 0.4, 1),
              width 0.85s cubic-bezier(0.5, 1.4, 0.4, 1);
  pointer-events: none;
  z-index: 0;
  box-shadow:
    0 0 22px rgba(124, 58, 237, 0.38),
    0 3px 10px rgba(0, 0, 0, 0.30),
    inset 0 1px 0 rgba(255, 255, 255, 0.18),
    inset 0 -1px 0 rgba(0, 0, 0, 0.20);
}
.et-toggle-pill.bulge {
  animation: etTogglePillBulge 0.5s cubic-bezier(0.3, 1.3, 0.5, 1);
}
@keyframes etTogglePillBulge {
  0%   { transform: scale(1, 1); }
  40%  { transform: scale(1.08, 1.18); }
  100% { transform: scale(1, 1); }
}
.et-toggle button {
  appearance: none;
  border: 0;
  background: transparent;
  position: relative;
  z-index: 1;
  color: var(--text-faint);
  font-family: 'Inter', sans-serif;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  padding: 5px 8px;
  border-radius: 999px;
  cursor: pointer;
  transition: color 0.2s;
  min-width: 28px;
}
.et-toggle button:hover { color: #c4b5fd; }
.et-toggle button.is-active { color: #ffffff; }

/* Sparkline — full-width row at the card's bottom. */
.et-spark {
  display: flex; align-items: flex-end; gap: 4px;
  height: 36px;
  margin-top: auto;
  transition: opacity 180ms ease;
}
.et-spark.is-swapping { opacity: 0.4; }
.et-spark > .et-bar {
  flex: 1;
  min-height: 4px;
  border-radius: 3px 3px 1px 1px;
  background: linear-gradient(180deg, rgba(45,212,191,0.95), rgba(167,139,250,0.55));
  position: relative;
  transition: height 220ms cubic-bezier(.2,.8,.2,1);
}
/* Empty bars: clearly present but visibly inactive — gives the chart a
   continuous baseline instead of looking half-empty when most days are 0. */
.et-spark > .et-bar.is-empty {
  background: rgba(255,255,255,0.10);
  min-height: 4px;
  height: 4px !important;
  align-self: flex-end;
}
.et-spark > .et-bar .et-tip {
  position: absolute;
  bottom: calc(100% + 6px);
  left: 50%; transform: translateX(-50%);
  background: var(--surface-2, rgba(20,20,24,0.92));
  color: var(--text-primary);
  font-size: 10px;
  font-family: 'Inter', sans-serif;
  white-space: nowrap;
  padding: 3px 6px;
  border-radius: 5px;
  pointer-events: none;
  opacity: 0;
  transition: opacity 120ms ease;
  border: 1px solid var(--border-faint);
}
.et-spark > .et-bar:hover .et-tip { opacity: 1; }

/* Bar-axis labels under the sparkline */
.et-axis {
  display: flex; gap: 4px;
  margin-top: 4px;
  font-size: 9px;
  color: var(--text-faint);
  font-family: 'Inter', sans-serif;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.et-axis > span {
  flex: 1;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
}

/* Live dot (mirrors dash-edit-time behavior) */
.edit-time-card .et-live-dot {
  position: absolute;
  top: 14px; right: 14px;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--accent);
  animation: dashLivePulse 1.8s ease-out infinite;
  z-index: 2;
}

/* Make the card act like the rest of the dash links */
a.edit-time-card { color: var(--text-primary); text-decoration: none; }

/* Mobile: hide axis ticks so the sparkline can breathe */
@media (max-width: 720px) {
  .et-laptop { width: 100px; height: 84px; }
  .et-axis { display: none; }
}

/* Next-shoot card */
.dash-shoot-name {
  font-family: var(--font-display), 'Bebas Neue', sans-serif;
  font-size: 22px; letter-spacing: 0.04em; line-height: 1;
  margin: 0;
  color: var(--text-primary);
}
.dash-shoot-name.dim { color: var(--text-tertiary); }
.dash-shoot-meta {
  font-size: 12px;
  color: var(--text-secondary);
  margin: 6px 0 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.dash-shoot-count {
  display: flex; align-items: baseline; gap: 8px;
  margin-top: auto;
  padding-top: 14px;
}
.dash-shoot-count .n {
  font-family: var(--font-display), 'Bebas Neue', sans-serif;
  font-size: 46px; line-height: 1;
  letter-spacing: 0.02em;
  color: var(--accent);
}
.dash-shoot-count .l {
  font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--text-tertiary);
}
.dash-next-shoot.is-empty .dash-shoot-meta {
  white-space: normal;
  line-height: 1.5;
  margin-top: 8px;
}

/* Money card */
.dash-money-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  margin-top: 4px;
}
.dash-money-grid > div { min-width: 0; }
.dash-money-l {
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin: 0 0 3px;
}
.dash-money-v {
  font-family: var(--font-display), 'Bebas Neue', sans-serif;
  font-size: 18px; line-height: 1; letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
  white-space: nowrap;
}
.dash-money-v.good   { color: var(--accent); }
.dash-money-v.zero   { color: var(--text-tertiary); }
.dash-money-v.danger { color: var(--status-danger); }
.dash-money-sub {
  font-size: 10px;
  color: var(--text-tertiary);
  margin: 4px 0 0;
}
.dash-money-sub.up   { color: var(--status-success); }
.dash-money-sub.down { color: var(--status-danger); }

/* ── Today (punch list) ── */
.dash-today { min-height: 220px; }
.dash-punch {
  display: grid;
  grid-template-columns: 3px 1fr auto;
  align-items: center;
  gap: 12px;
  padding: 10px 0;
  border-top: 0.5px solid var(--border-faint);
  text-decoration: none;
  color: inherit;
  transition: padding 150ms ease;
}
.dash-punch:first-of-type { border-top: 0; padding-top: 2px; }
.dash-punch:hover { padding-left: 4px; text-decoration: none; }
.dash-punch-bar {
  align-self: stretch;
  border-radius: 2px;
  background: var(--accent);
}
.dash-punch[data-urgency="high"]   .dash-punch-bar { background: #F472B6; }
.dash-punch[data-urgency="medium"] .dash-punch-bar { background: #FBBF24; }
.dash-punch[data-urgency="normal"] .dash-punch-bar { background: var(--accent); }
.dash-punch-body { min-width: 0; }
.dash-punch-what {
  font-size: 14px; font-weight: 500;
  color: var(--text-primary);
  margin: 0;
  line-height: 1.3;
}
.dash-punch-when {
  font-size: 12px;
  color: var(--text-tertiary);
  margin: 3px 0 0;
  line-height: 1.4;
}
.dash-punch-act {
  font-size: 12px;
  color: var(--accent);
  padding: 6px 12px;
  border-radius: 8px;
  border: 0.5px solid rgba(45,212,191,0.30);
  background: rgba(45,212,191,0.06);
  white-space: nowrap;
  transition: background 150ms ease, border-color 150ms ease;
}
.dash-punch:hover .dash-punch-act {
  background: rgba(45,212,191,0.14);
  border-color: rgba(45,212,191,0.50);
}

.dash-empty-block {
  display: flex; flex-direction: column; align-items: flex-start;
  gap: 8px;
  padding: 18px 4px 8px;
}
.dash-empty-h {
  font-family: var(--font-display), 'Bebas Neue', sans-serif;
  font-size: 22px; letter-spacing: 0.04em;
  margin: 0;
}
.dash-empty-block p { font-size: 13px; color: var(--text-secondary); margin: 0 0 6px; max-width: 380px; line-height: 1.5; }
.dash-empty { font-size: 13px; color: var(--text-secondary); margin: 4px 0 0; }

/* ── Shoot prep (checklist chips) ── */
.dash-prep { min-height: 220px; }
.dash-chk-row { display: flex; flex-wrap: wrap; gap: 6px; }
.dash-chk {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11px;
  padding: 5px 11px;
  border-radius: 999px;
  border: 0.5px solid var(--border-line);
  color: var(--text-secondary);
  background: rgba(255,255,255,0.02);
  transition: background 150ms ease, color 150ms ease;
}
.dash-chk-mark { font-size: 10px; opacity: 0.65; }
.dash-chk.done {
  color: var(--accent);
  border-color: rgba(45,212,191,0.40);
  background: rgba(45,212,191,0.06);
}
.dash-chk.done .dash-chk-mark { opacity: 1; }
.dash-prep-nudge {
  font-size: 13px;
  color: var(--text-secondary);
  margin: 14px 0 0;
  line-height: 1.5;
}
.dash-prep-cta {
  align-self: flex-start;
  margin-top: 12px;
  font-size: 12px;
  color: var(--accent);
  padding: 6px 12px;
  border-radius: 8px;
  border: 0.5px solid rgba(45,212,191,0.30);
  background: rgba(45,212,191,0.06);
  text-decoration: none;
  transition: background 150ms ease, border-color 150ms ease;
}
.dash-prep-cta:hover {
  background: rgba(45,212,191,0.14);
  border-color: rgba(45,212,191,0.50);
  text-decoration: none;
}

/* ── On the bench (in-progress projects) ── */
.dash-bench-row {
  display: grid;
  grid-template-columns: 1fr 110px 60px;
  align-items: center;
  gap: 14px;
  padding: 10px 0;
  border-top: 0.5px solid var(--border-faint);
  text-decoration: none;
  color: inherit;
  transition: padding-left 150ms ease;
}
.dash-bench-row:first-of-type { border-top: 0; padding-top: 2px; }
.dash-bench-row:hover { padding-left: 4px; text-decoration: none; }
.dash-bench-info { min-width: 0; }
.dash-bench-name {
  font-size: 14px; font-weight: 500;
  margin: 0; line-height: 1.3;
  color: var(--text-primary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.dash-bench-client { color: var(--text-tertiary); font-weight: 400; }
.dash-bench-meta {
  font-size: 11px;
  color: var(--text-tertiary);
  margin: 3px 0 0;
  text-transform: capitalize;
}
.dash-bench-bar {
  height: 5px;
  background: rgba(255,255,255,0.06);
  border-radius: 3px;
  overflow: hidden;
}
.dash-bench-bar > i {
  display: block; height: 100%;
  background: linear-gradient(90deg, var(--accent), var(--accent-soft));
  border-radius: 3px;
}
.dash-bench-days {
  text-align: right;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  color: var(--text-secondary);
}
.dash-bench-days.slip { color: var(--status-warning); }

/* ── This week (7-day strip) ── */
.dash-week-row {
  display: grid;
  grid-template-columns: 50px 1fr;
  align-items: center;
  gap: 10px;
  padding: 7px 0;
  border-top: 0.5px solid var(--border-faint);
  font-size: 12px;
}
.dash-week-row:first-of-type { border-top: 0; padding-top: 2px; }
.dash-week-label {
  color: var(--text-tertiary);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 10px;
}
.dash-week-row.is-today .dash-week-label,
.dash-week-row.is-today .dash-week-entry {
  color: var(--accent);
}
.dash-week-row.is-weekend .dash-week-label {
  color: var(--accent-soft);
}
.dash-week-entries { display: flex; flex-direction: column; gap: 2px; }
.dash-week-entry {
  color: var(--text-primary);
  text-decoration: none;
  font-size: 12px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.dash-week-entry:hover {
  color: var(--accent);
  text-decoration: none;
}
.dash-week-empty {
  color: var(--text-faint);
  font-size: 12px;
}

/* ── Year-at-a-glance heatmap ── */
.dash-year { min-height: 120px; }
.dash-heat {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: 8px;
  align-items: stretch;
  margin-top: 4px;
}
.dash-heat-col {
  display: flex; flex-direction: column; gap: 3px; align-items: stretch;
}
.dash-heat-m {
  font-size: 10px;
  letter-spacing: 0.14em;
  color: var(--text-tertiary);
  text-align: center;
  margin-bottom: 4px;
}
.dash-heat-m.is-current { color: var(--accent); }
.dash-heat-w {
  height: 8px;
  border-radius: 2px;
  background: rgba(255,255,255,0.04);
  transition: transform 120ms ease;
}
.dash-heat-w:hover { transform: scaleY(1.4); }
.dash-heat-w[data-l="1"] { background: rgba(45,212,191,0.22); }
.dash-heat-w[data-l="2"] { background: rgba(45,212,191,0.45); }
.dash-heat-w[data-l="3"] { background: rgba(45,212,191,0.70); }
.dash-heat-w[data-l="4"] { background: var(--accent); }

/* ── Quick actions row (kept, demoted to a thin bar under the grid) ── */
.dash-quick {
  display: flex; gap: 8px; flex-wrap: wrap;
  margin-top: 18px;
  padding-top: 14px;
  border-top: 0.5px solid var(--border-faint);
}

/* ── Narrow / mobile fallback ──
   Below ~960px the bento collapses to 1 column. Stat row stays 3-up via
   subgrid trickery if you want, but plain stacking is fine and avoids
   the cells getting unreadable. */
@media (max-width: 960px) {
  .dash-grid > .dash-cell { grid-column: span 12 !important; }
  .dash-money-grid { grid-template-columns: repeat(3, 1fr); }
}

/* ============================================================================
   REVENUE PAGE (Sales → Revenue, 2026-05-19)
   Reuses the bento dash-cell + dash-tag base from above. New styles below
   are specific to the monthly bar chart, the range toggle, the expense
   form, and the recent-expenses list. Big-number tiles use .dash-bignum
   from the dashboard so the look stays unified.
   ============================================================================ */

/* ── Range toggle (segmented control) ── */
.rev-range {
  display: inline-flex; gap: 2px;
  background: rgba(255,255,255,0.04);
  border: 0.5px solid var(--border-faint);
  border-radius: 8px;
  padding: 2px;
}
.rev-range a {
  font-size: 11px;
  font-family: 'Inter', sans-serif;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--text-tertiary);
  padding: 5px 12px;
  border-radius: 6px;
  text-decoration: none;
  transition: background 150ms ease, color 150ms ease;
}
.rev-range a:hover { color: var(--text-primary); text-decoration: none; }
.rev-range a.is-on {
  background: rgba(45,212,191,0.12);
  color: var(--accent);
}

/* ── Monthly bar chart ── */
.rev-chart {
  display: flex; align-items: flex-end; gap: 10px;
  height: 220px;
  padding: 6px 6px 0;
  position: relative;
  margin-bottom: 12px;
}
.rev-chart::before,
.rev-chart::after {
  content: ""; position: absolute;
  left: 0; right: 0; height: 0.5px;
  background: var(--border-faint);
  pointer-events: none;
}
.rev-chart::before { top: 0; }
.rev-chart::after  { bottom: 0; }
.rev-col {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column;
  align-items: center;
  gap: 6px;
  position: relative;
}
.rev-bar-stack {
  display: flex; flex-direction: column-reverse;
  align-items: stretch;
  width: 100%; max-width: 38px;
  height: 100%;
  gap: 2px;
}
.rev-bar {
  border-radius: 3px 3px 0 0;
  min-height: 0;
  transition: opacity 150ms ease, transform 150ms ease;
}
.rev-bar-income {
  background: linear-gradient(180deg, var(--accent), color-mix(in srgb, var(--accent) 75%, #000));
}
.rev-bar-expense {
  background: linear-gradient(180deg, #F472B6, var(--accent-soft));
  opacity: 0.62;
}
.rev-col:hover .rev-bar { transform: scaleY(1.02); transform-origin: bottom; }
.rev-col:hover .rev-bar-expense { opacity: 0.85; }
.rev-bar-month {
  font-size: 10px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.rev-col.is-current .rev-bar-month { color: var(--accent); }
.rev-col.is-current::before {
  /* Subtle highlight column behind the current month so it pops without
     adding chartjunk. Sits behind the bars (via z-index on bars). */
  content: "";
  position: absolute;
  inset: -4px -2px 18px;
  background: rgba(45,212,191,0.05);
  border-radius: 6px;
  pointer-events: none;
}
.rev-col > .rev-bar-stack, .rev-col > .rev-bar-month { position: relative; z-index: 1; }

.rev-legend {
  display: flex; align-items: center; gap: 18px;
  font-size: 11px;
  color: var(--text-secondary);
  padding-top: 6px;
}
.rev-sw {
  width: 10px; height: 10px;
  border-radius: 2px;
  display: inline-block;
  margin-right: 6px;
  vertical-align: -1px;
}
.rev-sw-in { background: var(--accent); }
.rev-sw-ex { background: linear-gradient(135deg, #F472B6, var(--accent-soft)); opacity: 0.62; }
.rev-legend-hint { margin-left: auto; color: var(--text-tertiary); }

/* ── Expense form ── */
.rev-form {
  display: grid;
  grid-template-columns: 1fr 110px;
  gap: 8px;
  margin-top: 4px;
}
.rev-input {
  /* background-color (not background) — when .rev-input is a <select>, the
     global select rule's chevron image must survive this declaration. */
  background-color: rgba(255,255,255,0.04);
  border: 0.5px solid var(--border-faint);
  border-radius: 8px;
  padding: 9px 11px;
  color: var(--text-primary);
  font: inherit;
  font-size: 13px;
  transition: border-color 150ms ease, background-color 150ms ease;
}
/* Selects on the revenue form need extra right-padding for the chevron. */
select.rev-input { padding-right: 32px; }
.rev-input:focus {
  outline: 0;
  border-color: var(--accent-line);
  background-color: rgba(255,255,255,0.06);
  box-shadow: 0 0 0 3px var(--accent-tint);
}
.rev-input::placeholder { color: var(--text-tertiary); }
.rev-input-desc    { grid-column: span 2; }
.rev-input-amt     { grid-column: 1; }
.rev-input-cat     { grid-column: 2; }
.rev-input-date    { grid-column: 1; }
.rev-input-project { grid-column: 2; }
.rev-submit { grid-column: span 2; margin-top: 4px; justify-content: center; }

/* ── Recent expenses list ── */
.rev-exp-row {
  display: grid;
  grid-template-columns: 1fr 90px 70px 80px 22px;
  align-items: center;
  gap: 12px;
  padding: 10px 0;
  border-top: 0.5px solid var(--border-faint);
  font-size: 13px;
}
.rev-exp-row:first-of-type { border-top: 0; padding-top: 2px; }
.rev-exp-info { min-width: 0; }
.rev-exp-desc {
  margin: 0; line-height: 1.3;
  color: var(--text-primary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.rev-exp-sub {
  margin: 2px 0 0;
  font-size: 11px;
  color: var(--text-tertiary);
}
.rev-exp-cat {
  font-size: 10px;
  letter-spacing: 0.06em;
  padding: 3px 8px;
  border-radius: 999px;
  background: rgba(167,139,250,0.12);
  color: var(--accent-soft);
  text-align: center;
  white-space: nowrap;
}
.rev-exp-cat[data-cat="Gear"]         { background: rgba(45,212,191,0.12); color: var(--accent); }
.rev-exp-cat[data-cat="Software"]     { background: rgba(103,232,249,0.14); color: var(--status-info); }
.rev-exp-cat[data-cat="Travel"]       { background: rgba(251,191,36,0.14);  color: var(--status-warning); }
.rev-exp-cat[data-cat="Subcontractor"]{ background: rgba(244,114,182,0.14); color: #F9A8D4; }
.rev-exp-cat[data-cat="Marketing"]    { background: rgba(167,139,250,0.14); color: var(--accent-soft); }
.rev-exp-cat[data-cat="Insurance"]    { background: rgba(94,234,212,0.12);  color: #5EEAD4; }
.rev-exp-cat[data-cat="Other"]        { background: rgba(255,255,255,0.06); color: var(--text-secondary); }
.rev-exp-date {
  font-size: 11px;
  color: var(--text-tertiary);
}
.rev-exp-amt {
  font-variant-numeric: tabular-nums;
  text-align: right;
  color: var(--status-danger);
}
.rev-exp-x {
  background: transparent;
  border: 0;
  color: var(--text-faint);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  padding: 2px 4px;
  border-radius: 4px;
  transition: color 120ms ease, background 120ms ease;
}
.rev-exp-x:hover {
  color: var(--status-danger);
  background: rgba(255,133,133,0.08);
}

@media (max-width: 720px) {
  .rev-chart { height: 160px; gap: 4px; }
  .rev-form { grid-template-columns: 1fr; }
  .rev-form > * { grid-column: 1 !important; }
  .rev-exp-row { grid-template-columns: 1fr auto auto; gap: 8px; }
  .rev-exp-cat, .rev-exp-x { display: none; }
}
